protected override void OnBeginTypedArray(MarkerCode typeOfElement, int elemCount) { PushCurrentState(); //enter new state : create new array, and set to current object _currentObject = _currentArray = _doc.CreateArray(); //expect array value _state = ParsingState.ExpectArrayValue; }
//------------------------------------------------------------ void WriteStartArray_T(MarkerCode elementType, int count) { //element type + encode length //check primitive value that we support #if DEBUG if (count >= 0 && count < 32) { //ok } else { throw new NotSupportedException(); } #endif //we encode num of element and element type //lower 5 bits for primitive type (0-32) //upper 2 bits for encoded length // 0 : num of element =0 // 1 : follow byte 1 bytes // 2 : follow by 2 bytes unsigned // 3 : followed by 4 bytes signed writer.Write((byte)MarkerCode.StartArray_T); if (count == 0) { //no element int encodedTypeAndElemCount = ((byte)elementType & 0x1f); writer.Write((byte)encodedTypeAndElemCount); } else if (count < 253) { //use 1 byte int encodedTypeAndElemCount = (1 << 5) | ((byte)elementType & 0x1f); writer.Write((byte)encodedTypeAndElemCount); writer.Write((byte)count); } else if (count < ushort.MaxValue) { int encodedTypeAndByteLength = (2 << 5) | ((byte)elementType & 0x1f); //length marker //then writer.Write((byte)encodedTypeAndByteLength); writer.Write((ushort)count); } else { int encodedTypeAndByteLength = (3 << 5) | ((byte)elementType & 0x1f); writer.Write((byte)encodedTypeAndByteLength); writer.Write(count); } }
protected void ReadValue(out MarkerCode marker) { //all object marker = (MarkerCode)reader.ReadByte(); switch (marker) { default: throw new NotSupportedException(); case MarkerCode.StartObject: ReadObject(0); break; case MarkerCode.StartObject_1: ReadObject(reader.ReadByte()); break; case MarkerCode.StartObject_2: ReadObject(reader.ReadUInt16()); break; case MarkerCode.StartObject_4: ReadObject(reader.ReadInt32()); break; case MarkerCode.Sep: // throw new NotSupportedException(); case MarkerCode.EndObject: break; //-------------------------- case MarkerCode.StartArray: ReadArray(0); break; case MarkerCode.StartArray_1: ReadArray(reader.ReadByte()); break; case MarkerCode.StartArray_2: ReadArray(reader.ReadUInt16()); break; case MarkerCode.StartArray_4: ReadArray(reader.ReadInt32()); break; case MarkerCode.StartArray_T: ReadTypedArray(0); break; case MarkerCode.StartArray_T_1: ReadTypedArray(reader.ReadByte()); break; case MarkerCode.StartArray_T_2: ReadTypedArray(reader.ReadUInt16()); break; case MarkerCode.StartArray_T_4: ReadTypedArray(reader.ReadInt32()); break; case MarkerCode.EndArray: //end arr break; //-------------------------- case MarkerCode.Null: OnNullObject(); break; case MarkerCode.NullString: OnNullString(); break; //-------------------------- case MarkerCode.True: OnBoolean(true); break; case MarkerCode.False: OnBoolean(false); break; //-------------------------- case MarkerCode.STR_1: { int len = reader.ReadByte(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.STR_2: { int len = reader.ReadUInt16(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.STR_4: { int len = reader.ReadInt32(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.EmptyString: OnEmptyString(); break; case MarkerCode.GUID: OnGuidData(reader.ReadBytes(8)); break; case MarkerCode.EmptyGuid: OnEmptyGuid(); break; case MarkerCode.Int16: OnInt16(reader.ReadInt16()); break; case MarkerCode.Int32: OnInt32(reader.ReadInt32()); break; case MarkerCode.Char: OnChar(reader.ReadChar()); break; case MarkerCode.UInt16: OnUInt16(reader.ReadUInt16()); break; case MarkerCode.UInt32: OnUInt32(reader.ReadUInt32()); break; case MarkerCode.UInt64: OnUInt64(reader.ReadUInt64()); break; case MarkerCode.Int64: OnInt64(reader.ReadInt64()); break; case MarkerCode.Byte: OnByte(reader.ReadByte()); break; case MarkerCode.SByte: OnSByte(reader.ReadSByte()); break; case MarkerCode.Num0: OnInteger(0); break; case MarkerCode.Num1: OnInteger(1); break; case MarkerCode.Num2: OnInteger(2); break; case MarkerCode.Num3: OnInteger(3); break; case MarkerCode.Num4: OnInteger(4); break; case MarkerCode.Num5: OnInteger(5); break; case MarkerCode.Num6: OnInteger(6); break; case MarkerCode.Num7: OnInteger(7); break; case MarkerCode.Num8: OnInteger(8); break; case MarkerCode.Num9: OnInteger(9); break; case MarkerCode.NumM1: OnInteger(-1); break; //-------------------------- case MarkerCode.Float32: OnFloat32(reader.ReadSingle()); break; case MarkerCode.Float64: OnFloat64(reader.ReadDouble()); break; case MarkerCode.Decimal: OnDecimal(reader.ReadDecimal()); break; case MarkerCode.DateTime: DateTime d = DateTime.FromBinary(reader.ReadInt64()); OnDateTime(d); break; case MarkerCode.BLOB_1: { int len = reader.ReadByte(); byte[] blob = reader.ReadBytes(len); OnBlob(blob); } break; case MarkerCode.BLOB_2: { int len = reader.ReadUInt16(); byte[] blob = reader.ReadBytes(len); OnBlob(blob); } break; case MarkerCode.BLOB_4: { int len = reader.ReadInt32(); byte[] blob = reader.ReadBytes(len); OnBlob(blob); } break; case MarkerCode.BLOB_8: throw new NotSupportedException(); //-------------------------- } }
void ReadTypedArray(int sizeHintInByteCount) { //read type ( //1. element type int encodedTypeAndElementLengthCode = reader.ReadByte(); //lower 5 bits is primitive type MarkerCode elementType = (MarkerCode)(0x1f & encodedTypeAndElementLengthCode); //update 2 bits is encoded element length space* int arrLen = 0; switch (encodedTypeAndElementLengthCode >> 5) { case 0: { //blank Arr } break; case 1: { //array element count is in next 1 byte arrLen = reader.ReadByte(); } break; case 2: { //array element count is in next 2 bytes, unsigned arrLen = reader.ReadUInt16(); } break; case 3: { //array element count is in next 4 bytes, signed arrLen = reader.ReadInt32(); } break; default: throw new NotSupportedException(); } //2. read element count OnBeginTypedArray(elementType, arrLen); //loop switch (elementType) { //only element type that support typed array case MarkerCode.Byte: for (int i = 0; i < arrLen; ++i) { OnByte(reader.ReadByte()); } break; case MarkerCode.SByte: for (int i = 0; i < arrLen; ++i) { OnSByte(reader.ReadSByte()); } break; case MarkerCode.True: case MarkerCode.False: for (int i = 0; i < arrLen; ++i) { OnBoolean(reader.ReadBoolean()); } break; case MarkerCode.Int16: for (int i = 0; i < arrLen; ++i) { OnInt16(reader.ReadInt16()); } break; case MarkerCode.UInt16: for (int i = 0; i < arrLen; ++i) { OnUInt16(reader.ReadUInt16()); } break; case MarkerCode.Char: for (int i = 0; i < arrLen; ++i) { OnChar(reader.ReadChar()); } break; case MarkerCode.Int32: for (int i = 0; i < arrLen; ++i) { OnInt32(reader.ReadInt32()); } break; case MarkerCode.UInt32: for (int i = 0; i < arrLen; ++i) { OnUInt32(reader.ReadUInt32()); } break; case MarkerCode.Int64: for (int i = 0; i < arrLen; ++i) { OnInt64(reader.ReadInt64()); } break; case MarkerCode.UInt64: for (int i = 0; i < arrLen; ++i) { OnUInt64(reader.ReadUInt64()); } break; case MarkerCode.Float32: for (int i = 0; i < arrLen; ++i) { OnFloat32(reader.ReadSingle()); } break; case MarkerCode.Float64: for (int i = 0; i < arrLen; ++i) { OnFloat64(reader.ReadDouble()); } break; case MarkerCode.DateTime: for (int i = 0; i < arrLen; ++i) { var dtm = DateTime.FromBinary(reader.ReadInt64()); OnDateTime(dtm); } break; case MarkerCode.Decimal: for (int i = 0; i < arrLen; ++i) { OnDecimal(reader.ReadDecimal()); } break; case MarkerCode.GUID: for (int i = 0; i < arrLen; ++i) { OnGuidData(reader.ReadBytes(16)); } break; default: throw new NotSupportedException(); } //should stop with end-arra var endArr = (MarkerCode)reader.ReadByte(); if (endArr != MarkerCode.EndArray) { throw new Exception("arrerr!"); } OnEndArray(); }
protected virtual void OnBeginTypedArray(MarkerCode typeOfElement, int elemCount) { }
bool ReadObjectKey() { //--------------------- //then read key and value MarkerCode marker = (MarkerCode)reader.ReadByte(); switch (marker) { case MarkerCode.EndObject: //stop current object return(false); case MarkerCode.STR_1: { int len = reader.ReadByte(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.STR_2: { int len = reader.ReadUInt16(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.STR_4: { int len = reader.ReadInt32(); OnUtf8StringData(reader.ReadBytes(len)); } break; case MarkerCode.EmptyString: OnEmptyString(); break; case MarkerCode.GUID: OnGuidData(reader.ReadBytes(8)); break; case MarkerCode.EmptyGuid: OnEmptyGuid(); break; case MarkerCode.Int16: OnInt16(reader.ReadInt16()); break; case MarkerCode.Int32: OnInt32(reader.ReadInt32()); break; case MarkerCode.Char: OnChar(reader.ReadChar()); break; case MarkerCode.UInt16: OnUInt16(reader.ReadUInt16()); break; case MarkerCode.UInt32: OnUInt32(reader.ReadUInt32()); break; case MarkerCode.UInt64: OnUInt64(reader.ReadUInt64()); break; case MarkerCode.Int64: OnInt64(reader.ReadInt64()); break; case MarkerCode.Byte: OnByte(reader.ReadByte()); break; case MarkerCode.SByte: OnSByte(reader.ReadSByte()); break; case MarkerCode.Num0: OnInteger(0); break; case MarkerCode.Num1: OnInteger(1); break; case MarkerCode.Num2: OnInteger(2); break; case MarkerCode.Num3: OnInteger(3); break; case MarkerCode.Num4: OnInteger(4); break; case MarkerCode.Num5: OnInteger(5); break; case MarkerCode.Num6: OnInteger(6); break; case MarkerCode.Num7: OnInteger(7); break; case MarkerCode.Num8: OnInteger(8); break; case MarkerCode.Num9: OnInteger(9); break; case MarkerCode.NumM1: OnInteger(-1); break; default: throw new NotSupportedException(); } return(true); }
void WriteIList(IList o_list) { Type t = o_list.GetType(); if (t.IsGenericType) { Type[] genArgs = t.GetGenericArguments(); bool isHandled = false; if (genArgs != null && genArgs.Length == 1) { Type elem_type = genArgs[0]; TypeCode typecode = Type.GetTypeCode(elem_type); MarkerCode arrElemMakerCode = MarkerCode.Unknown; int memberCount = o_list.Count; switch (typecode) { case TypeCode.Boolean: { arrElemMakerCode = MarkerCode.True; //boolean WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <bool>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Byte: { arrElemMakerCode = MarkerCode.Byte; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <byte>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.SByte: { arrElemMakerCode = MarkerCode.SByte; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <sbyte>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Char: { arrElemMakerCode = MarkerCode.Char; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <char>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Int16: { arrElemMakerCode = MarkerCode.Int16; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <short>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Int32: { arrElemMakerCode = MarkerCode.Int32; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <int>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Int64: { arrElemMakerCode = MarkerCode.Int64; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <long>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.UInt16: { arrElemMakerCode = MarkerCode.UInt16; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <ulong>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.UInt32: { arrElemMakerCode = MarkerCode.UInt32; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <uint>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.UInt64: { arrElemMakerCode = MarkerCode.UInt64; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <ulong>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.DateTime: { arrElemMakerCode = MarkerCode.DateTime; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <DateTime>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i].ToBinary()); } WriteEndArray(); } break; case TypeCode.Single: { arrElemMakerCode = MarkerCode.Float32; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <float>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Double: { arrElemMakerCode = MarkerCode.Float64; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <double>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; case TypeCode.Decimal: { arrElemMakerCode = MarkerCode.Decimal; WriteStartArray_T(arrElemMakerCode, memberCount); var list = (IList <decimal>)o_list; for (int i = 0; i < memberCount; ++i) { //write raw bool writer.Write(list[i]); } WriteEndArray(); } break; } if (arrElemMakerCode != MarkerCode.Unknown) { isHandled = true; } } //check if this support native type array *** if (!isHandled) { //just normal list WriteStartArray(); foreach (var e in o_list) { WriteObject(e); } WriteEndArray(); } } else { //just normal list WriteStartArray(); foreach (var e in o_list) { WriteObject(e); } WriteEndArray(); } }