Click here to Skip to main content
15,885,309 members
Articles / Mobile Apps / Windows Mobile

XML Serialization of Generic Dictionary, Multidimensional Array, and Inherited Type, with sharpSerializer .NET

Rate me:
Please Sign up or sign in to vote.
4.92/5 (48 votes)
9 Nov 2011CPOL8 min read 250.6K   2.9K   122  
How to serialize to XML, any generic, derived, or other complex type, which XMLSerializer cannot serialize
#region Copyright � 2010 Pawel Idzikowski [idzikowski@sharpserializer.com]

//  ***********************************************************************
//  Project: sharpSerializer
//  Web: http://www.sharpserializer.com
//  
//  This software is provided 'as-is', without any express or implied warranty.
//  In no event will the author(s) be held liable for any damages arising from
//  the use of this software.
//  
//  Permission is granted to anyone to use this software for any purpose,
//  including commercial applications, and to alter it and redistribute it
//  freely, subject to the following restrictions:
//  
//      1. The origin of this software must not be misrepresented; you must not
//        claim that you wrote the original software. If you use this software
//        in a product, an acknowledgment in the product documentation would be
//        appreciated but is not required.
//  
//      2. Altered source versions must be plainly marked as such, and must not
//        be misrepresented as being the original software.
//  
//      3. This notice may not be removed or altered from any source distribution.
//  
//  ***********************************************************************

#endregion

using System;
using System.Collections.Generic;
using System.IO;

namespace Polenter.Serialization.Core.Binary
{
    /// <summary>
    ///   Some methods which are used by IBinaryReader
    /// </summary>
    public static class BinaryReaderTools
    {
        ///<summary>
        ///</summary>
        ///<param name = "reader"></param>
        ///<returns></returns>
        public static string ReadString(BinaryReader reader)
        {
            if (!reader.ReadBoolean()) return null;
            return reader.ReadString();
        }

        ///<summary>
        ///</summary>
        ///<param name = "reader"></param>
        ///<returns></returns>
        public static int ReadNumber(BinaryReader reader)
        {
            // Size
            byte size = reader.ReadByte();

            // Number
            switch (size)
            {
                case NumberSize.Zero:
                    return 0;
                case NumberSize.B1:
                    return reader.ReadByte();
                case NumberSize.B2:
                    return reader.ReadInt16();
                default:
                    return reader.ReadInt32();
            }
        }

        /// <summary>
        /// </summary>
        /// <returns>empty array if there are no indexes</returns>
        public static int[] ReadNumbers(BinaryReader reader)
        {
            // Count
            int count = ReadNumber(reader);

            if (count == 0) return new int[0];

            // Items
            var result = new List<int>();
            for (int i = 0; i < count; i++)
            {
                result.Add(ReadNumber(reader));
            }
            return result.ToArray();
        }

        ///<summary>
        ///</summary>
        ///<param name = "expectedType"></param>
        ///<param name = "reader"></param>
        ///<returns></returns>
        public static object ReadValue(Type expectedType, BinaryReader reader)
        {
            if (!reader.ReadBoolean()) return null;
            return readValueCore(expectedType, reader);
        }

        private static object readValueCore(Type type, BinaryReader reader)
        {
            try
            {
                if (type == typeof (byte[])) return readArrayOfByte(reader);
                if (type == typeof (string)) return reader.ReadString();
                if (type == typeof (Boolean)) return reader.ReadBoolean();
                if (type == typeof (Byte)) return reader.ReadByte();
                if (type == typeof (Char)) return reader.ReadChar();
                if (type == typeof (DateTime)) return new DateTime(reader.ReadInt64());
                if (type == typeof(Guid)) return new Guid(reader.ReadBytes(16));
#if DEBUG || Smartphone || SILVERLIGHT
                if (type == typeof(decimal)) return readDecimal(reader);                
#else
                if (type == typeof (Decimal)) return reader.ReadDecimal();
#endif
                if (type == typeof (Double)) return reader.ReadDouble();
                if (type == typeof (Int16)) return reader.ReadInt16();
                if (type == typeof (Int32)) return reader.ReadInt32();
                if (type == typeof (Int64)) return reader.ReadInt64();
                if (type == typeof (SByte)) return reader.ReadSByte();
                if (type == typeof (Single)) return reader.ReadSingle();
                if (type == typeof (UInt16)) return reader.ReadUInt16();
                if (type == typeof (UInt32)) return reader.ReadUInt32();
                if (type == typeof (UInt64)) return reader.ReadUInt64();

                if (type == typeof (TimeSpan)) return new TimeSpan(reader.ReadInt64());

                // Enumeration
                if (type.IsEnum) return readEnumeration(type, reader);

                // Type
                if (isType(type))
                {
                    var typeName = reader.ReadString();
                    return Type.GetType(typeName, true);
                }

                throw new InvalidOperationException(string.Format("Unknown simple type: {0}", type.FullName));
            }
            catch (Exception ex)
            {
                throw new SimpleValueParsingException(
                    string.Format("Invalid type: {0}. See details in the inner exception.", type), ex);
            }
        }

        private static object readDecimal(BinaryReader reader)
        {
            var bits = new int[4];
            bits[0] = reader.ReadInt32();
            bits[1] = reader.ReadInt32();
            bits[2] = reader.ReadInt32();
            bits[3] = reader.ReadInt32();
            return new decimal(bits);
        }

        private static bool isType(Type type)
        {
            return type == typeof (Type) || type.IsSubclassOf(typeof (Type));
        }

        private static object readEnumeration(Type expectedType, BinaryReader reader)
        {
            // read the enum as int
            int value = reader.ReadInt32();
            object result = Enum.ToObject(expectedType, value);
            return result;
        }

        private static byte[] readArrayOfByte(BinaryReader reader)
        {
            int length = ReadNumber(reader);
            if (length == 0) return null;

            return reader.ReadBytes(length);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Polenter - Software Solutions
Germany Germany
I'm C# developer from Cologne, Germany. Here I owe a small software company. My hobby is general optimization - natural talent of all lazy people Wink | ;-)

Comments and Discussions