Click here to Skip to main content
15,885,365 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.9K   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="BinaryWriter"/> object. It also provides an extra
    /// Write method for <see cref="System.Object"/> types. 
    /// </summary>
    public class NxBinaryWriter : IDisposable, INxBinaryWriter
    {
        private NxSerializationContext mContext;
        private BinaryWriter mBaseWriter;

        /// <summary>
        /// Constructs a compact writer over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="output"><see cref="Stream"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="output"/> is null</exception>
        public NxBinaryWriter(Stream output)
            : this(output, Encoding.Default, new NxSerializationContext())
        {
        }
        /// <summary>
        /// Constructs a compact writer over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="output"><see cref="Stream"/> object</param>
        /// <param name="encoding"><see cref="Encoding"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="output"/> is null</exception>
        public NxBinaryWriter(Stream output, Encoding encoding)
            : this(output, encoding, new NxSerializationContext())
        {
        }
        /// <summary>
        /// Constructs a compact writer over a <see cref="Stream"/> object.
        /// </summary>
        /// <param name="output"><see cref="Stream"/> object</param>
        /// <param name="encoding"><see cref="Encoding"/> object</param>
        /// <param name="context"><see cref="NxSerializationContext"/> object</param>
        /// <exception cref="ArgumentNullException">If <paramref name="output"/> is null</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="context"/> is null</exception>
        public NxBinaryWriter(Stream output, Encoding encoding, NxSerializationContext context)
        {
            if (output == null)
                throw new ArgumentNullException("output");
            if (context == null)
                throw new ArgumentNullException("context");
            this.mContext = context;
            this.mBaseWriter = new BinaryWriter(output, encoding);
        }

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

        /// <summary> Returns the underlying <see cref="Stream"/> object. </summary>
        public Stream BaseStream { get { return mBaseWriter.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>
        /// Writes <paramref name="null"/> to the current stream and advances the stream position. 
        /// </summary>
        public void WriteNull()
        {
            // write type handle
            mBaseWriter.Write(mContext.SurrogateSelector.NullSurrogate.TypeHandle);
        }
        
        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be written</param>
        public void WriteObject(object graph)
        {
            // Find an appropriate surrogate for the object
            INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForObject(graph);
            // write type handle
            mBaseWriter.Write(surrogate.TypeHandle);
            surrogate.Write(this, graph);
        }

        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be serialized</param>
        /// <param name="headers">The array of <see cref="Header"/> objects to transmit with the graph specified by the graph parameter. 
        /// Can be a null reference </param>
        public void WriteObject(object graph, Header[] headers)
        {
            // Find an appropriate surrogate for the object
            INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForObject(graph);
            // write type handle
            Write(surrogate.TypeHandle);
            if (surrogate is INxRemotingSerializationSurrogate)
                ((INxRemotingSerializationSurrogate)surrogate).Write(this, graph, headers);
            else
            {
                WriteObjectAs(headers, typeof(Header[]));
                surrogate.Write(this, graph);
            }
        }

        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be written</param>
        /// <param name="type">Writes the object using surrogate for type <paramref name="type"/></param>
        public void WriteObjectAs(object graph, Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (graph == null)
                Write(mContext.SurrogateSelector.NullSurrogate.TypeHandle);
            else
            {
                // Find an appropriate surrogate for the object
                INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForType(type);
                surrogate.Write(this, graph);
            }
        }

        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be written</param>
        /// <param name="type">Writes the object using surrogate for type <paramref name="type"/></param>
        /// <param name="headers">The array of <see cref="Header"/> objects to transmit with the graph specified by the graph parameter. 
        /// Can be a null reference </param>
        public void WriteObjectAs(object graph, Type type, Header[] headers)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (graph == null)
                Write(mContext.SurrogateSelector.NullSurrogate.TypeHandle);
            else
            {
                // Find an appropriate surrogate for the object
                INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForType(type);
                if (surrogate is INxRemotingSerializationSurrogate)
                    ((INxRemotingSerializationSurrogate)surrogate).Write(this, graph, headers);
                else
                {
                    WriteObjectAs(headers, typeof(Header[]));
                    surrogate.Write(this, graph);
                }
            }
        }

        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be written</param>
        public void WriteObjectAs<T>(T graph)
        {
            // Find an appropriate surrogate for the object
            INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForType(typeof(T));
            surrogate.Write(this, graph);
        }


        /// <summary>
        /// Writes <paramref name="graph"/> to the current stream and advances the stream position. 
        /// </summary>
        /// <param name="graph">The root of the object graph to be written</param>
        /// <param name="headers">The array of <see cref="Header"/> objects to transmit with the graph specified by the graph parameter. 
        /// Can be a null reference </param>
        public void WriteObjectAs<T>(T graph, Header[] headers)
        {
            if (graph == null)
                mBaseWriter.Write(mContext.SurrogateSelector.NullSurrogate.TypeHandle);
            else
            {
                // Find an appropriate surrogate for the object
                INxSerializationSurrogate surrogate = mContext.SurrogateSelector.GetSurrogateForType(typeof(T));
                if (surrogate is INxRemotingSerializationSurrogate)
                    ((INxRemotingSerializationSurrogate)surrogate).Write(this, graph, headers);
                else
                {
                    WriteObjectAs(headers, typeof(Header[]));
                    surrogate.Write(this, graph);
                }
            }
        }


        #region /      INxBinaryWriter.Write(XXX)      /

        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(bool value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(byte value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="ch"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="ch">Object to write</param>
        public void Write(char ch) { mBaseWriter.Write(ch); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(short value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(int value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(long value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(decimal value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(float value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(double value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(DateTime value) { mBaseWriter.Write(value.ToBinary()); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(Guid value) { mBaseWriter.Write(value.ToByteArray()); }
        /// <summary>
        /// Writes <paramref name="buffer"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="buffer">Object to write</param>
        public void Write(byte[] buffer) { mBaseWriter.Write(buffer); }
        /// <summary>
        /// Writes <paramref name="chars"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="chars">Object to write</param>
        public void Write(char[] chars) { mBaseWriter.Write(chars); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        public void Write(string value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="buffer"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="buffer">buffer to write</param>
        /// <param name="index">starting position in the buffer</param>
        /// <param name="count">number of bytes to write</param>
        public void Write(byte[] buffer, int index, int count) { mBaseWriter.Write(buffer, index, count); }
        /// <summary>
        /// Writes <paramref name="chars"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="chars">buffer to write</param>
        /// <param name="index">starting position in the buffer</param>
        /// <param name="count">number of bytes to write</param>
        public void Write(char[] chars, int index, int count) { mBaseWriter.Write(chars, index, count); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        [CLSCompliant(false)]
        public void Write(sbyte value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        [CLSCompliant(false)]
        public void Write(ushort value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        [CLSCompliant(false)]
        public void Write(uint value) { mBaseWriter.Write(value); }
        /// <summary>
        /// Writes <paramref name="value"/> to the current stream and advances the stream position. 
        /// This method writes directly to the underlying stream.
        /// </summary>
        /// <param name="value">Object to write</param>
        [CLSCompliant(false)]
        public void Write(ulong value) { mBaseWriter.Write(value); }

        #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