/** * Read the address out of the buffer This makes a copy * and calls Parse on the copy. This is a "convienience" method. * @throw ParseException if the buffer is not a valid address */ static public Address Parse(MemBlock mb) { //Read some of the least significant bytes out, //AHAddress all have last bit 0, so we skip the last byte which //will have less entropy ushort idx = (ushort)NumberSerializer.ReadShort(mb, Address.MemSize - 3); Address a = _mb_cache[idx]; if (a != null) { if (a.ToMemBlock().Equals(mb)) { return(a); } } //Else we need to read the address and put it in the cache try { if (2 * mb.Length < mb.ReferencedBufferLength) { /* * This MemBlock is much smaller than the array * we are referencing, don't keep the big one * in scope, instead make a copy */ mb = MemBlock.Copy((ICopyable)mb); } int add_class = Address.ClassOf(mb); switch (add_class) { case AHAddress.ClassValue: a = new AHAddress(mb); break; case DirectionalAddress.ClassValue: a = new DirectionalAddress(mb); break; default: a = null; throw new ParseException("Unknown Address Class: " + add_class + ", buffer:" + mb.ToString()); } //Cache this result: _mb_cache[idx] = a; return(a); } catch (ArgumentOutOfRangeException ex) { throw new ParseException("Address too short: " + mb.ToString(), ex); } catch (ArgumentException ex) { throw new ParseException("Could not parse: " + mb.ToString(), ex); } }
public void Test() { System.Random r = new System.Random(); for (int i = 0; i < 1024; i++) { //Test ClassOf and SetClass: int c = r.Next(160); byte[] buf0 = new byte[Address.MemSize]; //Fill it with junk r.NextBytes(buf0); Address.SetClass(buf0, c); int c2 = Address.ClassOf(MemBlock.Reference(buf0, 0, Address.MemSize)); Assert.AreEqual(c, c2, "Class Round Trip"); //Test BigInteger stuff: int size = r.Next(1, MemSize + 1); byte[] buf1 = new byte[size]; r.NextBytes(buf1); BigInteger b1 = new BigInteger(buf1); byte[] buf2 = Address.ConvertToAddressBuffer(b1); //Check to see if the bytes are equivalent: int min_len = System.Math.Min(buf1.Length, buf2.Length); bool all_eq = true; for (int j = 0; j < min_len; j++) { all_eq = all_eq && (buf2[buf2.Length - j - 1] == buf1[buf1.Length - j - 1]); } if (!all_eq) { System.Console.Error.WriteLine("Buf1: "); foreach (byte b in buf1) { System.Console.Write("{0} ", b); } System.Console.Error.WriteLine(); System.Console.Error.WriteLine("Buf2: "); foreach (byte b in buf2) { System.Console.Write("{0} ", b); } System.Console.Error.WriteLine(); } Assert.IsTrue(all_eq, "bytes are equivalent"); BigInteger b2 = new BigInteger(buf2); Assert.AreEqual(b1, b2, "BigInteger round trip"); } }