Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C#

A Fast/Compact Serialization Framework

Rate me:
Please Sign up or sign in to vote.
4.85/5 (37 votes)
13 Oct 2010GPL35 min read 281.6K   1.2K   175  
A framework for object serializiation/deserialization that is many times faster and yields a compact output.
/*

OpenNxSerialization Framework
Copyright (C) 2006 - 2008 "NeXtreme Innovations"
[The Next Xtreme Innovations]

This program is free software, distributed under the terms of
the GNU General Public License Version 2. See the "License.txt" file
at the top of the source tree.

*/
using System;
using System.IO;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;

using NeXtreme.OpenNxSerialization.Surrogates;

namespace NeXtreme.OpenNxSerialization.IO
{
    /// <summary>
    /// This class encapsulates a <see cref="BinaryReader"/> object. It also provides an extra
    /// Read method for <see cref="System.Object"/> types. 
    /// </summary>
    public class NxBinaryReader : IDisposable, INxBinaryReader
    {
        private NxSerializationContext mContext;
        private BinaryReader mBaseReader;

        /// <summary>
        /// Constructs a compact reader over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="input"><see cref="Stream"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="input"/> is null</exception>
        public NxBinaryReader(Stream input)
            : this(input, Encoding.Default, new NxSerializationContext())
        {
        }
        /// <summary>
        /// Constructs a compact reader over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="input"><see cref="Stream"/> object</param>
        /// <param name="encoding"><see cref="System.Text.Encoding"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="input"/> is null</exception>
        public NxBinaryReader(Stream input, Encoding encoding)
            : this(input, Encoding.Default, new NxSerializationContext())
        {
            mContext = new NxSerializationContext();
            mBaseReader = new BinaryReader(input, encoding);
        }
        /// <summary>
        /// Constructs a compact reader over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="input"><see cref="Stream"/> object</param>
        /// <param name="encoding"><see cref="System.Text.Encoding"/> object</param>
        /// <param name="context"><see cref="NxSerializationContext"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="input"/> is null</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="context"/> is null</exception>
        public NxBinaryReader(Stream input, Encoding encoding, NxSerializationContext context)
        {
            if (input == null)
                throw new ArgumentNullException("input");
            if (context == null)
                throw new ArgumentNullException("context");
            this.mContext = context;
            this.mBaseReader = new BinaryReader(input, encoding);
        }

        /// <summary>
        /// Finalizer
        /// </summary>
        ~NxBinaryReader()
        {
            Dispose(false);
        }

        /// <summary> Returns the underlying <see cref="Stream"/> object. </summary>
        public Stream BaseStream { get { return mBaseReader.BaseStream; } }
        /// <summary> Returns the current <see cref="NxSerializationContext"/> object. </summary>
        public NxSerializationContext Context { get { return mContext; } }
        /// <summary>Returns the associated <see cref="INxTypeSurrogateSelector"/> instance.</summary>
        public INxTypeSurrogateSelector SurrogateSelector { get { return mContext.SurrogateSelector; } }

        /// <summary>
        /// Close the underlying <see cref="BinaryWriter"/>.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Close the underlying <see cref="BinaryWriter"/>.
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
        }

        /// <summary>
        /// Reads an object of type <see cref="object"/> from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <returns>The root of the deserialized object graph</returns>
        public object ReadObject()
        {
            // read type handle
            short handle = ReadInt16();
            // Find an appropriate surrogate by handle
            INxSerializationSurrogate surrogate =
                mContext.SurrogateSelector.GetSurrogateForTypeHandle(handle);
            return surrogate.Read(this);
        }

        /// <summary>
        /// Reads an object of type <see cref="object"/> from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <param name="handler">The delegate designed to handle <see cref="Header"/> objects. Can be a null reference</param>
        /// <returns>The root of the deserialized object graph</returns>
        public object ReadObject(HeaderHandler handler)
        {
            // read type handle
            short handle = ReadInt16();
            // Find an appropriate surrogate by handle
            INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForTypeHandle(handle);
            if (surrogate is INxRemotingSerializationSurrogate)
                return ((INxRemotingSerializationSurrogate)surrogate).Read(this, handler);
            else
            {
                Header[] headers = (Header[])ReadObjectAs(typeof(Header[]));
                if (handler != null)
                    handler(headers);
                return surrogate.Read(this);
            }
        }

        /// <summary>
        /// Reads an object of type <see cref="object"/> from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <param name="type">Reads the object using surrogate for type <paramref name="type"/></param>
        /// <returns>object read from the stream</returns>
        public object ReadObjectAs(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            // Find an appropriate surrogate by type
            INxSerializationSurrogate surrogate =
                mContext.SurrogateSelector.GetSurrogateForType(type);
            return surrogate.Read(this);
        }

        /// <summary>
        /// Reads an object of type <see cref="object"/> from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <param name="type">Reads the object using surrogate for type <paramref name="type"/></param>
        /// <param name="handler">The delegate designed to handle <see cref="Header"/> objects. Can be a null reference</param>
        /// <returns>The root of the deserialized object graph</returns>
        /// <returns>object read from the stream</returns>
        public object ReadObjectAs(Type type, HeaderHandler handler)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            // Find an appropriate surrogate by type
            INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForType(type);
            if (surrogate is INxRemotingSerializationSurrogate)
                return ((INxRemotingSerializationSurrogate)surrogate).Read(this, handler);
            else
            {
                Header[] headers = (Header[])ReadObjectAs(typeof(Header[]));
                if (handler != null)
                    handler(headers);
                return surrogate.Read(this);
            }
        }

        /// <summary>
        /// Reads an object of type <see cref="object"/> from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <returns>object read from the stream</returns>
        public T ReadObjectAs<T>()
        {
            // Find an appropriate surrogate by type
            INxSerializationSurrogate surrogate =
                mContext.SurrogateSelector.GetSurrogateForType(typeof(T));
            return (T)surrogate.Read(this);
        }

        /// <summary>
        /// Reads an object of type T from the current stream 
        /// and advances the stream position. 
        /// </summary>
        /// <param name="handler">The delegate designed to handle <see cref="Header"/> objects. Can be a null reference</param>
        /// <returns>The root of the deserialized object graph</returns>
        /// <returns>object of type T read from the stream</returns>
        public T ReadObjectAs<T>(HeaderHandler handler)
        {
            // Find an appropriate surrogate by type
            INxSerializationSurrogate surrogate =
                mContext.SurrogateSelector.GetSurrogateForType(typeof(T));
            if (surrogate is INxRemotingSerializationSurrogate)
                return (T)((INxRemotingSerializationSurrogate)surrogate).Read(this, handler);
            else
            {
                Header[] headers = (Header[])ReadObjectAs(typeof(Header[]));
                if (handler != null)
                    handler(headers);
                return (T)surrogate.Read(this);
            }
        }

        #region /      NxBinaryReader.ReadXXX      /

        /// <summary>
        /// Reads an object of type <see cref="bool"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public bool ReadBoolean() { return mBaseReader.ReadBoolean(); }
        /// <summary>
        /// Reads an object of type <see cref="byte"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public byte ReadByte() { return mBaseReader.ReadByte(); }
        /// <summary>
        /// Reads an object of type <see cref="byte"/>[] from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <param name="count">number of bytes read</param>
        /// <returns>object read from the stream</returns>
        public byte[] ReadBytes(int count) { return mBaseReader.ReadBytes(count); }
        /// <summary>
        /// Reads an object of type <see cref="char"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public char ReadChar() { return mBaseReader.ReadChar(); }
        /// <summary>
        /// Reads an object of type <see cref="char"/>[] from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public char[] ReadChars(int count) { return mBaseReader.ReadChars(count); }
        /// <summary>
        /// Reads an object of type <see cref="decimal"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public decimal ReadDecimal() { return mBaseReader.ReadDecimal(); }
        /// <summary>
        /// Reads an object of type <see cref="float"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public float ReadSingle() { return mBaseReader.ReadSingle(); }
        /// <summary>
        /// Reads an object of type <see cref="double"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public double ReadDouble() { return mBaseReader.ReadDouble(); }
        /// <summary>
        /// Reads an object of type <see cref="short"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public short ReadInt16() { return mBaseReader.ReadInt16(); }
        /// <summary>
        /// Reads an object of type <see cref="int"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public int ReadInt32() { return mBaseReader.ReadInt32(); }
        /// <summary>
        /// Reads an object of type <see cref="long"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public long ReadInt64() { return mBaseReader.ReadInt64(); }
        /// <summary>
        /// Reads an object of type <see cref="string"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public string ReadString() { return mBaseReader.ReadString(); }
        /// <summary>
        /// Reads an object of type <see cref="DateTime"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public DateTime ReadDateTime() { return DateTime.FromBinary(mBaseReader.ReadInt64()); }
        /// <summary>
        /// Reads an object of type <see cref="Guid"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        public Guid ReadGuid() { return new Guid(mBaseReader.ReadBytes(16)); }
        /// <summary>
        /// Reads the specifies number of bytes into <paramref name="buffer"/>.
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <param name="buffer">buffer to read into</param>
        /// <param name="index">starting position in the buffer</param>
        /// <param name="count">number of bytes to write</param>
        /// <returns>number of buffer read</returns>
        public int Read(byte[] buffer, int index, int count) { return mBaseReader.Read(buffer, index, count); }
        /// <summary>
        /// Reads the specifies number of bytes into <paramref name="buffer"/>.
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <param name="buffer">buffer to read into</param>
        /// <param name="index">starting position in the buffer</param>
        /// <param name="count">number of bytes to write</param>
        /// <returns>number of chars read</returns>
        public int Read(char[] buffer, int index, int count) { return mBaseReader.Read(buffer, index, count); }
        /// <summary>
        /// Reads an object of type <see cref="sbyte"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        [CLSCompliant(false)]
        public sbyte ReadSByte() { return mBaseReader.ReadSByte(); }
        /// <summary>
        /// Reads an object of type <see cref="ushort"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        [CLSCompliant(false)]
        public ushort ReadUInt16() { return mBaseReader.ReadUInt16(); }
        /// <summary>
        /// Reads an object of type <see cref="uint"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        [CLSCompliant(false)]
        public uint ReadUInt32() { return mBaseReader.ReadUInt32(); }
        /// <summary>
        /// Reads an object of type <see cref="ulong"/> from the current stream 
        /// and advances the stream position. 
        /// This method reads directly from the underlying stream.
        /// </summary>
        /// <returns>object read from the stream</returns>
        [CLSCompliant(false)]
        public ulong ReadUInt64() { return mBaseReader.ReadUInt64(); }

        #endregion
    }
}

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 GNU General Public License (GPLv3)


Written By
Architect
Pakistan Pakistan
Let a = b ....... (1)
a - b = a - b
a^2 - ab = a^2 - ab
a^2 - ab = a^2 - b^2 (from 1)
a (a - b) = (a + b) (a - b)
a = (a + b) ...... (2)

if a = 1
1 = (1 + 1) (from 1 & 2)
1 = 2 !!

Comments and Discussions