/** * 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 0: a = new AHAddress(mb); break; case 124: 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); } }