/*
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
}
}