/** * Parse the PType starting at mb, and return all of mb <b>after</b> * the PType. */ public static PType Parse(MemBlock mb, out MemBlock rest) { PType result = null; byte fb = mb[0]; bool is_v_n = IsValidNumeric((int)fb); /** * Since ptypes must be valid UTF8 strings, * if the second byte is null, the first byte is an ascii character * and hence has a value less than ASCII_UPPER_BOUND */ bool store_in_tbl = (is_v_n || (mb[1] == 0)); if (store_in_tbl) { //This is stored in our table: result = _table[fb]; if (result != null) { if (is_v_n) { //There is no null rest = mb.Slice(1); } else { //Skip the null rest = mb.Slice(2); } return(result); } } //Otherwise we have to make it: MemBlock raw_data = null; result = new PType(); if (is_v_n) { /* * Don't set the raw_data since it is only one byte and we may not need * it */ rest = mb.Slice(1); result._type_num = (int)fb; } else { int null_pos = mb.IndexOf(0); if (null_pos > 0) { //Include the "null", but make a copy so we don't keep some data in //scope for ever raw_data = MemBlock.Copy((ICopyable)mb.Slice(0, null_pos + 1)); rest = mb.Slice(null_pos + 1); } else { //There is no terminating Null, panic!! throw new ParseException( System.String.Format("PType not null terminated: {0}", mb.ToBase16String())); } result._type_num = -2; result._raw_data = raw_data; } if (store_in_tbl) { //Make sure we don't have to create an object like this again _table[fb] = result; } return(result); }
/** * Parse the PType starting at mb, and return all of mb <b>after</b> * the PType. */ public static PType Parse(MemBlock mb, out MemBlock rest) { PType result = null; byte fb = mb[0]; bool is_v_n = IsValidNumeric( (int)fb ); /** * Since ptypes must be valid UTF8 strings, * if the second byte is null, the first byte is an ascii character * and hence has a value less than ASCII_UPPER_BOUND */ bool store_in_tbl = ( is_v_n || (mb[1] == 0) ); if( store_in_tbl ) { //This is stored in our table: result = _table[ fb ]; if( result != null ) { if( is_v_n ) { //There is no null rest = mb.Slice(1); } else { //Skip the null rest = mb.Slice(2); } return result; } } //Otherwise we have to make it: MemBlock raw_data = null; result = new PType(); if( is_v_n ) { /* * Don't set the raw_data since it is only one byte and we may not need * it */ rest = mb.Slice(1); result._type_num = (int)fb; } else { int null_pos = mb.IndexOf(0); if( null_pos > 0 ) { //Include the "null", but make a copy so we don't keep some data in //scope for ever raw_data = MemBlock.Copy( (ICopyable)mb.Slice(0, null_pos + 1) ); rest = mb.Slice(null_pos + 1); } else { //There is no terminating Null, panic!! throw new ParseException( System.String.Format("PType not null terminated: {0}", mb.ToBase16String())); } result._type_num = -2; result._raw_data = raw_data; } if( store_in_tbl ) { //Make sure we don't have to create an object like this again _table[ fb ] = result; } return result; }