Listing 1: The header (XIOStream.h) and the implementation file (XIOStream.cpp) for a set of concrete XDR_Stream classes

/***************************************************************
  File: XIOStream.h
  Copyright (c) 1999 Bleading Edge Software Technologies, Inc.

  This Software is distributed under the open source, free 
  software model. Permission to use, modify, and distribute 
  this Software, including incorporating it into proprietary 
  software, is granted without fee, provided this copyright 
  notice appear in all copies of the code. You are under no 
  obligation to distribute source code which is derived from
  or uses this Software. You may not do anything however, to
  prevent the continued distribution of this Software under an
  open source distribution model. This includes, but is not 
  limited to, such things as copyrighting or claiming 
  authorship of the Software. This Software is distributed in 
  the hope that it will be useful, but it is provide "as is", 
  WITHOUT ANY WARRANTY; without even the implied warranty
  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

//$-------------------------------------------------------------
$Header: $
  Author: Jack W. Reeves

//!------------------------------------------------------------|
Description:

//#------------------------------------------------------------|
Notes:

//%************************************************************/
#ifndef UTIL_XIO_STREAM_H
#define UTIL_XIO_STREAM_H

#include <platform.h>

#include "XDRStream.h"

namespace Util {

class XIOStreambuf : public
XDR_Streambuf {
   // typedefs
   typedef XDR_Streambuf                 inherited;
   typedef std::char_traits<XDR_Char>    traits;
   typedef inherited::int_type           int_type;
   typedef traits::pos_type              pos_type;
   typedef traits::off_type              off_type;
   typedef std::streamsize               streamsize;

   // data
   std::streambuf*    _sb;
   char_type          _ibuf[128]; // so we can make 
                                  // underflow / uflow 
                                  // work properly
   char_type          _obuf[128]; // just to make things  
                                  // more efficient

public:
   XIOStreambuf(std::streambuf* sb);
   virtual ~XIOStreambuf();

   std::streambuf*    rdbuf()   const    { return _sb; }

protected:
   virtual inherited* setbuf(char* s, streamsize n);
   virtual pos_type   seekoff(off_type off, 
      std::ios_base::seekdir dir,
      std::ios_base::openmode which =
      std::ios_base::in | std::ios_base::out);
   virtual pos_type   seekpos(pos_type pos,
      std::ios_base::openmode which =
      std::ios_base::in | std::ios_base::out);
   virtual int        sync();

   virtual int_type   underflow();

   virtual int_type   overflow(int_type c = traits::eof());
};

class iXIOStream : public
iXDR_Stream {
   // data
   XIOStreambuf       _xsb;

public:
   iXIOStream(std::streambuf* sb);
   virtual ~iXIOStream();

private:
   iXIOStream(const iXIOStream&);
   iXIOStream& operator=(const iXIOStream&);
};



class oXIOStream : public
oXDR_Stream {
   // data
   XIOStreambuf       _xsb;

public:
   oXIOStream(std::streambuf* sb);
   virtual ~oXIOStream();

private:
   oXIOStream(const oXIOStream&);
   oXIOStream& operator=(const oXIOStream&);
};


class XIOStream : public XDR_Stream
{
   // data
   XIOStreambuf       _xsb;

public:
   XIOStream(std::streambuf* sb);
   virtual ~XIOStream();

private:
   XIOStream(const XIOStream&);
   XIOStream& operator=(const XIOStream&);
};

} //> namespace Util

#endif


/**************************************************************
  File: XIOStream.cpp
  Copyright (c) 1999 Bleading Edge Software Technologies, Inc.

  This Software is distributed under the open source, free 
  software model. Permission to use, modify, and distribute 
  this Software, including incorporating it into proprietary 
  software, is granted without fee, provided this copyright 
  notice appear in all copies of the code. You are under no 
  obligation to distribute source code which is derived from
  or uses this Software. You may not do anything however, to 
  prevent the continued distribution of this Software under 
  an open source distribution model. This includes, but is 
  not limited to, such things as copyrighting or claiming 
  authorship of the Software. This Software is distributed in
  the hope that it will be useful, but it is provide "as is",
  WITHOUT ANY WARRANTY; without even the implied warranty
  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

//$------------------------------------------------------------
$Header: $
  Author: Jack W. Reeves

//!-----------------------------------------------------------|
Description:

//#-----------------------------------------------------------|
Notes:

//%***********************************************************/
#include "XIOStream.h"

namespace Util {

XIOStreambuf::XIOStreambuf(std::streambuf* sb)
  : _sb(sb)
{
   // set up the put buffer, the get buffer is empty
   setp(_obuf, _obuf + sizeof(_obuf) / sizeof(char_type));
}


XIOStreambuf::~XIOStreambuf()
{
   // empty
}


XIOStreambuf::inherited*
XIOStreambuf::setbuf(char* s, streamsize n)
{
   // do nothing
   return this;
}


XIOStreambuf::pos_type
XIOStreambuf::seekoff(off_type off, 
   std::ios_base::seekdir dir, 
   std::ios_base::openmode which)
{
   // clear the get area
   setg(null, null, null);

   // adjust the offset by the size of an XDR_Char
   // (which better be 4)
   return _sb->pubseekoff
      ((off * sizeof(char_type)), dir, which) / sizeof(char_type);
}


XIOStreambuf::pos_type
XIOStreambuf::seekpos(pos_type pos,
std::ios_base::openmode which)
{
   // clear the get area
   setg(null, null, null);

   // adjust the position by the size of an XDR_Char.
   return _sb->pubseekpos((pos * sizeof(char_type)), which) / 
      sizeof(char_type);
}


int
XIOStreambuf::sync()
{
   // write any output to the controled sequence
   streamsize n = pptr() - pbase();
   if (n > 0) {
      streamsize x = _sb->sputn
         (reinterpret_cast<char*>(_obuf), 
         (n * sizeof(char_type)));
      if (x < 0 or size_t(x) != 
         (n * sizeof(char_type))) return -1;
      pbump(-n);
   }
   return _sb->pubsync();
}


XIOStreambuf::int_type
XIOStreambuf::underflow()
{
   // read some characters into the get buffer
   streamsize x = _sb->sgetn(reinterpret_cast<char*>(_ibuf),
      sizeof(_ibuf));
   if (x == 0) return traits_type::eof();

   // set up the get area
   setg(_ibuf, _ibuf, _ibuf + (x / sizeof(char_type)));
   return traits_type::to_int_type(*_ibuf);
}


XIOStreambuf::int_type
XIOStreambuf::overflow(int_type c)
{
   // write the buffer
   sync();

   // put the new character in the buffer
   *_obuf = traits_type::to_char_type(c);
   pbump(1);
   return traits_type::not_eof(c);
}


//
// xiostreams
//
iXIOStream::iXIOStream(std::streambuf* sb)
  : _xsb(sb)
{
   init(&_xsb);
}

iXIOStream::~iXIOStream()
{
   // empty
}


oXIOStream::oXIOStream(std::streambuf* sb)
  : _xsb(sb)
{
   init(&_xsb);
}

oXIOStream::~oXIOStream()
{
   // empty
}


XIOStream::XIOStream(std::streambuf* sb)
  : _xsb(sb)
{
   init(&_xsb);
}


XIOStream::~XIOStream()
{
   // empty
}

} //> namespace Util