namespace System {
+[Serializable]
public struct Guid : IFormattable, IComparable {
private uint _timeLow;
private byte _node4;
private byte _node5;
- private class GuidState {
+ internal class GuidState {
protected Random _prnd; // Pseudo RNG
protected RandomNumberGenerator _rnd; // Strong RNG
protected bool _usePRnd; // 'true' for pseudo RNG
protected ulong _lastTimestamp;
protected byte[] _mac;
- public int NextInt(uint x) {
+ public int NextInt(uint x)
+ {
if (_usePRnd) {
return _prnd.Next ((int) x);
}
}
}
- public void NextBytes(byte[] b) {
+ public void NextBytes(byte[] b)
+ {
if ( _usePRnd ) {
_prnd . NextBytes (b);
}
}
[MonoTODO("Get real MAC address")]
- public GuidState (bool usePRnd) {
+ public GuidState (bool usePRnd)
+ {
_usePRnd = usePRnd;
if ( _usePRnd ) {
- _prnd = new Random(unchecked((int) DateTime.Now.Ticks));
+ _prnd = new Random (unchecked((int) DateTime.Now.Ticks));
}
else {
_rnd = RandomNumberGenerator.Create ();
_mac[0] |= 0x80;
}
- public ulong NewTimestamp () {
+ public ulong NewTimestamp ()
+ {
ulong timestamp;
do {
- timestamp = (ulong) (DateTime.UtcNow - new DateTime(1582, 10, 15, 0, 0, 0)).Ticks;
+ timestamp = (ulong) (DateTime.UtcNow - new DateTime (1582, 10, 15, 0, 0, 0)).Ticks;
if (timestamp < _lastTimestamp) {
// clock moved backwards!
_clockSeq++;
};
- private static GuidState _guidState = new GuidState ( false /* use pseudo RNG? */ );
+ internal class GuidParser {
- private static void CheckNull (object o) {
+ private string _src;
+ private int _length;
+ private int _cur;
+
+ public GuidParser (string src)
+ {
+ _src = src;
+ Reset ();
+ }
+
+ private void Reset ()
+ {
+ _cur = 0;
+ _length = _src.Length;
+ }
+
+ private bool AtEnd ()
+ {
+ return _cur >= _length;
+ }
+
+ private void ThrowFormatException ()
+ {
+ throw new FormatException (Locale.GetText ("Invalid format for Guid.Guid(string)"));
+ }
+
+ private ulong ParseHex(int length, bool strictLength)
+ {
+ ulong res = 0;
+ int i;
+ bool end = false;
+
+ for (i=0; (!end) && i<length; ++i) {
+ if (AtEnd ()) {
+ if (strictLength || i==0) {
+ ThrowFormatException ();
+ }
+ else {
+ end = true;
+ }
+ }
+ else {
+ char c = Char.ToLower (_src[_cur]);
+ if (Char.IsDigit (c)) {
+ res = res * 16 + c - '0';
+ _cur++;
+ }
+ else if (c >= 'a' && c <= 'f') {
+ res = res * 16 + c - 'a' + 10;
+ _cur++;
+ }
+ else {
+ if (strictLength || i==0) {
+ ThrowFormatException ();
+ }
+ else {
+ end = true;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+
+ private bool ParseOptChar (char c)
+ {
+ if (!AtEnd() && _src[_cur] == c) {
+ _cur++;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private void ParseChar (char c)
+ {
+ bool b = ParseOptChar (c);
+ if (!b) {
+ ThrowFormatException ();
+ }
+ }
+
+ private Guid ParseGuid1 ()
+ {
+ bool openBrace;
+ int a;
+ short b;
+ short c;
+ byte[] d = new byte[8];
+ int i;
+
+ openBrace = ParseOptChar ('{');
+ a = (int) ParseHex(8, true);
+ ParseChar('-');
+ b = (short) ParseHex(4, true);
+ ParseChar('-');
+ c = (short) ParseHex(4, true);
+ ParseChar('-');
+ for (i=0; i<8; ++i) {
+ d[i] = (byte) ParseHex(2, true);
+ if (i == 1) {
+ ParseChar('-');
+ }
+ }
+
+ if (openBrace && !ParseOptChar('}')) {
+ ThrowFormatException ();
+ }
+
+ return new Guid(a, b, c, d);
+ }
+
+ private void ParseHexPrefix ()
+ {
+ ParseChar ('0');
+ ParseChar ('x');
+ }
+
+ private Guid ParseGuid2 ()
+ {
+ int a;
+ short b;
+ short c;
+ byte[] d = new byte [8];
+ int i;
+
+ ParseChar ('{');
+ ParseHexPrefix ();
+ a = (int) ParseHex (8, false);
+ ParseChar (',');
+ ParseHexPrefix ();
+ b = (short) ParseHex (4, false);
+ ParseChar (',');
+ ParseHexPrefix ();
+ c = (short) ParseHex (4, false);
+ ParseChar (',');
+ ParseChar ('{');
+ for (i=0; i<8; ++i) {
+ ParseHexPrefix ();
+ d[i] = (byte) ParseHex (2, false);
+ if (i != 7) {
+ ParseChar (',');
+ }
+
+ }
+ ParseChar ('}');
+ ParseChar ('}');
+
+ return new Guid (a,b,c,d);
+
+ }
+
+ public Guid Parse ()
+ {
+ Guid g;
+
+ try {
+ g = ParseGuid1 ();
+ }
+ catch (FormatException) {
+ Reset ();
+ g = ParseGuid2 ();
+ }
+ if (!AtEnd () ) {
+ ThrowFormatException ();
+ }
+ return g;
+ }
+
+ }
+
+ private static GuidState _guidState = new GuidState ( true /* use pseudo RNG? */ );
+
+ private static void CheckNull (object o)
+ {
if (o == null) {
throw new ArgumentNullException (Locale.GetText ("Value cannot be null."));
}
}
- private static void CheckLength (byte[] o, int l) {
+ private static void CheckLength (byte[] o, int l)
+ {
if (o . Length != l) {
- throw new ArgumentException (String.Format(Locale.GetText ("Array should be exactly {0} bytes long."), l));
+ throw new ArgumentException (String.Format (Locale.GetText ("Array should be exactly {0} bytes long."), l));
}
}
- private static void CheckArray (byte[] o, int l) {
+ private static void CheckArray (byte[] o, int l)
+ {
CheckNull (o);
CheckLength (o, l);
}
- public Guid (byte[] b) {
+ public Guid (byte[] b)
+ {
CheckArray (b, 16);
_timeLow = System.BitConverter.ToUInt32 (b, 0);
_timeMid = System.BitConverter.ToUInt16 (b, 4);
_node5 = b[15];
}
+ public Guid (string g)
+ {
+ CheckNull (g);
+
+ GuidParser p = new GuidParser (g);
+ Guid guid = p.Parse();
+
+ this = guid;
+ }
+
public Guid (int a, short b, short c, byte[] d)
{
CheckArray(d, 8);
}
}
- public int CompareTo (object value ) {
+ public int CompareTo (object value )
+ {
if (value == null )
return 1;
return 0;
}
- public override bool Equals ( object o ) {
+ public override bool Equals ( object o )
+ {
try {
- return CompareTo(o) == 0;
+ return CompareTo (o) == 0;
}
catch ( ArgumentException ) {
return false;
}
}
- public override int GetHashCode () {
+ public override int GetHashCode ()
+ {
int res;
res = (int) _timeLow;
return res;
}
- private static Guid NewTimeGuid() {
+ private static Guid NewTimeGuid()
+ {
ulong timestamp = _guidState.NewTimestamp ();
// Bit [31..0] (32 bits) for timeLow
return new Guid(timeLow, timeMid, timeHi, clockSeqHi, clockSeqLow, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
- private static Guid NewRandomGuid () {
+ private static Guid NewRandomGuid ()
+ {
byte[] b = new byte[16];
_guidState.NextBytes (b);
}
[MonoTODO]
- public static Guid NewGuid () {
+ public static Guid NewGuid ()
+ {
return NewRandomGuid();
}
- public byte[] ToByteArray () {
+ public byte[] ToByteArray ()
+ {
byte[] res = new byte[16];
byte[] tmp;
int d = 0;
return res;
}
- private string BaseToString(bool h, bool p, bool b) {
+ private string BaseToString(bool h, bool p, bool b)
+ {
string res = "";
if (p) {
res += "{";
}
- res += _timeLow.ToString("x8");
+ res += _timeLow.ToString ("x8");
if (h) {
res += "-";
}
- res += _timeMid.ToString("x4");
+ res += _timeMid.ToString ("x4");
if (h) {
res += "-";
}
- res += _timeHighAndVersion.ToString("x4");
+ res += _timeHighAndVersion.ToString ("x4");
if (h) {
res += "-";
}
- res += _clockSeqHiAndReserved.ToString("x2");
- res += _clockSeqLow.ToString("x2");
+ res += _clockSeqHiAndReserved.ToString ("x2");
+ res += _clockSeqLow.ToString ("x2");
if (h) {
res += "-";
}
- res += _node0.ToString("x2");
- res += _node1.ToString("x2");
- res += _node2.ToString("x2");
- res += _node3.ToString("x2");
- res += _node4.ToString("x2");
- res += _node5.ToString("x2");
+ res += _node0.ToString ("x2");
+ res += _node1.ToString ("x2");
+ res += _node2.ToString ("x2");
+ res += _node3.ToString ("x2");
+ res += _node4.ToString ("x2");
+ res += _node5.ToString ("x2");
if (p) {
res += ")";
return res;
}
- public override string ToString () {
+ public override string ToString ()
+ {
return BaseToString (true, false, false);
}
- public string ToString (string format) {
+ public string ToString (string format)
+ {
string f;
- bool h = false;
+ bool h = true;
bool p = false;
bool b = false;
f = format.ToLower();
if (f == "b") {
- h = true;
b = true;
}
else if (f == "p") {
- h = true;
p = true;
}
- else if (f == "d") {
- h = true;
+ else if (f == "n") {
+ h = false;
}
- else if (f != "n" && f != "") {
+ else if (f != "d" && f != "") {
throw new FormatException ( Locale.GetText ("Argument to Guid.ToString(string format) should be \"b\", \"B\", \"d\", \"D\", \"n\", \"N\", \"p\" or \"P\""));
}
}
return BaseToString (h, p, b);
}
- public string ToString (string format, IFormatProvider provider) {
+ public string ToString (string format, IFormatProvider provider)
+ {
return ToString (format);
}
- public static bool operator == (Guid a, Guid b) {
+ public static bool operator == (Guid a, Guid b)
+ {
return a.Equals(b);
}
- public static bool operator != (Guid a, Guid b) {
+ public static bool operator != (Guid a, Guid b)
+ {
return !( a.Equals (b) );
}