예제 #1
0
        void WriteValueContents(Type knownType, object value)
        {
            if (value == null)
            {
                CurrentGroup.Add(new XAttribute("type", "null"));
            }
            else
            {
                Type type = value.GetType();

                if (type.DerivesFrom <Type>())
                {
                    // Treat RuntimeType as if it's Type
                    type = typeof(Type);
                }

                var serializer = SerializerRegistry.GetSerializer(type);
                serializer.SerializeConstructor(ref value, this);
                serializer.SerializeContents(ref value, this);
                serializer.SerializeBacklinks(ref value, this);

                if (type != knownType)
                {
                    CurrentGroup.Add(new XAttribute("type", SerializerRegistry.GetSerializedTypeName(type)));
                }
            }
        }
        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);
            }
        }
예제 #3
0
        object ReadValueContents(Type knownType)
        {
            int typeIndex = _binaryReader.ReadInt32();

            if (typeIndex == -1)
            {
                return(null);
            }

            Type type;

            if (typeIndex == -2)
            {
                type = knownType;
            }
            else
            {
                type = SerializerRegistry.ReadSerializedTypeId(typeIndex, _binaryReader);
            }

            var serializer = SerializerRegistry.GetSerializer(type);

            object value;

            serializer.DeserializeConstructor(out value, _version, this);
            serializer.DeserializeContents(ref value, _version, this);
            serializer.DeserializeBacklinks(ref value, _version, this);
            return(value);
        }
예제 #4
0
        object ReadValueContents(Type knownType)
        {
            Type type;
            var  typeAttrib = CurrentGroup.Attribute("type");

            if (typeAttrib == null)
            {
                type = knownType;
            }
            else if (typeAttrib.Value == "null")
            {
                return(null);
            }
            else
            {
                type = SerializerRegistry.ParseSerializedType(typeAttrib.Value);
            }

            var serializer = SerializerRegistry.GetSerializer(type);

            object value;

            serializer.DeserializeConstructor(out value, _version, this);
            serializer.DeserializeContents(ref value, _version, this);
            serializer.DeserializeBacklinks(ref value, _version, this);
            return(value);
        }
예제 #5
0
 object ReadContents(Type knownType, bool allowCircularDependencies)
 {
     if (SerializerRegistry.IsPrimitive(knownType))
     {
         return(ReadValueContents(knownType));
     }
     else
     {
         return(ReadReferenceContents(knownType, allowCircularDependencies));
     }
 }
 void WriteContents(Type knownType, object value)
 {
     if (SerializerRegistry.IsPrimitive(knownType))
     {
         WriteValueContents(knownType, value);
     }
     else
     {
         WriteReferenceContents(knownType, value);
     }
 }
예제 #7
0
        public XElement WriteXml(string rootName, object rootReference)
        {
            Assert.That(!_hasWritten);
            _hasWritten = true;

            IncludeReference(rootReference);

            Assert.That(_groups.Count == 0);

            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();
                object value      = _references[id];
                Type   type       = value.GetType();
                var    serializer = SerializerRegistry.GetSerializer(type);

                try
                {
                    _groups.Push(_lookup[id]);
                    serializer.SerializeConstructor(ref value, this);
                    serializer.SerializeContents(ref value, this);
                    serializer.SerializeBacklinks(ref value, this);
                    _groups.Pop();
                }
                catch (Exception e)
                {
                    throw new SerializationException(
                              "Error occurred while serializing value of type '" + type.Name() + "'", e);
                }
            }

            Assert.That(_groups.Count == 0);

            XElement rootElement = new XElement(rootName);

            rootElement.Add(new XAttribute("id", rootId));
            rootElement.Add(new XAttribute("version", SerializationVersion.Value));
            foreach (var cur in _lookup.Values)
            {
                rootElement.Add(cur);
            }
            return(rootElement);
        }
예제 #8
0
        public object ReadXml()
        {
            var  root   = _doc.Root;
            long rootId = (long)root.GetAttribute("id");

            _version = (int)root.GetAttribute("version");

            Assert.That(_rootReferences.IsEmpty());

            foreach (var element in root.Elements())
            {
                Assert.That(element.Name.LocalName == "Reference");

                var id       = (long)element.GetAttribute("id");
                var typeName = (string)element.GetAttribute("type");

                var info = new ReadInfo();

                info.Element        = element;
                info.SerializedType = SerializerRegistry.ParseSerializedType(typeName);
                info.Serializer     = SerializerRegistry.GetSerializer(info.SerializedType);

                _rootReferences.Add(id, info);
            }

            foreach (var info in _rootReferences.Values)
            {
                DeserializeConstructor(info);
                DeserializeContents(info, false);
            }

            foreach (var info in _rootReferences.Values)
            {
                _groups.Push(info.Element);
                info.Serializer.DeserializeBacklinks(ref info.Value, _version, this);
                _groups.Pop();
            }

            foreach (var info in _rootReferences.Values)
            {
                info.Serializer.DeserializationComplete(ref info.Value, _version);
            }

            return(_rootReferences[rootId].Value);
        }
예제 #9
0
        public void Write(Type knownType, string groupName, object value)
        {
            Assert.IsNotNull(groupName);

            var element = new XElement(groupName);

            CurrentGroup.Add(element);
            _groups.Push(element);

            if (SerializerRegistry.IsPrimitive(knownType))
            {
                WriteValueContents(knownType, value);
            }
            else
            {
                WriteReferenceContents(knownType, value);
            }

            _groups.Pop();
        }
예제 #10
0
        public void IncludeReference(object value)
        {
            if (value == null)
            {
                return;
            }

            Type type = value.GetType();

            bool firstTime;
            long id = _objectIdGenerator.GetId(value, out firstTime);

            if (!_lookup.ContainsKey(id))
            {
                XElement rootElement = new XElement("Reference");
                rootElement.Add(new XAttribute("id", id));
                rootElement.Add(new XAttribute("type", SerializerRegistry.GetSerializedTypeName(type)));
                _lookup.Add(id, rootElement);
                _references.Add(id, value);
                _pending.Enqueue(id);
            }
        }
예제 #11
0
        public void WritePrimitive(Type knownType, object value)
        {
            Assert.IsNotNull(knownType);
            Assert.IsNotNull(value);

            if (knownType == typeof(bool))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(byte))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(short))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(ushort))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(int))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(uint))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(long))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(ulong))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(float))
            {
                CurrentGroup.Value = ((float)value).ToString("R");
            }
            else if (knownType == typeof(double))
            {
                CurrentGroup.Value = ((double)value).ToString("R");
            }
            else if (knownType == typeof(decimal))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(char))
            {
                CurrentGroup.Value = value.ToString();
            }
            else if (knownType == typeof(string))
            {
                CurrentGroup.Value = (string)value;
            }
            else if (knownType == typeof(byte[]))
            {
                CurrentGroup.Value = Convert.ToBase64String((byte[])value);
            }
            else if (knownType == typeof(Type))
            {
                CurrentGroup.Value = SerializerRegistry.GetSerializedTypeName((Type)value);
            }
            else if (knownType.IsEnum())
            {
                CurrentGroup.Value = value.ToString();
            }
            else
            {
                throw Assert.CreateException(
                          "unhandled primative type '{0}'", knownType.Name());
            }
        }
예제 #12
0
        public object ReadFromBinary()
        {
            _version = _binaryReader.ReadInt32();

            List <ReadInfo> rootReferencesInOrder = new List <ReadInfo>();

            while (true)
            {
                long id = _binaryReader.ReadInt64();
                if (id == 0)
                {
                    break;
                }

                var info = new ReadInfo();
                info.Id = id;
                info.ConstructorPosition = _binaryReader.ReadInt64();
                info.ContentsPosition    = _binaryReader.ReadInt64();
                info.BacklinkPosition    = _binaryReader.ReadInt64();
                info.SerializedType      = SerializerRegistry.ReadSerializedTypeId(_binaryReader);
                info.Serializer          = SerializerRegistry.GetSerializer(info.SerializedType);

                _rootReferences.Add(id, info);
                rootReferencesInOrder.Add(info);
            }

            long rootId = _binaryReader.ReadInt64();
            long constructorSeekOffset = _binaryReader.ReadInt64();
            long contentsSeekOffset    = _binaryReader.ReadInt64();
            long backlinkSeekOffset    = _binaryReader.ReadInt64();

            // endSeekOffset
            _binaryReader.ReadInt64();

            foreach (var info in rootReferencesInOrder)
            {
                info.ConstructorPosition += constructorSeekOffset;
                info.ContentsPosition    += contentsSeekOffset;
                info.BacklinkPosition    += backlinkSeekOffset;
            }

            foreach (var info in rootReferencesInOrder)
            {
                DeserializeConstructor(info);
                DeserializeContents(info, false);
            }

            _binaryReader.BaseStream.Seek(backlinkSeekOffset, SeekOrigin.Begin);

            foreach (var info in rootReferencesInOrder)
            {
                info.Serializer.DeserializeBacklinks(ref info.Value, _version, this);
            }

            foreach (var info in _rootReferences.Values)
            {
                info.Serializer.DeserializationComplete(ref info.Value, _version);
            }

            return(_rootReferences[rootId].Value);
        }
예제 #13
0
        public object ReadPrimitive(Type knownType)
        {
            Assert.IsNotNull(knownType);

            if (knownType == typeof(bool))
            {
                return(_binaryReader.ReadBoolean());
            }
            else if (knownType == typeof(byte))
            {
                return(_binaryReader.ReadByte());
            }
            else if (knownType == typeof(short))
            {
                return(_binaryReader.ReadInt16());
            }
            else if (knownType == typeof(ushort))
            {
                return(_binaryReader.ReadUInt16());
            }
            else if (knownType == typeof(int))
            {
                return(_binaryReader.ReadInt32());
            }
            else if (knownType == typeof(uint))
            {
                return(_binaryReader.ReadUInt32());
            }
            else if (knownType == typeof(long))
            {
                return(_binaryReader.ReadInt64());
            }
            else if (knownType == typeof(ulong))
            {
                return(_binaryReader.ReadUInt64());
            }
            else if (knownType == typeof(float))
            {
                return(_binaryReader.ReadSingle());
            }
            else if (knownType == typeof(double))
            {
                return(_binaryReader.ReadDouble());
            }
            else if (knownType == typeof(decimal))
            {
                return(_binaryReader.ReadDecimal());
            }
            else if (knownType == typeof(char))
            {
                return(_binaryReader.ReadChar());
            }
            else if (knownType == typeof(string))
            {
                return(_binaryReader.ReadString());
            }
            else if (knownType == typeof(byte[]))
            {
                var length = _binaryReader.ReadInt32();
                return(_binaryReader.ReadBytes(length));
            }
            else if (knownType == typeof(Type))
            {
                return(SerializerRegistry.ReadSerializedTypeId(_binaryReader));
            }
            else if (knownType.IsEnum())
            {
                return(Enum.ToObject(knownType, ReadPrimitive(Enum.GetUnderlyingType(knownType))));
            }

            throw Assert.CreateException(
                      "unhandled primative type '{0}'", knownType.Name());
        }
예제 #14
0
        public object ReadPrimitive(Type knownType)
        {
            Assert.IsNotNull(knownType);

            if (knownType == typeof(bool))
            {
                return(bool.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(byte))
            {
                return(byte.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(short))
            {
                return(short.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(ushort))
            {
                return(ushort.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(int))
            {
                return(int.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(uint))
            {
                return(uint.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(long))
            {
                return(long.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(ulong))
            {
                return(ulong.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(float))
            {
                return(float.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(double))
            {
                return(double.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(decimal))
            {
                return(decimal.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(char))
            {
                return(char.Parse(CurrentGroup.Value));
            }
            else if (knownType == typeof(string))
            {
                return(CurrentGroup.Value);
            }
            else if (knownType == typeof(byte[]))
            {
                return(Convert.FromBase64String(CurrentGroup.Value));
            }
            else if (knownType == typeof(Type))
            {
                return(SerializerRegistry.ParseSerializedType(CurrentGroup.Value));
            }
            else if (knownType.IsEnum())
            {
                return(Enum.Parse(knownType, CurrentGroup.Value));
            }

            throw Assert.CreateException(
                      "unhandled primative type '{0}'", knownType.Name());
        }
        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());
            }
        }