void WriteValueContents(Type knownType, object value) { if (value == null) { _currentPass.Write((int)-1); } else { Type type = value.GetType(); if (type.DerivesFrom <Type>()) { // Treat RuntimeType as if it's Type type = typeof(Type); } if (knownType == type) { _currentPass.Write((int)-2); } else { SerializerRegistry.WriteSerializedTypeId(type, _currentPass); } var serializer = SerializerRegistry.GetSerializer(type); serializer.SerializeConstructor(ref value, this); serializer.SerializeContents(ref value, this); serializer.SerializeBacklinks(ref value, this); } }
public void WriteToBinary(Stream stream, object rootReference) { using (MemoryStream constructorBuffer = new MemoryStream()) using (MemoryStream contentsBuffer = new MemoryStream()) using (MemoryStream backlinkBuffer = new MemoryStream()) { BinaryWriter constructorWriter = new BinaryWriter(constructorBuffer); BinaryWriter contentsWriter = new BinaryWriter(contentsBuffer); BinaryWriter backlinkWriter = new BinaryWriter(backlinkBuffer); BinaryWriter headerWriter = new BinaryWriter(stream); headerWriter.Write(SerializationVersion.Value); IncludeReference(rootReference); bool firstTime; long rootId = _objectIdGenerator.GetId(rootReference, out firstTime); Assert.That(_references.ContainsKey(rootId), "root object not included"); while (_pending.Count > 0) { long id = _pending.Dequeue(); Assert.That(id != 0); object value = _references[id]; Type type = value.GetType(); var serializer = SerializerRegistry.GetSerializer(type); headerWriter.Write(id); headerWriter.Write(constructorWriter.BaseStream.Position); headerWriter.Write(contentsWriter.BaseStream.Position); headerWriter.Write(backlinkWriter.BaseStream.Position); SerializerRegistry.WriteSerializedTypeId(type, headerWriter); try { _currentPass = constructorWriter; serializer.SerializeConstructor(ref value, this); _currentPass = contentsWriter; serializer.SerializeContents(ref value, this); _currentPass = backlinkWriter; serializer.SerializeBacklinks(ref value, this); _currentPass = null; } catch (Exception e) { throw new SerializationException( "Error occurred while serializing value of type '" + type.Name() + "'", e); } } headerWriter.Write((long)0); headerWriter.Write(rootId); constructorWriter.Flush(); contentsWriter.Flush(); backlinkWriter.Flush(); long headerOffsetsLength = 8 * 4; long constructorsOffset = headerWriter.BaseStream.Position + headerOffsetsLength; long contentsOffset = constructorsOffset + constructorBuffer.Length; long backlinkOffset = contentsOffset + contentsBuffer.Length; long endOffset = contentsOffset + contentsBuffer.Length; headerWriter.Write(constructorsOffset); headerWriter.Write(contentsOffset); headerWriter.Write(backlinkOffset); headerWriter.Write(endOffset); constructorBuffer.WriteTo(stream); contentsBuffer.WriteTo(stream); backlinkBuffer.WriteTo(stream); } }
public void WritePrimitive(Type knownType, object value) { Assert.IsNotNull(knownType); Assert.IsNotNull(value); if (knownType == typeof(bool)) { _currentPass.Write((bool)value); } else if (knownType == typeof(byte)) { _currentPass.Write((byte)value); } else if (knownType == typeof(short)) { _currentPass.Write((short)value); } else if (knownType == typeof(ushort)) { _currentPass.Write((ushort)value); } else if (knownType == typeof(int)) { _currentPass.Write((int)value); } else if (knownType == typeof(uint)) { _currentPass.Write((uint)value); } else if (knownType == typeof(long)) { _currentPass.Write((long)value); } else if (knownType == typeof(ulong)) { _currentPass.Write((ulong)value); } else if (knownType == typeof(float)) { _currentPass.Write((float)value); } else if (knownType == typeof(double)) { _currentPass.Write((double)value); } else if (knownType == typeof(decimal)) { _currentPass.Write((decimal)value); } else if (knownType == typeof(char)) { _currentPass.Write((char)value); } else if (knownType == typeof(string)) { _currentPass.Write((string)value); } else if (knownType == typeof(byte[])) { var bytes = (byte[])value; _currentPass.Write((int)bytes.Length); _currentPass.Write(bytes); } else if (knownType == typeof(Type)) { SerializerRegistry.WriteSerializedTypeId((Type)value, _currentPass); } else if (knownType.IsEnum()) { WritePrimitive(Enum.GetUnderlyingType(knownType), value); } else { throw Assert.CreateException( "unhandled primative type '{0}'", knownType.Name()); } }