Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

ProtocolWriter.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file ProtocolWriter.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032 
00033         @version        Initial version, July 2004      
00034         @author         Kris
00035 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.cluster.qos.socket.ProtocolWriter;
00040 
00041 private import mango.io.model.IPickle;
00042 
00043 private import  mango.io.PickleWriter,
00044                 mango.io.EndianWriter;
00045 
00046 private import  mango.cluster.model.IChannel;
00047 
00048 /*******************************************************************************
00049         
00050         Objects passed around a cluster are prefixed with a header, so the 
00051         receiver can pick them apart correctly. This header consists of:
00052 
00053         - the packet size, including the header (16 bits)
00054         - a command code (8 bits)
00055         - the length of the channel name (8 bits)
00056         - the channel name
00057         - the payload (an IPickle class)
00058 
00059         Everything is written in Network order (big endian).
00060 
00061 *******************************************************************************/
00062 
00063 class ProtocolWriter : PickleWriter
00064 {
00065         const ubyte Version = 0x01;
00066 
00067         enum Command : ubyte {OK, Exception, Full, Locked, 
00068                               Add, Copy, Remove, Load, AddQueue, RemoveQueue};
00069 
00070         /***********************************************************************
00071         
00072                 Construct a ProtocolWriter upon the given buffer. As
00073                 Objects are serialized, their content is written to this
00074                 buffer. The buffer content is then typically flushed to 
00075                 some external conduit, such as a file or socket.
00076 
00077                 Note that serialized data is always in Network order.
00078 
00079         ***********************************************************************/
00080         
00081         this (IBuffer buffer)
00082         in {
00083            assert (buffer);
00084            }
00085         body
00086         {
00087                 super (buffer);
00088         }
00089 
00090         /***********************************************************************
00091                 
00092                 Flush the output
00093         
00094         ***********************************************************************/
00095 
00096         override IWriter flush () 
00097         {
00098                 // remember the current buffer content
00099                 uint content = buffer.readable ();
00100 
00101                 // flush pickled object(s) to output
00102                 super.flush ();
00103 
00104                 // skip back in case we have to try this again
00105                 buffer.skip (-content);
00106 
00107                 return this;
00108         }
00109 
00110         /***********************************************************************
00111         
00112         ***********************************************************************/
00113 
00114         ProtocolWriter put (Command cmd, char[] channel, IPickle object = null, char[] element = null)
00115         {
00116                 // reset the buffer first!
00117                 buffer.clear ();
00118                 ubyte[] content = cast(ubyte[]) buffer.getContent();
00119 
00120                 super.put (cast(ushort) 0)
00121                      .put (cast(ubyte) cmd)
00122                      .put (cast(ubyte) Version)
00123                      .put (channel)
00124                      .put (element);
00125 
00126                 // is there a payload?
00127                 if (object)
00128                     super.freeze (object);
00129 
00130                 // go back and write the total number of bytes
00131                 ushort size = buffer.getLimit;
00132                 content[0] = size >> 8;
00133                 content[1] = size & 0xff;
00134                 return this;
00135         }
00136 
00137         /***********************************************************************
00138         
00139                 Write an exception message
00140 
00141         ***********************************************************************/
00142 
00143         ProtocolWriter exception (char[] message)
00144         {
00145                 put (ProtocolWriter.Command.Exception, message);
00146                 return this;
00147         }
00148 
00149         /***********************************************************************
00150                 
00151                 Write an "OK" confirmation
00152 
00153         ***********************************************************************/
00154 
00155         ProtocolWriter success (char[] message = null)
00156         {
00157                 put (ProtocolWriter.Command.OK, message);
00158                 return this;
00159         }
00160 
00161         /***********************************************************************
00162                 
00163                 Indicate something has filled up
00164 
00165         ***********************************************************************/
00166 
00167         ProtocolWriter full (char[] message)
00168         {
00169                 put (ProtocolWriter.Command.Full, message);
00170                 return this;
00171         }
00172 
00173         /***********************************************************************
00174         
00175                 Write a serialized payload as constructed by the method
00176                 ProtocolReader.getPacket()
00177 
00178         ***********************************************************************/
00179 
00180         ProtocolWriter reply (ClusterContent content)
00181         {
00182                 // reset the buffer first
00183                 buffer.clear ();
00184 
00185                 // write the length ...
00186                 super.put (cast(ushort) (content.length + ushort.sizeof + ubyte.sizeof + ubyte.sizeof));
00187 
00188                 // and the ack ...
00189                 super.put (cast(ubyte) ProtocolWriter.Command.OK);
00190 
00191                 // and the version ...
00192                 super.put (cast(ubyte) Version);
00193 
00194                 // and the payload (which includes both channel & element)
00195                 if (content.length)
00196                     buffer.append (content);
00197                 else
00198                    // or filler for an empty channel & element ...
00199                    super.put (cast(int) 0).put(cast(int) 0);
00200 
00201                 return this;
00202         }
00203 }
00204 

Generated on Tue Jan 25 21:18:22 2005 for Mango by doxygen 1.3.6