Listing 1: A stream to help compose a packet
class SegmentOutStream
{
LAPOut& out_link;
CRC16 crc;
void write_byte(const unsigned char a_byte)
{ out_link.write_byte(a_byte); crc << a_byte; }
public:
SegmentOutStream(LAPOut& _out_link);
~SegmentOutStream(void); // write the CRC and flush the packet
SegmentOutStream& operator << (const unsigned char a_byte)
{ write_byte(a_byte); return *this; }
SegmentOutStream& operator << (const unsigned short a_short);
SegmentOutStream& operator << (const unsigned long a_long);
SegmentOutStream& operator << (const SegmentHeader& seg_header);
// Write an array of bytes
// Array: a representation for an array. Note, for safety an Array object
// cannot be constructed explicitly, either on stack or on heap.
// An Array object can only be constructed via a friend function
// byte_array, and is always transient.
class Array
{
friend SegmentOutStream;
friend SegmentInStream;
const char * const ptr;
const unsigned long size;
// private constructor
Array(const char * byte_array, const unsigned long _size)
: ptr(byte_array), size(_size) {}
Array& operator = (const Array&); // unimplemented and forbidden
Array(const Array&); // unimplemented and forbidden
public:
friend inline Array byte_array(const char * ptr,
const unsigned long size)
{ return Array(ptr,size); }
};
SegmentOutStream& operator << (const Array& array);
};
// A stream to help de-compose a packet
// When the stream is fully constructed, it contains
// the complete packet, with CRC and other checks performed
class SegmentInStream
{
// The buffer where the packet is received to
// Two ptrs in buffer for the current reading
// and writing position
unsigned char buffer[Segment0::max_MTU+1];
const unsigned char * read_ptr;
unsigned char * write_ptr;
CRC16 curr_crc; // CRC accumulated while the packet is being received
// The packet header is being read as a part
// of the receiving process
SegmentHeader header;
// Take the current byte from the buffer
unsigned char take_byte(void)
{ assert( write_ptr > read_ptr ); return *read_ptr++; }
// Receive a byte from the link and into the
// buffer
void receive_byte(LAPIn& in_link);
public:
// Receive a packet. It throws up if there was
// an input error
SegmentInStream(LAPIn& in_link);
const SegmentHeader& q_header(void) const { return header; }
SegmentInStream& operator >> (unsigned char& a_byte)
{ a_byte = take_byte(); return *this; }
SegmentInStream& operator >> (unsigned short& a_short);
SegmentInStream& operator >> (unsigned long& a_long);
SegmentInStream& operator >>
(const SegmentOutStream::Array& array);
void write(FILE * fp); // Dump the rest if the stream into a file
};
//End of File