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

ProtocolReader.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file ProtocolReader.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 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029 
00030         @version        Initial version, July 2004      
00031         @author         Kris
00032 
00033 
00034 *******************************************************************************/
00035 
00036 module mango.cluster.qos.socket.ProtocolReader;
00037 
00038 private import  mango.io.Exception,
00039                 mango.io.PickleReader,
00040                 mango.io.EndianReader;
00041 
00042 private import  mango.cluster.model.ICluster;
00043 
00044 /*******************************************************************************
00045         
00046         Objects passed around a cluster are prefixed with a header, so the 
00047         receiver can pick them apart correctly. This header consists of:
00048 
00049         - the packet size, including the header (16 bits)
00050         - a command code (8 bits)
00051         - the length of the channel name (8 bits)
00052         - the channel name
00053         - the payload (an IPickle class)
00054 
00055         Everything is written in Network order (big endian).
00056 
00057 *******************************************************************************/
00058 
00059 class ProtocolReader : PickleReader
00060 {
00061         /***********************************************************************
00062         
00063                 Construct a ProtocolReader upon the given buffer. As
00064                 Objects are serialized, their content is written to this
00065                 buffer. The buffer content is then typically flushed to 
00066                 some external conduit, such as a file or socket.
00067 
00068                 Note that serialized data is always in Network order.
00069 
00070         ***********************************************************************/
00071         
00072         this (IBuffer buffer)
00073         in {
00074            assert (buffer);
00075            }
00076         body
00077         {
00078                 super (buffer);
00079         }
00080 
00081         /***********************************************************************
00082         
00083                 Return the payload if there was one, null otherwise.
00084 
00085         ***********************************************************************/
00086 
00087         IPayload getPayload (inout char[] channel, inout char[] element, inout ubyte cmd)
00088         {
00089                 int position = buffer.getPosition;
00090 
00091                 ushort size;
00092                 ubyte  versn;
00093 
00094                 get (size);
00095                 get (cmd);
00096                 get (versn);
00097 
00098                 // avoid allocation for these two strings
00099                 get (channel);
00100                 get (element);
00101 
00102                 // is there a payload attached?
00103                 if (size > (buffer.getPosition - position))
00104                     return cast(IPayload) thaw ();
00105 
00106                 return null;
00107         }
00108 
00109         /***********************************************************************
00110         
00111                 Return a duplicated slice of the buffer representing the 
00112                 recieved payload. This is a bit of a hack, but eliminates
00113                 a reasonable amount of overhead. Note that the channel/key
00114                 text is retained right at the start of the buffer, allowing
00115                 the writer to toss the whole thing back without any further
00116                 munging. 
00117 
00118         ***********************************************************************/
00119 
00120         ClusterContent getPacket (inout char[] channel, inout char[] element, inout ubyte cmd)
00121         {
00122                 ushort  size;
00123                 ubyte   versn;
00124 
00125                 // load up the length first.
00126                 get (size);
00127                 //printf ("size: %d\n", cast(int) size);
00128 
00129                 // read the header 
00130                 get (cmd);
00131 
00132                 // read the version stamp
00133                 get (versn);
00134 
00135                 // subtract header size
00136                 size -= buffer.getPosition;
00137                 
00138                 if (buffer.get (size, false) is null)
00139                     throw new IOException ("payload too large to fit within buffer");
00140 
00141                 // duplicate the remaining packet (with channel/key text)
00142                 ClusterContent content = cast(ClusterContent) buffer.toString().dup;
00143 
00144                 // get a slice upon the channel name. Note this is 
00145                 // dup'd as part of the payload
00146                 get (channel);
00147 
00148                 // get a slice upon the element name. Note this is 
00149                 // dup'd as part of the payload
00150                 get (element);
00151 
00152                 // return the dup'd payload (including channel/key text)
00153                 return content;
00154         }
00155 }
00156 

Generated on Sun Nov 7 19:06:52 2004 for Mango by doxygen 1.3.6