コード例 #1
0
 /// <summary>
 /// Called by serializer when recursing to base classes or
 /// class member variables to duplicate the context args of
 /// the caller so caller isn't unexpectedly affected by logic
 /// in the child processing
 /// </summary>
 /// <returns></returns>
 public TypeSerializationArgs Clone()
 {
     TypeSerializationArgs clone = new TypeSerializationArgs();
     
     clone.Writer = this.Writer;
     clone.Reader = this.Reader;
     clone.Flags = this.Flags;
     clone.NameTable = this.NameTable;            
     clone.SerializationInfo = this.SerializationInfo;
     
     //  IsBaseClass
     //  Indicates that the serialization call is being made to
     //  automatically serialize a base class. This needs to be
     //  cleared at each level so that it isn't propagated to
     //  the processing of the base class' properties so we don't
     //  retain the value from the source args.            
     
     //  Succeeded
     //  Success is determined at each level and shouldn't be
     //  affected by caller state. This technically shouldn't
     //  matter because the caller should have stopped processing
     //  if an error occurred.
     
     return clone;
 }
コード例 #2
0
ファイル: Serializer.cs プロジェクト: wilson0x4d/DataRelay
        /// <summary>
        /// Serializes an object
        /// </summary>
        /// <param name="writer">The target stream</param>
        /// <param name="instance">The object to serialize. This can be null.</param>
        /// <param name="flags">One or more <see cref="SerializedFlags"/> options</param>
        public static void Serialize <T>(IPrimitiveWriter writer, T instance, SerializerFlags flags)
        {
            TypeSerializationInfo typeInfo = TypeSerializationInfo.GetTypeInfo <T>(instance);
            TypeSerializationArgs args     = new TypeSerializationArgs();

            args.Writer = writer;
            args.Flags  = flags;

            typeInfo.Serialize(instance, args);
        }
コード例 #3
0
        bool DeserializeCustomSerializable(ref object instance, TypeSerializationArgs args)
        {
            if (instance == null)
            {
                instance = CreateInstance();
            }

            ICustomSerializable ics = instance as ICustomSerializable;

            ics.Deserialize(args.Reader);
            return(true);
        }
コード例 #4
0
 void SerializeCustomSerializable(object instance, TypeSerializationArgs args)
 {
     if (instance == null)
     {
         throw new ArgumentNullException("Cannot serialize null object with ICustomSerializable");
     }
     else
     {
         ICustomSerializable ics = instance as ICustomSerializable;
         ics.Serialize(args.Writer);
     }
 }
コード例 #5
0
 void SerializeVersionSerializable(object instance, TypeSerializationArgs args)
 {
     if (instance == null)
     {
         args.Writer.Write(NullVersion);
     }
     else
     {
         IVersionSerializable ivs = instance as IVersionSerializable;
         args.Writer.Write((byte)ivs.CurrentVersion);
         ivs.Serialize(args.Writer);
     }
 }
コード例 #6
0
        public static object Deserialize(Stream stream, SerializerFlags flags, CompressionImplementation compression, Type instanceType)
        {
            TypeSerializationInfo typeInfo = null;
            TypeSerializationArgs args     = new TypeSerializationArgs();
            object instance = Activator.CreateInstance(instanceType);

            args.Flags  = flags;
            args.Reader = GetReader(stream, flags, compression);

            typeInfo = TypeSerializationInfo.GetTypeInfo(instanceType);
            typeInfo.Deserialize(ref instance, args);

            return(instance);
        }
コード例 #7
0
        bool DeserializeVersionSerializable(ref object instance, TypeSerializationArgs args)
        {
            byte version = args.Reader.ReadByte();
            bool success = false;

            if (version != NullVersion)
            {
                if (instance == null)
                {
                    instance = CreateInstance();
                }

                IVersionSerializable ivs = instance as IVersionSerializable;
                args.Reader.Response = SerializationResponse.Success;
                try
                {
                    ivs.Deserialize(args.Reader, version);
                }
                catch (Exception exc)
                {
                    const bool indicateTruncate = true;
                    string     data             = Algorithm.ToByteString(args.Reader.BaseStream, 2 << 11, indicateTruncate);
                    throw new SerializationException(string.Format("Failed to deserialized type {0} version {1} data {2}",
                                                                   instance.GetType().FullName, version, data), exc);
                }
                success = true;

                //throw exception if necessary
                switch (args.Reader.Response)
                {
                case SerializationResponse.Handled:
                    throw new HandledVersionException(ivs.CurrentVersion, version);

                case SerializationResponse.Unhandled:
                    throw new UnhandledVersionException(ivs.CurrentVersion, version);

                default:
                    break;
                }
            }
            else
            {
                instance = null;
            }

            return(success);
        }
コード例 #8
0
        /// <summary>
        /// Internal use only
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <param name="args"></param>
        public static void Serialize <T>(T instance, TypeSerializationArgs args)
        {
            TypeSerializationInfo typeInfo = null;

            if (args.IsBaseClass)
            {
                //  For base class handling, make sure we explicitly get the type
                //  info for the template parameter
                typeInfo = TypeSerializationInfo.GetTypeInfo(typeof(T));
            }
            else
            {
                //  Otherwise use the default type detection
                typeInfo = TypeSerializationInfo.GetTypeInfo <T>(instance);
            }

            typeInfo.Serialize(instance, args);
        }
コード例 #9
0
 public bool Deserialize(ref object instance, TypeSerializationArgs args)
 {
     if (deserializeMethod == null)
     {
         lock (syncRoot)
         {
             if (deserializeMethod == null)
             {
                 deferredInitializationAction();
                 deferredInitializationAction = null;
             }
         }
     }
     if (attribute != null && attribute.SuppressWarningExceptions)
     {
         using (Serializer.OpenSuppressAlertScope())
         {
             return(this.deserializeMethod(ref instance, args));
         }
     }
     return(this.deserializeMethod(ref instance, args));
 }
コード例 #10
0
        /// <summary>
        /// Internal use only
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static bool Deserialize <T>(ref object instance, TypeSerializationArgs args)
        {
            TypeSerializationInfo typeInfo = null;

            //  Check arguments
            if (args.Reader == null)
            {
                Debug.Fail("Input stream is null");
                throw new ArgumentNullException("reader");
            }

            if (args.IsBaseClass)
            {
                //  For base class handling, make sure we explicitly get the type
                //  info for the template parameter
                typeInfo = TypeSerializationInfo.GetTypeInfo(typeof(T));
            }
            else
            {
                //  Otherwise use the default type detection
                typeInfo = TypeSerializationInfo.GetTypeInfo <T>(instance);
            }
            return(typeInfo.Deserialize(ref instance, args));
        }
コード例 #11
0
        void SerializeAutoSerializable(object instance, TypeSerializationArgs args)
        {
            TypeSerializationArgs callerArgs = args;

            args = args.Clone();

            if (this.IsInline)
            {
                //  Inline objects are serialized with only a 2-byte length prefix
                //  No version info or anything else
                int  length         = 0;
                long lengthPosition = args.Writer.BaseStream.Position;
                long endPosition    = -1;

                args.Writer.Write((byte)length);

                if (instance != null)
                {
                    args.Header                = new TypeSerializationHeader();
                    args.Header.DataVersion    = 1;
                    args.Header.DataMinVersion = 1;

                    this.autoSerializeMethod(instance, args);
                    endPosition = args.Writer.BaseStream.Position;

                    length = (int)((endPosition - lengthPosition) - InlineHeaderSize);
                    if (length > MaxInlineSize)
                    {
                        throw new NotSupportedException(string.Format(
                                                            "Inline classes must be {0} bytes or less. Class {1} serialized to {2} bytes.",
                                                            MaxInlineSize,
                                                            instance.GetType().FullName,
                                                            length
                                                            ));
                    }

                    args.Writer.BaseStream.Position = lengthPosition;
                    args.Writer.Write((byte)length);
                    args.Writer.BaseStream.Position = endPosition;
                }
            }
            else if (instance == null)
            {
                args.Writer.Write(NullVersion);
            }
            else
            {
                args.Header                = new TypeSerializationHeader();
                args.Header.DataVersion    = (byte)this.CurrentVersion;
                args.Header.DataMinVersion = (byte)this.MinVersion;

                //  If min version is less than or equal legacy version then write
                //  out legacy version + 1 as the min version in the data stream.This
                //  is to prevent older class definitions from attempting to
                //  deserialize the new data using IVersionSerializable
                if ((this.LegacyVersion > 0) && (this.LegacyVersion >= this.MinVersion))
                {
                    args.Header.DataMinVersion = (byte)(this.LegacyVersion + 1);
                }

                //  If this isn't a base class invocation then make sure
                //  SerializationInfo is initialized for the first time.
                //  If it is a base class then get the base class info
                //  from the parent's SerializationInfo
                if (callerArgs.IsBaseClass == false)
                {
                    ISerializationInfo info = instance as ISerializationInfo;

                    if (info != null)
                    {
                        args.SerializationInfo = info.SerializationInfo;
                    }
                    else
                    {
                        //  SerializationInfo may not be null in this case
                        //  because this may be an object contained in a parent
                        //  class. We need to make sure the child object doesn't
                        //  use the serialization info from the container
                        args.SerializationInfo = null;
                    }
                }
                else if (args.SerializationInfo != null)
                {
                    args.SerializationInfo = callerArgs.SerializationInfo.BaseClassInfo;
                }

                //  Handled cached serialization info if original data
                //  was newer than the class definition that deserialized it
                if (
                    (args.SerializationInfo != null) &&
                    (args.SerializationInfo.Version > this.CurrentVersion)
                    )
                {
                    args.Header.DataVersion    = (byte)args.SerializationInfo.Version;
                    args.Header.DataMinVersion = (byte)args.SerializationInfo.MinVersion;
                }

                //  Write a special version byte to indicate this serialized
                //  data uses a header. Because this version is guaranteed to
                //  be higher than actual object versions, older serialization
                //  code will simply treat this is a higher unhandled version,
                //  which is true.
                args.Writer.Write(HasHeaderVersion);

                //  Write the header with placeholder data
                args.Header.Write(args.Writer);

                //  Serialize the object
                this.autoSerializeMethod(instance, args);

                //  Update the header with final data. Note that the
                //  TypeSerializationHeader class takes care of the
                //  stream position
                args.Header.Write(args.Writer);
            }
        }
コード例 #12
0
 bool DeserializeUnknownType(ref object instance, TypeSerializationArgs args)
 {
     instance = args.Reader.Read();
     return(true);
 }
コード例 #13
0
 void SerializeUnknownType(object instance, TypeSerializationArgs args)
 {
     args.Writer.Write(instance);
 }
コード例 #14
0
        bool DeserializeAutoSerializable(ref object instance, TypeSerializationArgs args)
        {
            byte dataVersion = 1;
            bool isSerializationInfoSupported = (instance == null) ? this.supportsSerializationInfo : (instance is ISerializationInfo);
            TypeSerializationArgs callerArgs  = args;
            byte dataMinVersion = 0;

            //  Create a local copy of args so we don't mess with caller's context
            args = args.Clone();

            if (this.IsInline)
            {
                //  Read length prefix. If length is 0 then object is null
                byte length = args.Reader.ReadByte();
                if (length == 0)
                {
                    dataVersion = NullVersion;
                }
            }
            else
            {
                dataVersion = args.Reader.ReadByte();
            }

            if (dataVersion == NullVersion)
            {
                instance = null;
                return(false);
            }

            if (dataVersion == HasHeaderVersion)
            {
                args.Header = new TypeSerializationHeader();
                args.Header.Read(args.Reader);
                dataVersion    = args.Header.DataVersion;
                dataMinVersion = args.Header.DataMinVersion;
            }

            if (
                //  Version of the data is less than our supported minimum version
                //	OR data is a lower version than the min version that can be deserialized
                //  OR data is a higher version but this type isn't forward compatible
                //  OR data has a min version that is higher than this current type definition
                (dataVersion < this.MinVersion) ||
                (this.CurrentVersion < dataMinVersion) ||
                (dataVersion < this.MinDeserializeVersion) ||
                ((dataVersion > this.CurrentVersion) && (isSerializationInfoSupported == false)) ||
                ((args.Header != null) && (args.Header.DataMinVersion > this.CurrentVersion))
                )
            {
                throw new UnhandledVersionException(this.CurrentVersion, dataVersion);
            }
            else
            {
                if (instance == null)
                {
                    instance = CreateInstance();
                }

                //  If this is the derived class then create a new top-level
                //  serialization info. If this is the base class then set
                //  the base class serialization info
                if (callerArgs.IsBaseClass == false)
                {
                    args.SerializationInfo = new SerializationInfo();

                    if (isSerializationInfoSupported == true)
                    {
                        ((ISerializationInfo)instance).SerializationInfo = args.SerializationInfo;
                    }
                }
                else
                {
                    callerArgs.SerializationInfo.BaseClassInfo = new SerializationInfo();
                    args.SerializationInfo = callerArgs.SerializationInfo.BaseClassInfo;
                }

                args.SerializationInfo.Version = dataVersion;

                if (args.Header != null)
                {
                    args.SerializationInfo.MinVersion = args.Header.DataMinVersion;
                }

                this.autoDeserializeMethod(instance, dataVersion, args);

                if (args.Succeeded == false)
                {
                    //this should never be hit, as it is a legacy of the volatile flag
                    return(false);
                }

                if (isSerializationInfoSupported == true)
                {
                    if (dataVersion > this.CurrentVersion)
                    {
                        int readDataLength      = (int)(args.Reader.BaseStream.Position - args.Header.DataPosition);
                        int unhandledDataLength = args.Header.DataLength - readDataLength;

                        args.SerializationInfo.UnhandledData = args.Reader.ReadBytes(unhandledDataLength);
                    }
                }
            }

            return(true);
        }