/// <summary> /// Deserializes an object from a binary source. /// </summary> /// <param name="Reader">Deserializer.</param> /// <param name="DataType">Optional datatype. If not provided, will be read from the binary source.</param> /// <param name="Embedded">If the object is embedded into another.</param> /// <param name="CheckFieldNames">If field names are to be extended.</param> /// <returns>Deserialized object.</returns> public object Deserialize(IDeserializer Reader, uint?DataType, bool Embedded, bool CheckFieldNames) { StreamBookmark Bookmark = Reader.GetBookmark(); uint? DataTypeBak = DataType; uint FieldDataType; ulong FieldCode; Guid ObjectId = Embedded ? Guid.Empty : Reader.ReadGuid(); string TypeName; string FieldName; string CollectionName; if (!Embedded) { Reader.SkipVariableLengthUInt64(); // Content length. } if (!DataType.HasValue) { DataType = Reader.ReadBits(6); if (DataType.Value == ObjectSerializer.TYPE_NULL) { return(null); } } switch (DataType.Value) { case ObjectSerializer.TYPE_OBJECT: if (Embedded && Reader.BitOffset > 0 && Reader.ReadBit()) { ObjectId = Reader.ReadGuid(); } break; case ObjectSerializer.TYPE_BOOLEAN: return(Reader.ReadBit()); case ObjectSerializer.TYPE_BYTE: return(Reader.ReadByte()); case ObjectSerializer.TYPE_INT16: return(Reader.ReadInt16()); case ObjectSerializer.TYPE_INT32: return(Reader.ReadInt32()); case ObjectSerializer.TYPE_INT64: return(Reader.ReadInt64()); case ObjectSerializer.TYPE_SBYTE: return(Reader.ReadSByte()); case ObjectSerializer.TYPE_UINT16: return(Reader.ReadUInt16()); case ObjectSerializer.TYPE_UINT32: return(Reader.ReadUInt32()); case ObjectSerializer.TYPE_UINT64: return(Reader.ReadUInt64()); case ObjectSerializer.TYPE_DECIMAL: return(Reader.ReadDecimal()); case ObjectSerializer.TYPE_DOUBLE: return(Reader.ReadDouble()); case ObjectSerializer.TYPE_SINGLE: return(Reader.ReadSingle()); case ObjectSerializer.TYPE_DATETIME: return(Reader.ReadDateTime()); case ObjectSerializer.TYPE_DATETIMEOFFSET: return(Reader.ReadDateTimeOffset()); case ObjectSerializer.TYPE_TIMESPAN: return(Reader.ReadTimeSpan()); case ObjectSerializer.TYPE_CHAR: return(Reader.ReadChar()); case ObjectSerializer.TYPE_STRING: return(Reader.ReadString()); case ObjectSerializer.TYPE_CI_STRING: return(new CaseInsensitiveString(Reader.ReadString())); case ObjectSerializer.TYPE_ENUM: return(Reader.ReadString()); case ObjectSerializer.TYPE_BYTEARRAY: return(Reader.ReadByteArray()); case ObjectSerializer.TYPE_GUID: return(Reader.ReadGuid()); case ObjectSerializer.TYPE_NULL: return(null); case ObjectSerializer.TYPE_ARRAY: throw new Exception("Arrays must be embedded in objects."); default: throw new Exception("Object or value expected."); } bool Normalized = this.NormalizedNames; if (Normalized) { FieldCode = Reader.ReadVariableLengthUInt64(); TypeName = null; } else { FieldCode = 0; TypeName = Reader.ReadString(); } if (Embedded) { if (Normalized) { ulong CollectionCode = Reader.ReadVariableLengthUInt64(); CollectionName = this.context.GetFieldName(null, CollectionCode); } else { CollectionName = Reader.ReadString(); } } else { CollectionName = Reader.CollectionName; } if (Normalized) { if (FieldCode == 0) { TypeName = string.Empty; } else if (CheckFieldNames) { TypeName = this.context.GetFieldName(CollectionName, FieldCode); } else { TypeName = CollectionName + "." + FieldCode.ToString(); } } if (this.returnTypedObjects && !string.IsNullOrEmpty(TypeName)) { Type DesiredType = Types.GetType(TypeName); if (DesiredType is null) { DesiredType = typeof(GenericObject); } if (DesiredType != typeof(GenericObject)) { IObjectSerializer Serializer2 = this.context.GetObjectSerializer(DesiredType); Reader.SetBookmark(Bookmark); return(Serializer2.Deserialize(Reader, DataTypeBak, Embedded)); } } LinkedList <KeyValuePair <string, object> > Properties = new LinkedList <KeyValuePair <string, object> >(); while (true) { if (Normalized) { FieldCode = Reader.ReadVariableLengthUInt64(); if (FieldCode == 0) { break; } if (CheckFieldNames) { FieldName = this.context.GetFieldName(CollectionName, FieldCode); } else { FieldName = CollectionName + "." + FieldCode.ToString(); } } else { FieldName = Reader.ReadString(); if (string.IsNullOrEmpty(FieldName)) { break; } } FieldDataType = Reader.ReadBits(6); switch (FieldDataType) { case ObjectSerializer.TYPE_BOOLEAN: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadBoolean())); break; case ObjectSerializer.TYPE_BYTE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadByte())); break; case ObjectSerializer.TYPE_INT16: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt16())); break; case ObjectSerializer.TYPE_INT32: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt32())); break; case ObjectSerializer.TYPE_INT64: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt64())); break; case ObjectSerializer.TYPE_SBYTE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadSByte())); break; case ObjectSerializer.TYPE_UINT16: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt16())); break; case ObjectSerializer.TYPE_UINT32: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt32())); break; case ObjectSerializer.TYPE_UINT64: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt64())); break; case ObjectSerializer.TYPE_DECIMAL: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDecimal())); break; case ObjectSerializer.TYPE_DOUBLE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDouble())); break; case ObjectSerializer.TYPE_SINGLE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadSingle())); break; case ObjectSerializer.TYPE_DATETIME: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDateTime())); break; case ObjectSerializer.TYPE_DATETIMEOFFSET: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDateTimeOffset())); break; case ObjectSerializer.TYPE_TIMESPAN: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadTimeSpan())); break; case ObjectSerializer.TYPE_CHAR: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadChar())); break; case ObjectSerializer.TYPE_STRING: case ObjectSerializer.TYPE_ENUM: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadString())); break; case ObjectSerializer.TYPE_CI_STRING: Properties.AddLast(new KeyValuePair <string, object>(FieldName, new CaseInsensitiveString(Reader.ReadString()))); break; case ObjectSerializer.TYPE_BYTEARRAY: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadByteArray())); break; case ObjectSerializer.TYPE_GUID: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadGuid())); break; case ObjectSerializer.TYPE_NULL: Properties.AddLast(new KeyValuePair <string, object>(FieldName, null)); break; case ObjectSerializer.TYPE_ARRAY: Properties.AddLast(new KeyValuePair <string, object>(FieldName, this.ReadGenericArray(Reader))); break; case ObjectSerializer.TYPE_OBJECT: Properties.AddLast(new KeyValuePair <string, object>(FieldName, this.Deserialize(Reader, FieldDataType, true))); break; default: throw new Exception("Unrecognized data type: " + FieldDataType.ToString()); } } return(new GenericObject(CollectionName, TypeName, ObjectId, Properties)); }
/// <summary> /// Deserializes an object from a binary source. /// </summary> /// <param name="Reader">Binary deserializer.</param> /// <param name="DataType">Optional datatype. If not provided, will be read from the binary source.</param> /// <param name="Embedded">If the object is embedded into another.</param> /// <param name="CheckFieldNames">If field names are to be extended.</param> /// <returns>Deserialized object.</returns> public object Deserialize(BinaryDeserializer Reader, uint?DataType, bool Embedded, bool CheckFieldNames) { uint FieldDataType; ulong FieldCode; ulong CollectionCode; StreamBookmark Bookmark = Reader.GetBookmark(); uint? DataTypeBak = DataType; Guid ObjectId = Embedded ? Guid.Empty : Reader.ReadGuid(); ulong ContentLen = Embedded ? 0 : Reader.ReadVariableLengthUInt64(); string TypeName; string FieldName; string CollectionName; if (!DataType.HasValue) { DataType = Reader.ReadBits(6); if (DataType.Value == ObjectSerializer.TYPE_NULL) { return(null); } } switch (DataType.Value) { case ObjectSerializer.TYPE_OBJECT: break; case ObjectSerializer.TYPE_BOOLEAN: return(Reader.ReadBit()); case ObjectSerializer.TYPE_BYTE: return(Reader.ReadByte()); case ObjectSerializer.TYPE_INT16: return(Reader.ReadInt16()); case ObjectSerializer.TYPE_INT32: return(Reader.ReadInt32()); case ObjectSerializer.TYPE_INT64: return(Reader.ReadInt64()); case ObjectSerializer.TYPE_SBYTE: return(Reader.ReadSByte()); case ObjectSerializer.TYPE_UINT16: return(Reader.ReadUInt16()); case ObjectSerializer.TYPE_UINT32: return(Reader.ReadUInt32()); case ObjectSerializer.TYPE_UINT64: return(Reader.ReadUInt64()); case ObjectSerializer.TYPE_DECIMAL: return(Reader.ReadDecimal()); case ObjectSerializer.TYPE_DOUBLE: return(Reader.ReadDouble()); case ObjectSerializer.TYPE_SINGLE: return(Reader.ReadSingle()); case ObjectSerializer.TYPE_DATETIME: return(Reader.ReadDateTime()); case ObjectSerializer.TYPE_TIMESPAN: return(Reader.ReadTimeSpan()); case ObjectSerializer.TYPE_CHAR: return(Reader.ReadChar()); case ObjectSerializer.TYPE_STRING: return(Reader.ReadString()); case ObjectSerializer.TYPE_ENUM: return(Reader.ReadString()); case ObjectSerializer.TYPE_BYTEARRAY: return(Reader.ReadByteArray()); case ObjectSerializer.TYPE_GUID: return(Reader.ReadGuid()); case ObjectSerializer.TYPE_NULL: return(null); default: throw new Exception("Object or value expected."); } FieldCode = Reader.ReadVariableLengthUInt64(); if (Embedded) { CollectionCode = Reader.ReadVariableLengthUInt64(); CollectionName = this.provider.GetFieldName(null, CollectionCode); } else { CollectionName = Reader.CollectionName; } if (FieldCode == 0) { TypeName = string.Empty; } else if (CheckFieldNames) { TypeName = this.provider.GetFieldName(CollectionName, FieldCode); } else { TypeName = CollectionName + "." + FieldCode.ToString(); } LinkedList <KeyValuePair <string, object> > Properties = new LinkedList <KeyValuePair <string, object> >(); while ((FieldCode = Reader.ReadVariableLengthUInt64()) != 0) { if (CheckFieldNames) { FieldName = this.provider.GetFieldName(CollectionName, FieldCode); } else { FieldName = CollectionName + "." + FieldCode.ToString(); } FieldDataType = Reader.ReadBits(6); switch (FieldDataType) { case ObjectSerializer.TYPE_BOOLEAN: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadBoolean())); break; case ObjectSerializer.TYPE_BYTE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadByte())); break; case ObjectSerializer.TYPE_INT16: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt16())); break; case ObjectSerializer.TYPE_INT32: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt32())); break; case ObjectSerializer.TYPE_INT64: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadInt64())); break; case ObjectSerializer.TYPE_SBYTE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadSByte())); break; case ObjectSerializer.TYPE_UINT16: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt16())); break; case ObjectSerializer.TYPE_UINT32: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt32())); break; case ObjectSerializer.TYPE_UINT64: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadUInt64())); break; case ObjectSerializer.TYPE_DECIMAL: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDecimal())); break; case ObjectSerializer.TYPE_DOUBLE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDouble())); break; case ObjectSerializer.TYPE_SINGLE: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadSingle())); break; case ObjectSerializer.TYPE_DATETIME: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadDateTime())); break; case ObjectSerializer.TYPE_TIMESPAN: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadTimeSpan())); break; case ObjectSerializer.TYPE_CHAR: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadChar())); break; case ObjectSerializer.TYPE_STRING: case ObjectSerializer.TYPE_ENUM: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadString())); break; case ObjectSerializer.TYPE_BYTEARRAY: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadByteArray())); break; case ObjectSerializer.TYPE_GUID: Properties.AddLast(new KeyValuePair <string, object>(FieldName, Reader.ReadGuid())); break; case ObjectSerializer.TYPE_NULL: Properties.AddLast(new KeyValuePair <string, object>(FieldName, null)); break; case ObjectSerializer.TYPE_ARRAY: Properties.AddLast(new KeyValuePair <string, object>(FieldName, this.ReadGenericArray(Reader))); break; case ObjectSerializer.TYPE_OBJECT: Properties.AddLast(new KeyValuePair <string, object>(FieldName, this.Deserialize(Reader, FieldDataType, true))); break; default: throw new Exception("Unrecognized data type: " + FieldDataType.ToString()); } } return(new GenericObject(CollectionName, TypeName, ObjectId, Properties)); }