Mercurial > projects > ldc
diff tango/tango/net/cluster/tina/ProtocolReader.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/tango/net/cluster/tina/ProtocolReader.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,157 @@ +/******************************************************************************* + + copyright: Copyright (c) 2004 Kris Bell. All rights reserved + + license: BSD style: $(LICENSE) + + version: July 2004: Initial release + + author: Kris + +*******************************************************************************/ + +module tango.net.cluster.tina.ProtocolReader; + +private import tango.io.protocol.Reader, + tango.io.protocol.Allocator, + tango.io.protocol.PickleProtocol; + +private import tango.net.cluster.model.IMessage; + +private import tango.net.cluster.NetworkRegistry; + +private import tango.net.cluster.tina.ClusterTypes; + +/******************************************************************************* + + Objects passed around a cluster are prefixed with a header, so the + receiver can pick them apart correctly. This header consists of: + --- + * the packet size, including the header (16 bits) + * a command code (8 bits) + * a version id (8 bits) + * a timestamp (64 bits) + * length of the channel name (32 bits) + * the channel name + * length of the key (32 bits) + * the key + * an optional payload (an IMessage instance) + --- + + Everything is written in Network order (big endian). + +*******************************************************************************/ + +class ProtocolReader : Reader +{ + /*********************************************************************** + + Construct a ProtocolReader upon the given buffer. As + Objects are serialized their content is written to this + buffer. The buffer content is then typically flushed to + some external conduit, such as a file or socket. + + Note that arrays (such as text) are *always* sliced from + the buffer -- there's no heap activity involved. Thus it + may be necessary to .dup content where appropriate + + ***********************************************************************/ + + this (IBuffer buffer) + { + super (new BufferSlice (new PickleProtocol (buffer))); + } + + /*********************************************************************** + + deserialize a payload into a provided host, or via + the registered instance of the incoming payload + + ***********************************************************************/ + + IMessage thaw (IMessage host = null) + { + return thaw (NetworkRegistry.shared, host); + } + + /*********************************************************************** + + deserialize a payload into a provided host, or via + the registered instance of the incoming payload + + ***********************************************************************/ + + IMessage thaw (NetworkRegistry registry, IMessage host = null) + { + return registry.thaw (this, host); + } + + /*********************************************************************** + + Read the protocol header and return true if there's a + payload available + + ***********************************************************************/ + + bool getHeader (inout ubyte cmd, inout char[] channel, inout char[] element) + { + auto position = buffer.position; + + long time; + ushort size; + ubyte versn; + + get (size) (cmd) (versn) (time); + + // avoid allocation for these two strings + get (channel) (element); + + // is there a payload attached? + if (size > (buffer.position - position)) + return true; + + return false; + } + + /*********************************************************************** + + Return an aliased slice of the buffer representing the + recieved payload. This is a bit of a hack, but eliminates + a reasonable amount of overhead. Note that the channel/key + text is retained right at the start of the returned content, + enabling the host to toss the whole thing back without any + further munging. + + ***********************************************************************/ + + ClusterContent getPacket (inout ubyte cmd, inout char[] channel, inout char[] element, inout long time) + { + ushort size; + ubyte versn; + + // load up the header + get (size) (cmd) (versn) (time); + + //printf ("size: %d\n", cast(int) size); + + // subtract header size + size -= buffer.position; + + // may throw an exception if the payload is too large to fit + // completely inside the buffer! + buffer.slice (size, false); + + // slice the remaining packet (with channel/key text) + auto content = cast(ClusterContent) buffer.slice; + + // get a slice upon the channel name + get (channel); + + // get a slice upon the element name + get (element); + + // return the aliased payload (including channel/key text) + return content; + } +} +