コード例 #1
0
 /// <summary>
 /// Writes an info xml file in the storer.
 /// </summary>
 /// <param name="storer"> The storer. </param>
 /// <param name="path"> The path to the file. </param>
 /// <param name="className"> Name of the class. </param>
 /// <param name="values"> Values. </param>
 private void WriteInfo(IWriteOnlyDataStorer storer, string path, string className, IDictionary <string, string> values)
 {
     storer.Add(
         StringUtils.Combine(path, InfoFileName),
         this.SerializeInfo(className, values)
         );
 }
コード例 #2
0
        /// <summary>
        /// Writes an object (or graph of objects with the given root) in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        private void Write(object graph, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            if (graph == null)
            {
                this.WriteNull(path, storer);
                return;
            }

            Type graphType = graph.GetType();

            if (this.TryWriteCollection(graph, graphType, path, storer, references))
            {
                return;
            }

            if (this.TryWriteDictionary(graph, graphType, path, storer, references))
            {
                return;
            }

            if (this.TryWriteMDArray(graph, graphType, path, storer, references))
            {
                return;
            }

            if (this.TryWriteFormattable(graph, graphType, path, storer, references))
            {
                return;
            }

            throw new UnsupportedTypeException(graphType);
        }
コード例 #3
0
        /// <summary>
        /// Serializes an object, or graph of objects with the given root to the array of bytes. </summary>
        /// <param name="graph">
        /// The object, or root of the object graph, to serialize.
        /// All child objects of this root object are automatically serialized.
        /// </param>
        /// <returns> Array of bytes that associated with the graph if serialization has been finished successfully, otherwise null. </returns>
        /// <exception cref="Localization.ValueNullException">
        /// The exception that is thrown when graph is null.
        /// </exception>
        public byte[] Serialize <T>(T graph)
        {
            if (object.ReferenceEquals(graph, null))
            {
                Validation.NotNull("Graph", graph as object);
                return(null);
            }

            while (Interlocked.CompareExchange(ref this.formatterIsLoading, 1, 1) == 1)
            {
                // Waits while assemblies have been loaded
                Thread.Sleep(1);
            }

            try
            {
                string graphName = graph.ToString();

                Type type = typeof(T);

                if (this.IsPrimitive(type))
                {
                    // Tries serialize the object/graph of the objects (as primitive type)

                    Func <object, string> primitiveConverter = this.GetPrimitiveConverterToString(typeof(T));
                    return(primitiveConverter(graph).GetBytes());
                }
                else
                {
                    // Tries serialize the object/graph of the objects (as non-primitive type)

                    Dictionary <object, string> references = new Dictionary <object, string>(100);
                    IWriteOnlyDataStorer        storer     = this.CreateWriteOnlyDataStorer();

                    this.Write(graph, "", storer, references);
                    return(storer.Close());
                }
            }
            catch
            {
                return(null);
            }
        }
コード例 #4
0
        /// <summary>
        /// Tries write reference to object in information file and gets information about of continuation of writing.
        /// </summary>
        /// <param name="storer"> The storer. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="references"> Dictionary that contains references to objects.</param>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="className"> Name of the class. </param>
        /// <returns> Returns true if writing should be continued (for first object), otherwise false (if object with same reference has been found). </returns>
        /// <remarks> The method adds creates an information file if object has been written before. </remarks>
        private bool TryWriteValue(IWriteOnlyDataStorer storer, string path, IDictionary <object, string> references, object graph, string className)
        {
            if (graph.GetType().IsClass)
            {
                string reference;
                if (references.TryGetValue(graph, out reference))
                {
                    IDictionary <string, string> values = new Dictionary <string, string>()
                    {
                        { ReferenceToString, reference }
                    };

                    this.WriteInfo(storer, path, className, values);
                    return(false);
                }
                else
                {
                    references.Add(graph, path);
                    return(true);
                }
            }

            return(true);
        }
コード例 #5
0
 /// <summary>
 /// Writes a null xml file in the storer.
 /// </summary>
 /// <param name="path"> The path to the file. </param>
 /// <param name="storer"> The storer. </param>
 private void WriteNull(string path, IWriteOnlyDataStorer storer)
 {
     this.WriteInfo(storer, path, NullIdentifier, new Dictionary <string, string>());
 }
コード例 #6
0
        /// <summary>
        /// Tries write a formattable object in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="type"> Type of the object. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> True if formattable objecthas been written (or is exist), otherwise false. </returns>
        private bool TryWriteFormattable(object graph, Type type, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            // Gets a formattable type for the specified type

            FormattableType formattableType = this.formattableTypes.FindOrDefault(f => f.IsRelatedType(type, true));

            if (formattableType == null)
            {
                // If formattable type isn't exists -> type isn't supported -> returns false
                return(false);
            }

            // Tries write the object in the storer

            string className = formattableType.Name;

            if (this.TryWriteValue(storer, path, references, graph, className))
            {
                formattableType.OnSerializing(graph);

                FormattableValue[] formattableValues = formattableType.GetValues(type);
                FormattableValue   formattableValue;
                int    length = formattableValues.Length;
                object value;
                Type   valueType;

                IDictionary <string, string> values = new Dictionary <string, string>(length);

                for (int i = 0; i < length; i++)
                {
                    formattableValue = formattableValues[i];

                    value     = formattableValue.GetValue(graph);
                    valueType = formattableValue.Type;

                    if (this.IsPrimitive(valueType))
                    {
                        // Value of the object is primitive - writes it in the information file

                        values.Add(formattableValue.Name, this.GetPrimitiveConverterToString(valueType)(value));
                    }
                    else
                    {
                        // Value of the object isn't primitive - writes it in new file

                        try
                        {
                            // Tries write a value in the new file
                            this.Write(
                                value,
                                StringUtils.Combine(path, formattableValue.Name, DirectorySeparatorString),
                                storer,
                                references
                                );
                        }
                        catch (Exception ex)
                        {
                            // Thrown error if value isn't optional
                            if (!formattableValue.Optional)
                            {
                                throw new KeyCanNotSavedException(formattableType, formattableType.Name, ex);
                            }
                        }
                    }
                }

                formattableType.OnSerialized(graph);

                this.WriteInfo(storer, path, className, values);
            }

            return(true);
        }
コード例 #7
0
        /// <summary>
        /// Tries write a multidimensional array in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="mdArrayType"> Type of the multidimensional array. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> True if multidimensional array has been written (or is exist), otherwise false. </returns>
        private bool TryWriteMDArray(object graph, Type mdArrayType, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            // Gets an identifier of the multidimensional array

            string identifier = GetMDArrayTypeIndentifier(mdArrayType);

            if (identifier == null)
            {
                // If identifier is null -> multidimensional array isn't supported -> returns false
                return(false);
            }

            // Tries write the multidimensional array in the storer

            Array array = graph as Array;

            if (this.TryWriteValue(storer, path, references, array, identifier))
            {
                Type elementType = mdArrayType.GetElementType();
                bool isPrimitive = this.IsPrimitive(elementType);

                // Writes the information about of the multidimensional array in the document

                int   rank    = array.Rank;
                int[] lengths = new int[rank];
                bool  isEmpty = false;

                IDictionary <string, string> values = new Dictionary <string, string>(rank + 2)
                {
                    { RankString, array.Rank.ToString() },
                };

                int length = 0;
                for (int i = 0; i < rank; i++)
                {
                    length     = array.GetLength(i);
                    lengths[i] = length;

                    if (!isEmpty && length == 0)
                    {
                        isEmpty = true;
                    }

                    values.Add(StringUtils.Combine(LengthWithUnderscoreString, (i + 1).ToString()), length.ToString());
                }

                values.Add(PrimitiveString, isPrimitive ? TrueString : FalseString);

                this.WriteInfo(storer, path, identifier, values);

                if (!isEmpty)
                {
                    if (isPrimitive)
                    {
                        // Elements of the multidimensional array are primitive - writes their in single file

                        storer.Add(
                            StringUtils.Combine(path, MDArrayFileName),
                            this.GetPrimitiveMDArrayData(array, elementType, lengths)
                            );
                    }
                    else
                    {
                        // Elements of the multidimensional array aren't primitive - writes their in different files

                        IEnumerable <int[]> product = CreateCartesianProduct(lengths);

                        int    index       = 0;
                        string indexString = "";
                        foreach (int[] p in product)
                        {
                            indexString = index.ToString();
                            index++;

                            Write(
                                p,
                                StringUtils.Combine(path, indexString, IndicesDirectoryString),
                                storer,
                                references
                                );

                            Write(
                                array.GetValue(p),
                                StringUtils.Combine(path, indexString, ValueDirectoryString),
                                storer,
                                references
                                );
                        }
                    }
                }
            }

            return(true);
        }
コード例 #8
0
        /// <summary>
        /// Tries write a dictionary in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="dicType"> Type of the dictionary. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> True if dictionary has been written (or is exist), otherwise false. </returns>
        private bool TryWriteDictionary(object graph, Type dicType, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            // Gets an identifier of the dictionary

            string identifier = GetDictionaryTypeIndentifier(dicType);

            if (identifier == null)
            {
                // If identifier is null -> dictionary isn't supported -> returns false
                return(false);
            }

            // Tries write the dictionary in the storer

            IDictionary dictionary = graph as IDictionary;

            if (this.TryWriteValue(storer, path, references, dictionary, identifier))
            {
                Type[] genericArgs = dicType.GetGenericArguments();
                Type   keyType     = genericArgs[0];
                Type   valueType   = genericArgs[1];

                bool isPrimitiveKeys   = IsPrimitive(keyType);
                bool isPrimitiveValues = IsPrimitive(valueType);
                int  count             = dictionary.Count;

                // Writes the information about of the dictionary in the document

                IDictionary <string, string> values = new Dictionary <string, string>()
                {
                    { PrimitiveKeysString, isPrimitiveKeys ? TrueString : FalseString },
                    { PrimitiveValuesString, isPrimitiveValues ? TrueString : FalseString },
                    { CountString, count.ToString() },
                };

                this.WriteInfo(storer, path, identifier, values);

                // Writes the data of the dictionary in the storer

                if (count != 0)
                {
                    if (isPrimitiveKeys && isPrimitiveValues)
                    {
                        // Keys and values of the dictionary are primitive - writes their in single file

                        storer.Add(
                            StringUtils.Combine(path, DictionaryFileName),
                            this.GetPrimitiveDictionaryData(dictionary, keyType, valueType)
                            );
                    }
                    else
                    {
                        if (isPrimitiveKeys)
                        {
                            // Keys of the dictionary are primitive - writes their in single file

                            storer.Add(
                                StringUtils.Combine(path, DictionaryKeysFileName),
                                this.GetPrimitiveDictionaryKeysData(dictionary, keyType)
                                );
                        }
                        else
                        {
                            // Keys aren't primitive - writes their in different files

                            int index = 0;
                            foreach (DictionaryEntry pair in dictionary)
                            {
                                this.Write(
                                    pair.Key,
                                    StringUtils.Combine(path, index.ToString(), KeyDirectoryString),
                                    storer,
                                    references
                                    );
                                index++;
                            }
                        }

                        if (isPrimitiveValues)
                        {
                            // Values of the dictionary are primitive - writes their in single file

                            storer.Add(
                                StringUtils.Combine(path, DictionaryValuesFileName),
                                this.GetPrimitiveDictionaryValuesData(dictionary, valueType)
                                );
                        }
                        else
                        {
                            // Values of the dictionary aren't primitive - writes their in different files

                            int index = 0;
                            foreach (DictionaryEntry pair in dictionary)
                            {
                                this.Write(
                                    pair.Value,
                                    StringUtils.Combine(path, index.ToString(), ValueDirectoryString),
                                    storer,
                                    references
                                    );
                                index++;
                            }
                        }
                    }
                }
            }

            return(true);
        }
コード例 #9
0
        /// <summary>
        /// Tries write a collection in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="collectionType"> Type of the collection. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> True if collection has been written (or is exist), otherwise false. </returns>
        private bool TryWriteCollection(object graph, Type collectionType, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            // Gets an identifier of the collection

            string identifier = GetCollectionTypeIndentifier(collectionType);

            if (identifier == null)
            {
                // If identifier is null -> collection isn't supported -> returns false
                return(false);
            }

            // Tries write the collection in the storer

            IEnumerable enumerable = graph as IEnumerable;

            if (this.TryWriteValue(storer, path, references, enumerable, identifier))
            {
                Type elementType = (collectionType.IsArray) ? collectionType.GetElementType() : collectionType.GetGenericArguments()[0];

                bool isPrimitive = this.IsPrimitive(elementType);
                int  count       = 0;

                ICollection collection = enumerable as ICollection;
                if (collection != null)
                {
                    count = collection.Count;
                }
                else
                {
                    IEnumerator enumerator = enumerable.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        count++;
                    }
                }

                // Writes the information about of the collection in the document

                IDictionary <string, string> values = new Dictionary <string, string>()
                {
                    { PrimitiveString, isPrimitive ? TrueString : FalseString },
                    { CountString, count.ToString() },
                };

                this.WriteInfo(storer, path, identifier, values);

                // Writes the data of the collection in the storer

                if (count != 0)
                {
                    if (isPrimitive)
                    {
                        // Elements of the collection are primitive - writes their in single file

                        storer.Add(
                            StringUtils.Combine(path, CollectionFileName),
                            this.GetPrimitiveCollectionData(enumerable, elementType)
                            );
                    }
                    else
                    {
                        // Elements of the collection aren't primitive - writes their in differerent files

                        IList list = enumerable as IList;
                        if (list != null)
                        {
                            for (int i = 0; i < count; i++)
                            {
                                this.Write(
                                    list[i],
                                    StringUtils.Combine(path, i.ToString(), DirectorySeparatorString),
                                    storer,
                                    references
                                    );
                            }
                        }
                        else
                        {
                            int index = 0;
                            foreach (object item in enumerable)
                            {
                                this.Write(
                                    item,
                                    StringUtils.Combine(path, index.ToString(), DirectorySeparatorString),
                                    storer,
                                    references
                                    );
                                index++;
                            }
                        }
                    }
                }
            }

            return(true);
        }