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