Пример #1
0
        internal override void PassPreamble()
        {
            {
                // we can not create the XmlReader in the formatter class constructor since this reader constructor starts to read the stream.
                // We need to create a new reader for each serialization.
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreComments = true;
                settings.IgnoreProcessingInstructions = true;
                settings.IgnoreWhitespace             = true;
                this.xmlReader = XmlReader.Create(this.stream, settings);
            }

            this.xmlReader.Read();
            this.xmlReader.Read();
            this.xmlReader.Read();
            this.xmlReader.Read();
            if (this.xmlReader.Value == "2.0")
            {
                this.Version = StreamFormatVersion.Version2_0;
            }
            else
            if (this.xmlReader.Value == "3.0")
            {
                this.Version = StreamFormatVersion.Version3_0;
            }
            else
            {
                throw new Exception(ErrorMessages.GetText(7));                        // "Unknown file version."
            }
            this.xmlReader.Read();
        }
Пример #2
0
        /// <summary>
        /// Returns a TypeConverterContainer&lt;T&gt;.
        /// </summary>
        public ITypeContainer CreateNewContainer(object ContainedObject)
        {
            if (ContainedObject == null)
            {
                return(null);
            }

            Type           type = ContainedObject.GetType();
            ITypeContainer obj  = null;

            TypeConverter tc = GetTypeConverterByCache(type);

            try
            {
                if (tc.CanConvertTo(TypeString) && tc.CanConvertFrom(TypeString))
                {
                    obj = CreateATypeConverterContainerGeneric(type, TypeString, tc.ConvertTo(null, Tools.EnUSCulture, ContainedObject, TypeString));
                    if (obj != null)
                    {
                        var o2 = obj as _CLRTypeConverterContainerGeneric <string>;
                        if (o2.Serialized == null || o2.Serialized == type.FullName)
                        {
                            Log.WriteLine(string.Format(
                                              ErrorMessages.GetText(15)                  //"The type '{0}' uses {1} as TypeConverter, but it does not convert to string correctly. Please investigate or contact the type's author."
                                              , type.FullName, tc.GetType().FullName));
                            return(null);
                        }
                    }
                }
                else
                if (tc.CanConvertTo(TypeByteArray) && tc.CanConvertFrom(TypeByteArray))
                {
                    obj = CreateATypeConverterContainerGeneric(type, TypeByteArray, tc.ConvertTo(null, Tools.EnUSCulture, ContainedObject, TypeByteArray));
                }
            }
            catch (Exception e)
            {
                Log.WriteLine(e.Message);
            }
            if (obj == null)
            {
                Log.WriteLine(string.Format(
                                  ErrorMessages.GetText(16)      //"The type '{0}' uses {1} as TypeConverter, but its transcoding type is unknown. Please investigate or contact the type's author."
                                  , type.FullName, tc.GetType().FullName));
            }

            return(obj);
        }
Пример #3
0
        // ------------------------------

        internal override void PassPreamble()
        {
            // Passes the UTF8 prefix "":
            if (!stream.CanSeek || (stream.CanSeek && stream.Position == 0))
            {
                byte[] prefix = new byte[3];
                int    n      = this.stream.Read(prefix, 0, 3);
                if (n != 3 || prefix[0] != 'ï' || prefix[1] != '»' || prefix[2] != '¿')
                {
                    throw new FormatException("stream");
                }
            }

            {
                // We have to build a new JSONReader on each deserialization because it just do not manage multiple json data in one stream correctly.

                XmlDictionaryReaderQuotas quotas = XmlDictionaryReaderQuotas.Max;
                this._JSONReader = JsonReaderWriterFactory.CreateJsonReader(stream,
#if !SILVERLIGHT
                                                                            Encoding.UTF8,
#endif
                                                                            quotas
#if !SILVERLIGHT
                                                                            , null
#endif
                                                                            );
            }

            this._JSONReader.Read();
            this._JSONReader.Read();
            this._JSONReader.Read();
            if (this._JSONReader.Value == "2.0")
            {
                this.Version = StreamFormatVersion.Version2_0;
            }
            else
            if (this._JSONReader.Value == "3.0")
            {
                this.Version = StreamFormatVersion.Version3_0;
            }
            else
            {
                throw new Exception(ErrorMessages.GetText(7));                        // "Unknown file version."
            }
            this._JSONReader.Read();
        }
Пример #4
0
 static byte[] SerializeObject(object o)
 {
     using (MemoryStream stream = new MemoryStream())
     {
         var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
         try
         {
             formatter.Serialize(stream, o);
         }
         catch (Exception e)
         {
             throw new Exception(string.Format(
                                     ErrorMessages.GetText(8),    //"Type '{0}' (or one of its sub-data) is not serializable by BCL's BinaryFormatter. (suggestion: try remove attribute [Serializable], or add an exploitable constructor).",
                                     o.GetType().GetName()), e);
         }
         return(stream.ToArray());
     }
 }
Пример #5
0
        // -------------------------------------------------------------------------------

        internal static SerializationFormatter ChooseDefaultFormatter(Parameters parameters)
        {
            switch (parameters.SerializerFormatter)
            {
            case SerializerFormatters.BinarySerializationFormatter:
                return(new BinarySerializationFormatter(parameters));

#if !JSON_DISABLED
            case SerializerFormatters.JSONSerializationFormatter:
                return(new JSONSerializationFormatter(parameters));
#endif
            case SerializerFormatters.XmlSerializationFormatter:
                return(new XmlSerializationFormatter(parameters));

            default:
                throw new ArgumentException(ErrorMessages.GetText(2));                         // "Unknown CustomFormatter");
            }
        }
        internal override void PassPreamble()
        {
            string p = this.binaryReader.ReadString();

            if (p == BinarySerializationFormatter.DocumentPreambleVersion2)
            {
                this.Version = StreamFormatVersion.Version2_0;
            }
            else
            if (p == BinarySerializationFormatter.DocumentPreambleVersion3)
            {
                this.Version = StreamFormatVersion.Version3_0;
            }
            else
            {
                throw new Exception(
                          ErrorMessages.GetText(7));                      //"Unknown file version");
            }
        }
        // ------------------------------

        /// <summary>
        /// For each parameter, find its index in the SelectedFields, in the order of this.ParameterFields.
        /// </summary>
        /// <param name="SelectedFields">Concatenated selected public and private fields of a particular TypeManager.</param>
        /// <param name="CancelOnErrors">If true, an error will return null. If false, an error will throw an exception.</param>
        /// <returns>int[this.ParameterFields.Length]</returns>
        internal int[] GetParameterIndexes(FieldInfo[] SelectedFields, bool CancelOnErrors)
        {
            int[] indexes = new int[this.ParameterFields.Length];
            for (int i = 0; i < this.ParameterFields.Length; i++)
            {
                var fi = ParameterFields[i];

                indexes[i] = Array.IndexOf(SelectedFields, fi);
                if (indexes[i] < 0)
                {
                    if (CancelOnErrors)
                    {
                        return(null);
                    }
                    string msg = string.Format(
                        ErrorMessages.GetText(14)                        // "Type \"{0}\" can not be constructed because this parameter's type has been disallowed by a filter: Parameter's name=\"{1}\", Corresponding field's name=\"{2}\", Type=\"{3}\".\n\tSuggestion: use a filter to disallow the main type, or to allow the parameter's type."
                        , this.constructorInfo.DeclaringType.FullName, this.constructorInfo.GetParameters()[i].Name, fi.Name, fi.FieldType.FullName);
                    Log.WriteLine(msg);
                    throw new Exception(msg);
                }
            }
            return(indexes);
        }
Пример #8
0
 internal NoMethodsException(Type t)
     : base(string.Format(
                ErrorMessages.GetText(13)         // "Type {0} has no Add() method nor [Insert() method and Count get method], we can not set its items."
                , t.FullName))
 {
 }
Пример #9
0
        // TODO: write a generic method for each Primitive type, in order to avoid boxing to object.
        internal static Object TranscodeStringToPrimitiveObject(string s, L3TypeManager typeManager)
        {
            TypeCode tc = (TypeCode)typeManager.TypeIndex;

#if DEBUG
            if ((int)tc < (int)TypeCode.Boolean)
            {
                throw new ArgumentException(ErrorMessages.GetText(9));                //"data is not a Primitive type");
            }
#endif
            switch (tc)
            {
            case TypeCode.Boolean:
                return(Boolean.Parse(s));

            case TypeCode.Byte:
                return(Byte.Parse(s));

            case TypeCode.Char:
#if SILVERLIGHT || PORTABLE
                return(s[0]);
#else
                return(Char.Parse(s));
#endif
            case TypeCode.DateTime:
                return(Tools.DateTimeFromTicksAndKind(ulong.Parse(s)));

            case TypeCode.Decimal:
                return(Decimal.Parse(s, Tools.EnUSCulture));

            case TypeCode.Double:
                return(Double.Parse(s, Tools.EnUSCulture));

            case TypeCode.Int16:
                return(Int16.Parse(s));

            case TypeCode.Int32:
                return(Int32.Parse(s));

            case TypeCode.Int64:
                return(Int64.Parse(s));

            case TypeCode.SByte:
                return(SByte.Parse(s));

            case TypeCode.Single:
                return(Single.Parse(s, Tools.EnUSCulture));

            case TypeCode.String:
                return(s);

            case TypeCode.UInt16:
                return(UInt16.Parse(s));

            case TypeCode.UInt32:
                return(UInt32.Parse(s));

            case TypeCode.UInt64:
                return(UInt64.Parse(s));

            default:
                throw new Exception();
            }
        }
Пример #10
0
        // TODO: write a generic method for each Primitive type, in order to avoid boxing to object.
        internal Object ReadPrimitiveObjectFromBinaryStream(BinaryReader2 binaryReader, L3TypeManager typeManager, bool CompressIntsAs7Bits)
        {
            TypeCode tc = (TypeCode)typeManager.TypeIndex;

#if DEBUG
            if ((int)tc < (int)TypeCode.Boolean)
            {
                throw new ArgumentException(ErrorMessages.GetText(9));                //"data is not a Primitive type");
            }
#endif
            switch (tc)
            {
            case TypeCode.Boolean:
                return(binaryReader.ReadBoolean());

            case TypeCode.Byte:
                return(binaryReader.ReadByte());

            case TypeCode.Char:
                return(binaryReader.ReadChar());

            case TypeCode.DateTime:
                return(Tools.DateTimeFromTicksAndKind(binaryReader.ReadUInt64()));

            case TypeCode.Decimal:
                return(binaryReader.ReadDecimal());

            case TypeCode.Double:
                return(binaryReader.ReadDouble());

            case TypeCode.SByte:
                return(binaryReader.ReadSByte());

            case TypeCode.Single:
                return(binaryReader.ReadSingle());

            case TypeCode.String:
                return(binaryReader.ReadString());

            case TypeCode.Int16:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.ReadSpecial7BitEncodedShort());
                }
                else
                {
                    return(binaryReader.ReadInt16());
                }

            case TypeCode.Int32:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.ReadSpecial7BitEncodedInt());
                }
                else
                {
                    return(binaryReader.ReadInt32());
                }

            case TypeCode.Int64:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.ReadSpecial7BitEncodedLong());
                }
                else
                {
                    return(binaryReader.ReadInt64());
                }

            case TypeCode.UInt16:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.Read7BitEncodedUShort());
                }
                else
                {
                    return(binaryReader.ReadUInt16());
                }

            case TypeCode.UInt32:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.Read7BitEncodedUInt());
                }
                else
                {
                    return(binaryReader.ReadUInt32());
                }

            case TypeCode.UInt64:
                if (CompressIntsAs7Bits)
                {
                    return(binaryReader.Read7BitEncodedULong());
                }
                else
                {
                    return(binaryReader.ReadUInt64());
                }

            default:
#if DEBUG
                throw new Exception();
#else
                return(null);
#endif
            }
        }
Пример #11
0
        void AddAComplexObject_NoInstanceTest(
            ref ChannelInfos channelInfos, object obj,
#if DEBUG
            string NameToWrite,
#endif
            L3TypeManager typeManager, bool AtRoot, bool WriteType)
        {
            IDictionary AsIDictionary = null;

            bool AddSectionMark = AtRoot && this.parameters.TheStreamingMode == StreamingModes.MultiplexStream;

            if (AddSectionMark)
            {
                this.ChannelEnterChannelSection(ref channelInfos);
            }

            long?NumberOfElements = null;

            if (typeManager.l2TypeManager.L1TypeManager.type.IsArray)
            {
                Array array = obj as Array;
                if (array.Rank != 1)
                {
                    throw new Exception(ErrorMessages.GetText(1));                     // "This version of UniversalSerializer can not manage multi-dimentionnal arrays."
                }
                // TODO: create a Container for complex arrays (not only multidimensional, see Array.GetLowerBound() too).
                NumberOfElements =
#if SILVERLIGHT || PORTABLE || WINDOWS_UWP
                    array.Length;
#else
                    array.GetLongLength(0);
#endif
            }
            else
            if (typeManager.l2TypeManager.L1TypeManager.IsAnObjectIEnumerable)
            {
                NumberOfElements = (obj as IEnumerable).GetCount();
            }
            else
            if (typeManager.l2TypeManager.L1TypeManager.IsADictionary)
            {
                AsIDictionary = obj as IDictionary;
                if (AsIDictionary != null)
                {
                    NumberOfElements = AsIDictionary.Count;
                }
                else
                {
                    AsIDictionary = Tools.GenericIDictionaryBoxer <int, int> .CreateFromGenericIDictionary(obj, typeManager);

                    if (AsIDictionary != null)
                    {
                        NumberOfElements = AsIDictionary.Count;
                    }
                    else
                    {
                        throw new Exception();                         // error.
                    }
                }
            }

            this.ChannelEnterSubBranch(
                ref channelInfos,
                NumberOfElements,
#if DEBUG
                NameToWrite,
#endif
                WriteType ? (int?)typeManager.TypeIndex : null,
                null
#if DEBUG
                , typeManager.l2TypeManager.L1TypeManager.type
#endif
                , typeManager.l2TypeManager.L1TypeManager.IsStructure
                );
            {
                #region serialize the fields.
                if (typeManager.SelectedFieldTypeManagers != null)
                {
                    for (int ifi = 0; ifi < typeManager.SelectedFieldTypeManagers.Length; ifi++)
                    {
                        object fieldValue =
                            typeManager.l2TypeManager.SelectedFieldGetters[ifi](obj);

                        Type FieldType = typeManager.l2TypeManager.SelectedFields[ifi].FieldType;

                        Type t = fieldValue != null?fieldValue.GetType() : FieldType;

                        L3TypeManager _tm;
                        bool          serializable = FieldType == t ? true : l3typeManagerCollection.l2TypeManagerCollection.CanThisTypeBeSerialized(t);
                        if (!serializable)
                        {
                            fieldValue = null;
                        }

                        if (FieldType != t && serializable)
                        {
#if DEBUG
                            if (!t.Is(FieldType))                             // TODO: optimize this test and let it even in relase compilation.
                            {
                                if (!FieldType.Is(typeof(Nullable <>)))
                                {
                                    throw new Exception();
                                }
                            }
#endif
                            _tm = this.l3typeManagerCollection.GetTypeManager(t, this, true, false);
                        }
                        else
                        {
                            _tm = typeManager.SelectedFieldTypeManagers[ifi];
                            if (_tm == null)
                            {
                                _tm =
                                    typeManager.SelectedFieldTypeManagers[ifi] =                                      // updates the TypeManager.
                                                                                 this.l3typeManagerCollection.GetTypeManager(FieldType, this, true, false);
                                typeManager.l2TypeManager.SelectedFieldTypeManagers[ifi] = _tm.l2TypeManager;
                            }
                        }
                        bool WriteTypeNumber = serializable && FieldType != t;

                        this.AddAnObject(ref channelInfos, fieldValue,
                                         null,
                                         _tm.TypeIndex,
                                         _tm, false,
                                         WriteTypeNumber
                                         );
                    }
                }
                #endregion serialize the fields.

                #region serialize the properties.
                if (typeManager.SelectedPropertyTypeManagers != null)
                {
                    // serialize the properties.
                    for (int ipi = 0; ipi < typeManager.SelectedPropertyTypeManagers.Length; ipi++)
                    {
                        var  pi           = typeManager.l2TypeManager.SelectedProperties[ipi];
                        Type propertyType = pi.PropertyType;

                        object propertyValue =
                            typeManager.l2TypeManager.SelectedPropertyGetters[ipi](obj);
                        Type t = propertyValue != null?propertyValue.GetType() : propertyType;

                        L3TypeManager _tm;

                        bool serializable = propertyType == t ? true : l3typeManagerCollection.l2TypeManagerCollection.CanThisTypeBeSerialized(t);
                        if (!serializable)
                        {
                            propertyValue = null;
                        }

                        if (propertyType != t && serializable)
                        {
#if DEBUG
                            if (!t.Is(propertyType))                             // TODO: optimize this test and let it even in relase compilation.
                            {
                                if (!propertyType.Is(typeof(Nullable <>)))
                                {
                                    throw new Exception();
                                }
                            }
#endif
                            _tm = this.l3typeManagerCollection.GetTypeManager(t, this, true, false);
                        }
                        else
                        {
                            _tm = typeManager.SelectedPropertyTypeManagers[ipi];
                            if (_tm == null)
                            {
                                _tm =
                                    typeManager.SelectedPropertyTypeManagers[ipi] =                                      // updates the TypeManager.
                                                                                    this.l3typeManagerCollection.GetTypeManager(propertyType, this, true, false);
                                typeManager.l2TypeManager.SelectedPropertyTypeManagers[ipi] = _tm.l2TypeManager;
                            }
                        }
                        bool WriteTypeNumber = serializable && propertyType != t;

                        this.AddAnObject(ref channelInfos, propertyValue,
                                         null,
                                         _tm.TypeIndex,
                                         _tm, false,
                                         WriteTypeNumber
                                         );
                    }
                }
                #endregion serialize the properties.

                // serialize an inner dictionary:
                if (typeManager.l2TypeManager.L1TypeManager.IsADictionary)
                {
                    this.AddADictionary(
                        ref channelInfos, AsIDictionary, typeManager
                        );
                }

                // serialize an inner collection:
                if (typeManager.l2TypeManager.L1TypeManager.IsAnObjectIEnumerable)
                {
                    this.AddACollection(ref channelInfos, obj as IEnumerable, typeManager
                                        );
                }
            }
            this.ChannelExitSubBranch(ref channelInfos);
            if (AddSectionMark)
            {
                this.ChannelExitChannelSection(ref channelInfos);
            }
        }
Пример #12
0
        // ---------------------------------------------

        void AddACollection(
            ref ChannelInfos channelInfos,
            IEnumerable iEnumerable,
            L3TypeManager collectionTypeManager,
            string NameToWrite = null)
        {
            if (collectionTypeManager.l2TypeManager.L1TypeManager.type.IsArray)
            {
                Array array = iEnumerable as Array;
                if (array.Rank != 1)
                {
                    throw new Exception(ErrorMessages.GetText(1));                     // "This version of UniversalSerializer can not manage multi-dimentionnal arrays."
                }
                // TODO: create a Container for complex arrays (multidimensional and not-0-based, see Array.GetLowerBound()).
            }


            Type          collectionType = iEnumerable.GetType();
            L3TypeManager typeManager    =
                collectionTypeManager.l2TypeManager.L1TypeManager.type == collectionType ?
                collectionTypeManager
                                : this.l3typeManagerCollection.GetTypeManager(collectionType, this, true, false);
            int collectionTypeNumber =
                typeManager.TypeIndex;

            if (iEnumerable.IsEmpty())
            {
                // Optimisation: we only write an empty object as a collection.
                this.ChannelAddNull(
                    ref channelInfos
                    );

                return;
            }

            Type CommonItemType =             // can be null.
                                  typeManager.CollectionItemsTypeManager != null ?
                                  typeManager.CollectionItemsTypeManager.l2TypeManager.L1TypeManager.type
                                : null;

            this.ChannelEnterCollection(
                ref channelInfos
#if DEBUG
                , NameToWrite
#endif
#if DEBUG
                , collectionType
#endif
                );
            var CommonItemTM         = typeManager.CollectionItemsTypeManager;
            int?CommonItemTypeNumber =
                CommonItemTM != null ?
                CommonItemTM.TypeIndex
                                : (int?)null;


            if (CommonItemTM == null || CommonItemTM.l2TypeManager.IsClass || TypeTools.TypeEx.IsInterface(CommonItemTM.l2TypeManager.L1TypeManager.type))
            {
                // For item types that are not-sealed classes or interfaces:

                // item of foreach can not be referenced. Therefore we enumerate manually:
                var enumerator = iEnumerable.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    var item = enumerator.Current;
                    if (item != null)
                    {
                        Type          itemType = item.GetType();
                        L3TypeManager itemTm   =
                            itemType != CommonItemType?
                            this.l3typeManagerCollection.GetTypeManager(item.GetType(), this, true, false)                             // Items can have different types, even if all items inherit the same type.
                                : CommonItemTM;

                        int  ItemTypeNumber  = itemTm.TypeIndex;
                        bool WriteTypeNumber = (ItemTypeNumber != CommonItemTypeNumber);                         // We write the type index only if it is different from the common type index.

                        this.AddAnObject(ref channelInfos, item, null, ItemTypeNumber, itemTm, false, WriteTypeNumber);
                    }
                    else
                    {
                        this.ChannelAddNull(
                            ref channelInfos
                            );
                    }
                }
            }
            else             // structures or sealed classes can not inherit therefore can be serialized faster (because we don't have to specify the item type):
            {
#if !DEBUG && !WINDOWS_UWP
                if (CommonItemTypeNumber != null)
                {
                    // Using a generic IEnumerable is a bit quicker (11 % on .NET 4.5).
                    var mi2 = gfAddAllStructs.MakeGenericMethod(CommonItemType);
                    mi2.Invoke(this, new object[] {
                        iEnumerable, channelInfos, CommonItemTypeNumber.Value, CommonItemTM
                    });
                }
                else
#endif
                {
                    // The normal algorithm makes debugging easier.
                    // item of foreach can not be referenced. Therefore we enumerate manually:
                    var enumerator = iEnumerable.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        var item = enumerator.Current;
                        this.AddAnObject(ref channelInfos, item, null, CommonItemTypeNumber.Value, CommonItemTM, false, false);
                    }
                }
            }
            this.ChannelExitCollection(ref channelInfos);
        }
Пример #13
0
 /// <summary>
 /// Can not cast deserialized type.
 /// </summary>
 /// <param name="DeserializedType"></param>
 /// <param name="WantedType"></param>
 public TypeMismatchException(Type DeserializedType, Type WantedType)
     : base(string.Format(
                ErrorMessages.GetText(10),// "Can not cast deserialized type \"{0}\" to wanted type \"{1}\".",
                DeserializedType.FullName, WantedType.FullName))
 {
 }
Пример #14
0
        internal object ConstructAndSetMembers <T>(
            L3TypeManager l3TypeManager,
            bool AddToTheInstances, long?NumberOfElements)
        {
#if false//DEBUG
            if (l3TypeManager.l2TypeManager.L1TypeManager.Name == "CircularInstancesInAListAndParametricConstructor")
            {
                Debugger.Break();
            }
#endif

            L2GenericTypeManager <T> typeManager = l3TypeManager.l2TypeManager as L2GenericTypeManager <T>;

            T   obj;
            var gtd = typeManager.L1TypeManager;

            if (gtd.type.IsArray)
            {
                object array = Array.CreateInstance(typeManager.CollectionItemsTypeManager.L1TypeManager.type,
#if SILVERLIGHT || PORTABLE || WINDOWS_UWP
                                                    checked ((int)NumberOfElements.Value)
#else
                                                    NumberOfElements.Value
#endif
                                                    );
                if (AddToTheInstances)
                {
                    this.instancesChannel.AddInstance(array); // Adds the instance before deserializing inner data. Because of possible circular types.
                }
                return(array);
            }
            else
            if (typeManager.DefaultConstructor != null)
            {
                #region Build from a default (no-param) constructor

                // creates an instance (or a value if it is a structure):
#if SILVERLIGHT
                if (typeManager.L1TypeManager.type.IsEnum)
                {
                    obj = default(T);
                }
                else
#endif
                obj = (T)typeManager.DefaultConstructor();

                if (AddToTheInstances)
                {
                    this.instancesChannel.AddInstance(obj);     // Add the instance before deserializing inner data.
                }
                if (typeManager.SelectedFields != null)
                {
                    typeManager.SetFieldValues(ref obj,
                                               GetFieldValues(l3TypeManager));
                }

                if (typeManager.SelectedProperties != null)
                {
                    typeManager.SetPropertyValues(ref obj,
                                                  GetPropertyValues(l3TypeManager));
                }

                #endregion Build from a default (no-param) constructor
            }
            else
            if (typeManager.parametricConstructorDescriptor != null)
            #region Build from a parametric constructor
            {
                int instanceIndex = 0;
                if (AddToTheInstances)
                {
                    instanceIndex = this.instancesChannel.ReserveSpaceForInstance();         // reserves site.
                }


                object[] fieldValues =
                    (typeManager.SelectedFields != null) ?
                    GetFieldValues(l3TypeManager)
                                : new object[0];
                for (int i = 0; i < fieldValues.Length; i++)
                {
                    var nr = fieldValues[i] as InstancesChannel.InstanceNotReadyAndListOfNeeds;
                    if (nr != null)
                    {
                        var iCopy = i;         // tells C# to not use a closure for the following lambda.
                        nr.Setters.Add((o) => fieldValues[iCopy] = o);
                    }
                }

                object[] propValues =
                    (typeManager.SelectedProperties != null) ?
                    GetPropertyValues(l3TypeManager)
                                : new object[0];
                for (int i = 0; i < propValues.Length; i++)
                {
                    var nr = propValues[i] as InstancesChannel.InstanceNotReadyAndListOfNeeds;
                    if (nr != null)
                    {
                        var iCopy = i;         // tells C# to not use a closure for the following lambda.
                        nr.Setters.Add((o) => propValues[iCopy] = o);
                    }
                }

#if false // Future use, when the parameter indexes will be on both fields and properties.
                object[] fieldsAndProps = new object[fieldValues.Length + propValues.Length];
                fieldValues.CopyTo(fieldsAndProps, 0);
                propValues.CopyTo(fieldsAndProps, fieldValues.Length);
#endif
                // TODO: check if the deserialized ParametricConstructorDescriptor is the same as the TypeManager's one.

                int      nbPars     = typeManager.parametricConstructorDescriptor.ParameterFields.Length;
                object[] parameters = new object[nbPars];
                if (nbPars > 0 && typeManager.ParametricConstructorFieldParameterIndexes == null)
                {
                    throw new Exception(ErrorMessages.GetText(19));         // "Type {0} can not be deserialized because of 1) an error in its Container and 2) a refused private field."
                }
                for (int ipars = 0; ipars < nbPars; ipars++)
                {
                    parameters[ipars] = fieldValues[typeManager.ParametricConstructorFieldParameterIndexes[ipars]];
                }

                // I do not use a Linq Expression compiled constructor because it takes a lot of time to be produced.
                // A reflection constructor call is slower but it has no creation time.
                try
                {
                    obj = (T)typeManager.parametricConstructorDescriptor.constructorInfo.Invoke(parameters);
                }
                catch (Exception e)
                {
                    string msg = string.Format(
                        ErrorMessages.GetText(11),        //"Construction (instanciation) of type \"{0}\" caused an error: {1}."
                        typeof(T).FullName, e.Message);
                    for (int ip = 0; ip < parameters.Length; ip++)
                    {
                        var p = parameters[ip];
                        if (p != null)
                        {
                            msg += string.Format("\n\tParameter #{0} is type \"{1}\".", ip.ToString(), p.GetType().FullName);
                        }
                    }
                    Log.WriteLine(msg);
                    throw new Exception(msg, e);
                }

                if (AddToTheInstances)
                {
                    this.instancesChannel.SetInstance(instanceIndex, obj);
                }

                if (fieldValues.Length > 0)
                {
                    typeManager.SetFieldValues(ref obj, fieldValues);
                }

                if (propValues.Length > 0)
                {
                    typeManager.SetPropertyValues(ref obj, propValues);
                }
            }
            #endregion Build from a parametric constructor
            else
            {
                string msg = string.Format(
                    ErrorMessages.GetText(12)        //"No exploitable constructor for type {0}"
                    , gtd.type.FullName);
                Log.WriteLine(msg);

                throw new Exception(msg);         // No valid constructor.
            }

            return(obj);
        }
Пример #15
0
        // --------------------------------------------------

        Object DeserializeDictionary(
            object dictionary,
            long NumberOfElements,
            L3TypeManager WantedType,
            Element e
            )
        {
#if DEBUG
            if (dictionary == null || WantedType == null)
            {
                Debugger.Break();
            }
#endif
            IDictionary dict = Tools.GenericIDictionaryBoxer <int, int> .CreateFromGenericIDictionary(dictionary, WantedType);

            L3TypeManager keysType   = WantedType.DictionaryKeysTypeManager;   // can be null, for not-generic dictionaries.
            L3TypeManager ValuesType = WantedType.DictionaryValuesTypeManager; // can be null, for not-generic dictionaries.

            for (int i = 0; i < NumberOfElements; i++)
            {
                var key   = this.LookForObjectAndManagesChannels(keysType, null, null, false);
                var Value = this.LookForObjectAndManagesChannels(ValuesType, null, null, false);

                var keyAsNotReady   = key as InstancesChannel.InstanceNotReadyAndListOfNeeds;
                var valueAsNotReady = Value as InstancesChannel.InstanceNotReadyAndListOfNeeds;

                if (keyAsNotReady == null && valueAsNotReady == null)
                {
                    dict.Add(key, Value);
                }
                else
                {
                    var dictCopy = dict; // tells C# to not use a closure for the following lambdas.

                    if (keyAsNotReady != null && valueAsNotReady != null)
                    {
                        // TODO: implement (how?)

                        string typeMsg = "[ unknown ]";
                        if (ValuesType != null && keysType != null)
                        {
                            typeMsg =
                                "[ " + Tools.GetName(keysType.l2TypeManager.L1TypeManager.type) + " or " +
                                Tools.GetName(ValuesType.l2TypeManager.L1TypeManager.type) + " ]";
                        }
                        else
                        if (WantedType != null)
                        {
                            if (WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments != null)
                            {
                                if (WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments[0] == WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments[1])
                                {
                                    typeMsg = Tools.GetName(WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments[0]);
                                }
                                else
                                {
                                    typeMsg =
                                        "[ " +
                                        Tools.GetName(WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments[0])
                                        + " or " +
                                        Tools.GetName(WantedType.l2TypeManager.L1TypeManager.AsGenericIDictionaryGenericArguments[1])
                                        + " ]";
                                }
                            }
                        }
                        throw new NotSupportedException(
                                  string.Format(ErrorMessages.GetText(22), // "Type {0} has a circular type in its constructor parameters in a form that is not supported."
                                                typeMsg));
                    }
                    else
                    if (keyAsNotReady != null)
                    {
                        var ValueCopy = Value;     // tells C# to not use a closure for the following lambda.
                        keyAsNotReady.Setters.Add((o) => dictCopy.Add(o, ValueCopy));
                    }
                    else
                    {
                        var keyCopy = key;     // tells C# to not use a closure for the following lambda.
                        valueAsNotReady.Setters.Add((o) => dictCopy.Add(keyCopy, o));
                    }
                }
            }
            if (e.NeedsAnEndElement)
            {
                this.PassClosingTag(ElementTypes.Dictionary);
            }

            return(dictionary);
        }
Пример #16
0
        // --------------------------------------------------

        Object DeserializeCollection(
            object collection,
            long NumberOfElements,
            L3TypeManager WantedType,
            Element e
            )
        {
#if false//DEBUG
            //if (collection.GetType().Name == "RelationsDHéritage")
            if (WantedType.l2TypeManager.L1TypeManager.Name == "List<DéclarationStructurée>")
            {
                Debugger.Break();
            }
#endif

#if DEBUG
            if (collection == null || WantedType == null)
            {
                Debugger.Break();
            }
#endif
            IList list             = collection as IList;
            bool  listIsNotIndexed = list == null;
            if (listIsNotIndexed)
            {
                Type ItemType;
                list = Tools.GetIListBoxer(collection as IEnumerable, out ItemType);
            }

            Array array     = collection as Array;
            bool  is1DArray = array != null && array.Rank == 1;
#if DEBUG
            if (array != null && array.Rank != 1)
            {
                throw new Exception(
                          ErrorMessages.GetText(1));//"This version of UniversalSerializer can not manage multi-dimentionnal arrays."
            }
#endif
            L3TypeManager itemsType = WantedType.CollectionItemsTypeManager;// Manager.Value;
#if false
            if (itemsType == null)
            {
                Debugger.Break();
            }
#endif

            for (int i = 0; i < NumberOfElements; i++)
            {
                var item = this.LookForObjectAndManagesChannels(
                    itemsType
                    , null
                    , null
                    , false
                    );

                var notReady = item as InstancesChannel.InstanceNotReadyAndListOfNeeds;

                if (is1DArray)
                {
                    if (notReady == null)
                    {
                        list[i] = item;
                    }
                    else
                    {
                        var iCopy    = i;    // tells C# to not use a closure for the following lambda.
                        var listCopy = list; // tells C# to not use a closure for the following lambda.
                        notReady.Setters.Add((o) => listCopy[iCopy] = o);
                    }
                }
                else
                if (notReady == null)
                {
#if NET3_5
                    // .NET 3.5 can not do IList.Add(null) on a List<T>. This is a workaround.
                    if (item == null && WantedType != null && WantedType.CollectionItemsTypeManager.l2TypeManager.L1TypeManager.IsNullable)
                    {
                        var m = WantedType.ItemAdder.Value;
                        if (m != null)
                        {
                            m(list, null);
                        }
                        else
                        {
                            list.Add(item);
                        }
                    }
                    else
                    {
                        list.Add(item);
                    }
#else
                    list.Add(item);
#endif
                }
                else
                {
                    if (listIsNotIndexed)
                    {
                        throw new NotSupportedException(
                                  string.Format(ErrorMessages.GetText(22), // "Type {0} has a circular type in its constructor parameters in a form that is not supported."
                                                Tools.GetName(itemsType.l2TypeManager.L1TypeManager.type)));
                    }
                    list.Add(itemsType.l2TypeManager.DefaultValue); // reserve space, to preserve right indexes.
                    var listCopy = list;                            // tells C# to not use a closure for the following lambda.
                    var iCopy    = i;                               // tells C# to not use a closure for the following lambda.
                    notReady.Setters.Add((o) => listCopy[iCopy] = o);
                }
            }
            if (e.NeedsAnEndElement)
            {
                this.PassClosingTag(ElementTypes.Collection);
            }

            return(collection);
        }