private T ReadFullObject <T>(int pos) { var hdr = BinaryObjectHeader.Read(Stream, pos); // Validate protocol version. BinaryUtils.ValidateProtocolVersion(hdr.Version); try { // Already read this object? object hndObj; if (_hnds != null && _hnds.TryGetValue(pos, out hndObj)) { return((T)hndObj); } if (hdr.IsUserType && _mode == BinaryMode.ForceBinary) { BinaryObject portObj; if (_detach) { Stream.Seek(pos, SeekOrigin.Begin); portObj = new BinaryObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr); } else { portObj = new BinaryObject(_marsh, Stream.GetArray(), pos, hdr); } T obj = _builder == null ? TypeCaster <T> .Cast(portObj) : TypeCaster <T> .Cast(_builder.Child(portObj)); AddHandle(pos, obj); return(obj); } else { // Find descriptor. var desc = _marsh.GetDescriptor(hdr.IsUserType, hdr.TypeId); // Instantiate object. if (desc.Type == null) { if (desc is BinarySurrogateTypeDescriptor) { throw new BinaryObjectException("Unknown type ID: " + hdr.TypeId); } throw new BinaryObjectException("No matching type found for object [typeId=" + desc.TypeId + ", typeName=" + desc.TypeName + ']'); } // Preserve old frame. var oldHdr = _curHdr; int oldPos = _curPos; var oldStruct = _curStruct; bool oldRaw = _curRaw; var oldSchema = _curSchema; var oldSchemaMap = _curSchemaMap; // Set new frame. _curHdr = hdr; _curPos = pos; SetCurSchema(desc); _curStruct = new BinaryStructureTracker(desc, desc.ReaderTypeStructure); _curRaw = false; // Read object. Stream.Seek(pos + BinaryObjectHeader.Size, SeekOrigin.Begin); var obj = desc.Serializer.ReadBinary <T>(this, desc.Type, pos); _curStruct.UpdateReaderStructure(); // Restore old frame. _curHdr = oldHdr; _curPos = oldPos; _curStruct = oldStruct; _curRaw = oldRaw; _curSchema = oldSchema; _curSchemaMap = oldSchemaMap; return(obj); } } finally { // Advance stream pointer. Stream.Seek(pos + hdr.Length, SeekOrigin.Begin); } }
private T ReadFullObject <T>(int pos) { var hdr = BinaryObjectHeader.Read(Stream, pos); // Validate protocol version. BinaryUtils.ValidateProtocolVersion(hdr.Version); try { // Already read this object? object hndObj; if (_hnds != null && _hnds.TryGetValue(pos, out hndObj)) { return((T)hndObj); } if (hdr.IsUserType && _mode == BinaryMode.ForceBinary) { BinaryObject portObj; if (_detach) { Stream.Seek(pos, SeekOrigin.Begin); portObj = new BinaryObject(_marsh, Stream.ReadByteArray(hdr.Length), 0, hdr); } else { portObj = new BinaryObject(_marsh, Stream.GetArray(), pos, hdr); } T obj = _builder == null ? TypeCaster <T> .Cast(portObj) : TypeCaster <T> .Cast(_builder.Child(portObj)); AddHandle(pos, obj); return(obj); } else { // Find descriptor. IBinaryTypeDescriptor desc; if (!_descs.TryGetValue(BinaryUtils.TypeKey(hdr.IsUserType, hdr.TypeId), out desc)) { throw new BinaryObjectException("Unknown type ID: " + hdr.TypeId); } // Instantiate object. if (desc.Type == null) { throw new BinaryObjectException("No matching type found for object [typeId=" + desc.TypeId + ", typeName=" + desc.TypeName + ']'); } // Preserve old frame. var oldHdr = _curHdr; int oldPos = _curPos; var oldStruct = _curStruct; bool oldRaw = _curRaw; var oldSchema = _curSchema; var oldSchemaMap = _curSchemaMap; // Set new frame. _curHdr = hdr; _curPos = pos; SetCurSchema(desc); _curStruct = new BinaryStructureTracker(desc, desc.ReaderTypeStructure); _curRaw = false; // Read object. Stream.Seek(pos + BinaryObjectHeader.Size, SeekOrigin.Begin); object obj; var sysSerializer = desc.Serializer as IBinarySystemTypeSerializer; if (sysSerializer != null) { obj = sysSerializer.ReadInstance(this); } else { try { obj = FormatterServices.GetUninitializedObject(desc.Type); // Save handle. AddHandle(pos, obj); } catch (Exception e) { throw new BinaryObjectException("Failed to create type instance: " + desc.Type.AssemblyQualifiedName, e); } desc.Serializer.ReadBinary(obj, this); } _curStruct.UpdateReaderStructure(); // Restore old frame. _curHdr = oldHdr; _curPos = oldPos; _curStruct = oldStruct; _curRaw = oldRaw; _curSchema = oldSchema; _curSchemaMap = oldSchemaMap; // Process wrappers. We could introduce a common interface, but for only 2 if-else is faster. var wrappedSerializable = obj as SerializableObjectHolder; if (wrappedSerializable != null) { return((T)wrappedSerializable.Item); } var wrappedDateTime = obj as DateTimeHolder; if (wrappedDateTime != null) { return(TypeCaster <T> .Cast(wrappedDateTime.Item)); } return((T)obj); } } finally { // Advance stream pointer. Stream.Seek(pos + hdr.Length, SeekOrigin.Begin); } }