Listing 4: The Message class

class Header : public NetObject
{
  unsigned char  type_ ;
  unsigned short body_size_;
  // other members not shown
protected:
  void netWrite(netBuffer &nb) const
  {
    nb << type_ << body_size_;
    // insert other members
  }
  void netRead(netBuffer &nb)
  {
    nb >> type_ >> body_size_;
    // extract other members
  }
public:
  int type() const { return type_; }
  int body_size() const { return body_size_; }
  // other methods not shown;
};

class Attribute : public NetObject
{
  int  id_;
  Buffer data_;

protected:
  void netWrite(NetBuffer &nb)const
  {
     nb << id_ <<  data_.size() << data_;
  }
  void netRead(NetBuffer &nb)
  {
    int len;
    nb >> id_ >> len;
    data_.resize (len);
    nb >> data_;
  }
public:
  Attribute() : id(0) {}
  Attribute(int i, const Buffer &d)
    : id_(i),data_(d) { netClear(); }

  int id() const { return id_; }
  const Buffer & data() const { return data_; }
};

class Message : public NetObject
{
  Header header_;
  Buffer body_;
  NetVector<Attribute> attributes_;
protected:

  void netWrite(NetBuffer &nb)const
  {
   nb << header_ << body_ << attributes_;
  }
  void netRead(NetBuffer &nb)
  {
    nb >> header_ ;
    body_.resize (header_.body_size());
    nb >> body_ >> attributes_;
  }

public:

  Message(const Buffer &buf)
  {
    netRead(NetBuffer(buf));
  }

  Message &operator=(const Buffer &buf)
  {
    netRead(NetBuffer(buf));
    return *this;
  }

  const Header& header() const { return header_; }
  const Buffer& body()   const { return body_;   }
  const NetVector<Attribute> & attributes()
  { return attributes_; }

  Attribute findAttribute(int id);
  // other members not shown
};
— End of Listing —