Mercurial > projects > ldc
view tango/tango/io/protocol/Writer.d @ 137:ce7b81fb957f trunk
[svn r141] fixed more problems with classinfo
moved more IR state out of the AST classes
author | lindquist |
---|---|
date | Fri, 18 Jan 2008 16:42:16 +0100 |
parents | 1700239cab2e |
children |
line wrap: on
line source
/******************************************************************************* copyright: Copyright (c) 2004 Kris Bell. All rights reserved license: BSD style: $(LICENSE) version: Oct 2004: Initial release Dec 2006: Outback release author: Kris *******************************************************************************/ module tango.io.protocol.Writer; private import tango.io.Buffer, tango.io.FileConst; public import tango.io.model.IBuffer, tango.io.model.IConduit; public import tango.io.protocol.model.IWriter; private import tango.io.protocol.model.IProtocol; /******************************************************************************* Writer base-class. Writers provide the means to append formatted data to an IBuffer, and expose a convenient method of handling a variety of data types. In addition to writing native types such as integer and char[], writers also process any class which has implemented the IWritable interface (one method). All writers support the full set of native data types, plus their fundamental array variants. Operations may be chained back-to-back. Writers support a Java-esque put() notation. However, the Tango style is to place IO elements within their own parenthesis, like so: --- write (count) (" green bottles"); --- Note that each written element is distict; this style is affectionately known as "whisper". The code below illustrates basic operation upon a memory buffer: --- auto buf = new Buffer (256); // map same buffer into both reader and writer auto read = new Reader (buf); auto write = new Writer (buf); int i = 10; long j = 20; double d = 3.14159; char[] c = "fred"; // write data types out write (c) (i) (j) (d); // read them back again read (c) (i) (j) (d); // same thing again, but using put() syntax instead write.put(c).put(i).put(j).put(d); read.get(c).get(i).get(j).get(d); --- Writers may also be used with any class implementing the IWritable interface, along with any struct implementing an equivalent function. *******************************************************************************/ class Writer : IWriter { // the buffer associated with this writer. Note that this // should not change over the lifetime of the reader, since // it is assumed to be immutable elsewhere package IBuffer buffer_; package IProtocol.ArrayWriter arrays; package IProtocol.Writer elements; // end of line sequence package char[] eol = FileConst.NewlineString; /*********************************************************************** Construct a Writer on the provided Protocol ***********************************************************************/ this (IProtocol protocol) { buffer_ = protocol.buffer; elements = &protocol.write; arrays = &protocol.writeArray; } /*********************************************************************** Construct a Writer on the given OutputStream. We do our own protocol handling, equivalent to the NativeProtocol. ***********************************************************************/ this (OutputStream stream) { auto b = cast(Buffered) stream; buffer_ = (b ? b.buffer : new Buffer (stream.conduit)); arrays = &writeArray; elements = &writeElement; } /*********************************************************************** Return the associated buffer ***********************************************************************/ final IBuffer buffer () { return buffer_; } /*********************************************************************** Emit a newline ***********************************************************************/ IWriter newline () { return put (eol); } /*********************************************************************** set the newline sequence ***********************************************************************/ IWriter newline (char[] eol) { this.eol = eol; return this; } /*********************************************************************** Flush the output of this writer and return a chaining ref ***********************************************************************/ final IWriter flush () { buffer_.flush; return this; } /*********************************************************************** Flush this writer. This is a convenience method used by the "whisper" syntax. ***********************************************************************/ final IWriter put () { return flush; } /*********************************************************************** Write via a delegate to the current buffer-position ***********************************************************************/ final IWriter put (IWriter.Closure dg) { dg (this); return this; } /*********************************************************************** Write a class to the current buffer-position ***********************************************************************/ final IWriter put (IWritable x) { if (x is null) buffer_.error ("Writer.put :: attempt to write a null IWritable object"); return put (&x.write); } /*********************************************************************** Write a boolean value to the current buffer-position ***********************************************************************/ final IWriter put (bool x) { elements (&x, x.sizeof, IProtocol.Type.Bool); return this; } /*********************************************************************** Write an unsigned byte value to the current buffer-position ***********************************************************************/ final IWriter put (ubyte x) { elements (&x, x.sizeof, IProtocol.Type.UByte); return this; } /*********************************************************************** Write a byte value to the current buffer-position ***********************************************************************/ final IWriter put (byte x) { elements (&x, x.sizeof, IProtocol.Type.Byte); return this; } /*********************************************************************** Write an unsigned short value to the current buffer-position ***********************************************************************/ final IWriter put (ushort x) { elements (&x, x.sizeof, IProtocol.Type.UShort); return this; } /*********************************************************************** Write a short value to the current buffer-position ***********************************************************************/ final IWriter put (short x) { elements (&x, x.sizeof, IProtocol.Type.Short); return this; } /*********************************************************************** Write a unsigned int value to the current buffer-position ***********************************************************************/ final IWriter put (uint x) { elements (&x, x.sizeof, IProtocol.Type.UInt); return this; } /*********************************************************************** Write an int value to the current buffer-position ***********************************************************************/ final IWriter put (int x) { elements (&x, x.sizeof, IProtocol.Type.Int); return this; } /*********************************************************************** Write an unsigned long value to the current buffer-position ***********************************************************************/ final IWriter put (ulong x) { elements (&x, x.sizeof, IProtocol.Type.ULong); return this; } /*********************************************************************** Write a long value to the current buffer-position ***********************************************************************/ final IWriter put (long x) { elements (&x, x.sizeof, IProtocol.Type.Long); return this; } /*********************************************************************** Write a float value to the current buffer-position ***********************************************************************/ final IWriter put (float x) { elements (&x, x.sizeof, IProtocol.Type.Float); return this; } /*********************************************************************** Write a double value to the current buffer-position ***********************************************************************/ final IWriter put (double x) { elements (&x, x.sizeof, IProtocol.Type.Double); return this; } /*********************************************************************** Write a real value to the current buffer-position ***********************************************************************/ final IWriter put (real x) { elements (&x, x.sizeof, IProtocol.Type.Real); return this; } /*********************************************************************** Write a char value to the current buffer-position ***********************************************************************/ final IWriter put (char x) { elements (&x, x.sizeof, IProtocol.Type.Utf8); return this; } /*********************************************************************** Write a wchar value to the current buffer-position ***********************************************************************/ final IWriter put (wchar x) { elements (&x, x.sizeof, IProtocol.Type.Utf16); return this; } /*********************************************************************** Write a dchar value to the current buffer-position ***********************************************************************/ final IWriter put (dchar x) { elements (&x, x.sizeof, IProtocol.Type.Utf32); return this; } /*********************************************************************** Write a boolean array to the current buffer-position ***********************************************************************/ final IWriter put (bool[] x) { arrays (x.ptr, x.length * bool.sizeof, IProtocol.Type.Bool); return this; } /*********************************************************************** Write a byte array to the current buffer-position ***********************************************************************/ final IWriter put (byte[] x) { arrays (x.ptr, x.length * byte.sizeof, IProtocol.Type.Byte); return this; } /*********************************************************************** Write an unsigned byte array to the current buffer-position ***********************************************************************/ final IWriter put (ubyte[] x) { arrays (x.ptr, x.length * ubyte.sizeof, IProtocol.Type.UByte); return this; } /*********************************************************************** Write a short array to the current buffer-position ***********************************************************************/ final IWriter put (short[] x) { arrays (x.ptr, x.length * short.sizeof, IProtocol.Type.Short); return this; } /*********************************************************************** Write an unsigned short array to the current buffer-position ***********************************************************************/ final IWriter put (ushort[] x) { arrays (x.ptr, x.length * ushort.sizeof, IProtocol.Type.UShort); return this; } /*********************************************************************** Write an int array to the current buffer-position ***********************************************************************/ final IWriter put (int[] x) { arrays (x.ptr, x.length * int.sizeof, IProtocol.Type.Int); return this; } /*********************************************************************** Write an unsigned int array to the current buffer-position ***********************************************************************/ final IWriter put (uint[] x) { arrays (x.ptr, x.length * uint.sizeof, IProtocol.Type.UInt); return this; } /*********************************************************************** Write a long array to the current buffer-position ***********************************************************************/ final IWriter put (long[] x) { arrays (x.ptr, x.length * long.sizeof, IProtocol.Type.Long); return this; } /*********************************************************************** Write an unsigned long array to the current buffer-position ***********************************************************************/ final IWriter put (ulong[] x) { arrays (x.ptr, x.length * ulong.sizeof, IProtocol.Type.ULong); return this; } /*********************************************************************** Write a float array to the current buffer-position ***********************************************************************/ final IWriter put (float[] x) { arrays (x.ptr, x.length * float.sizeof, IProtocol.Type.Float); return this; } /*********************************************************************** Write a double array to the current buffer-position ***********************************************************************/ final IWriter put (double[] x) { arrays (x.ptr, x.length * double.sizeof, IProtocol.Type.Double); return this; } /*********************************************************************** Write a real array to the current buffer-position ***********************************************************************/ final IWriter put (real[] x) { arrays (x.ptr, x.length * real.sizeof, IProtocol.Type.Real); return this; } /*********************************************************************** Write a char array to the current buffer-position ***********************************************************************/ final IWriter put (char[] x) { arrays (x.ptr, x.length * char.sizeof, IProtocol.Type.Utf8); return this; } /*********************************************************************** Write a wchar array to the current buffer-position ***********************************************************************/ final IWriter put (wchar[] x) { arrays (x.ptr, x.length * wchar.sizeof, IProtocol.Type.Utf16); return this; } /*********************************************************************** Write a dchar array to the current buffer-position ***********************************************************************/ final IWriter put (dchar[] x) { arrays (x.ptr, x.length * dchar.sizeof, IProtocol.Type.Utf32); return this; } /*********************************************************************** Dump array content into the buffer. Note that the default behaviour is to prefix with the array byte count ***********************************************************************/ private void writeArray (void* src, uint bytes, IProtocol.Type type) { put (bytes); writeElement (src, bytes, type); } /*********************************************************************** Dump content into the buffer ***********************************************************************/ private void writeElement (void* src, uint bytes, IProtocol.Type type) { buffer_.append (src [0 .. bytes]); } }