Listing 1

/*****************************************************************
  File: XdrStream.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: /osahome/Amber/RWE/libprjs/util/String_stream.h,
v 1.2 2001/01/31 15:12:19 jreeves Exp $
  Author: Jack W. Reeves

//!---------------------------------------------------------------|

Description:
  XDR_Stream is an iostream that reads and writes XDR.

//#---------------------------------------------------------------|

Notes:

//****************************************************************/
#ifndef UTIL_XDR_STREAM_H
#define UTIL_XDR_STREAM_H

#include <iostream>
#include <string>
#include <vector>

namespace Util {

   struct XDR_Char {
      // data
      unsigned char _data[4];

      // operations
      void swap_bytes();
      void pad(int);
   }; 

} //> namespace Util


namespace std {
struct char_traits<Util::XDR_Char> {
   typedef Util::XDR_Char   char_type;
   typedef long             int_type;
   typedef streamoff        off_type;
   typedef streampos        pos_type;
   typedef mbstate_t        state_type;

   static void assign(char_type& c1, const char_type& c2);
   static bool eq(const char_type& c1, const char_type& c2);
   static bool lt(const char_type& c1, const char_type& c2);

   static int compare(const char_type* s1, const char_type* s2);
   static size_t length(const char_type* s1);
   static const char_type* find(const char_type* s, size_t n,
      const char_type& a);
   
   static char_type* move(char_type* s1, const char_type* s2, 
      size_t n);
   static char_type* copy(char_type* s1, const char_type* s2, 
      size_t n);
   static char_type* assign(char_type* s, size_t n, char_type a);

   static int_type not_eof(const int_type& c);
   static char_type to_char_type(const int_type& c);
   static int_type to_int_type(const char_type& c);
   static bool eq_int_type(const int_type& c1, 
      const int_type& c2);
   static int_type eof();
};

} //> namespace

namespace Util {

   typedef std::basic_streambuf<XDR_Char>   XDR_Streambuf;

   // input streams
   class iXDR_Stream : virtual public std::basic_ios<XDR_Char> {
   public:
      // Types inherited from basic_ios
      typedef XDR_Char                   char_type;
      typedef std::char_traits<XDR_Char>   traits_type;
      typedef traits_type::int_type      int_type;
      typedef traits_type::pos_type      pos_type;
      typedef traits_type::off_type      off_type;

      // constructor / destructor
      explicit iXDR_Stream(XDR_Streambuf* sb);
      virtual ~iXDR_Stream();

      // prefix / suffix
      class sentry;

      // standard manipulators
      iXDR_Stream& operator>>
         (iXDR_Stream& (*pf)(iXDR_Stream&));
      iXDR_Stream& operator>>
         (std::basic_ios<XDR_Char>& (*pf)
         (std::basic_ios<XDR_Char>&));
      iXDR_Stream& operator>>
         (std::ios_base& (*pf)(std::ios_base&));

      // encoded input
      iXDR_Stream& operator>>(bool& n);
      iXDR_Stream& operator>>(char& n);
      iXDR_Stream& operator>>(signed char& n);
      iXDR_Stream& operator>>(unsigned char& n);
      iXDR_Stream& operator>>(short& n);
      iXDR_Stream& operator>>(unsigned short& n);
      iXDR_Stream& operator>>(int& n);
      iXDR_Stream& operator>>(unsigned int& n);
      iXDR_Stream& operator>>(long& n);
      iXDR_Stream& operator>>(unsigned long& n);
      iXDR_Stream& operator>>(float& f);
      iXDR_Stream& operator>>(double& f);
      iXDR_Stream& operator>>(long double& f);

      // copy
      iXDR_Stream& operator>>(XDR_Streambuf* sb);

      // opaque data extractors
      size_t      get(void* d, size_t l);
      size_t       vget(void* d, size_t l);
      size_t       vget(std::vector<unsigned char>& d);

      // array extractors
      template<typename T>
      size_t       get_arr(T* a, size_t l);
      template<typename T>
      size_t       vget_arr(T* a, size_t l);
      template<typename T>
      size_t       vget_arr(std::vector<T>& v);

      // unformated input
      std::streamsize   gcount() const;

      int_type    get();
      iXDR_Stream& get(char_type& c); 
      iXDR_Stream& get(XDR_Streambuf&
         sb, std::streamsize n);

      iXDR_Stream& ignore(std::streamsize n = 1, 
         int_type delim = traits_type::eof());
      int_type    peek();

      iXDR_Stream& read(char_type* s, std::streamsize n);
      std::streamsize   readsome(char_type* s, 
         std::streamsize n);

      iXDR_Stream& putback(char_type c);
      iXDR_Stream& unget();
      int    sync();

      pos_type   tellg();
      iXDR_Stream& seekg(pos_type); 
      iXDR_Stream& seekg(off_type, std::ios_base::seekdir);
   };

   // string extractors
   iXDR_Stream& operator>>
      (iXDR_Stream&, char* s);
   iXDR_Stream& operator>>
      (iXDR_Stream&, signed char* s);
   iXDR_Stream& operator>>
      (iXDR_Stream&, unsigned char* s);

   iXDR_Stream& operator>>
      (iXDR_Stream&, std::string& str);

   // input stream sentry class
   class iXDR_Stream::sentry {
      bool   _ok;
   public:
      explicit sentry(iXDR_Stream& is);
      ~sentry();
      operator bool() const   { return _ok; }
   };


   // output streams
   class oXDR_Stream : virtual public std::basic_ios<XDR_Char> {
   public: 
      // Types inherited from basic_ios
      typedef XDR_Char                char_type;
      typedef std::char_traits<XDR_Char>   traits_type;
      typedef traits_type::int_type   int_type;
      typedef traits_type::pos_type   pos_type;
      typedef traits_type::off_type   off_type;

      // constructor / destructor
      explicit oXDR_Stream(XDR_Streambuf* sb);
      virtual ~oXDR_Stream();

      // prefix / suffix
      class sentry;

      // standard manipulators
      oXDR_Stream& operator<<
         (oXDR_Stream& (*pf)(oXDR_Stream&));
      oXDR_Stream& operator<<
         (std::basic_ios<XDR_Char>& (*pf)
         (std::basic_ios<XDR_Char>&));
      oXDR_Stream& operator<<
         (std::ios_base& (*pf)(std::ios_base&));

      // encoded output
      oXDR_Stream& operator<<(bool n);
      oXDR_Stream& operator<<(char n);
      oXDR_Stream& operator<<(signed char n);
      oXDR_Stream& operator<<(unsigned char n);
      oXDR_Stream& operator<<(short n);
      oXDR_Stream& operator<<(unsigned short n);
      oXDR_Stream& operator<<(int n);
      oXDR_Stream& operator<<(unsigned int n);
      oXDR_Stream& operator<<(long n);
      oXDR_Stream& operator<<(unsigned long n);
      oXDR_Stream& operator<<(float f);
      oXDR_Stream& operator<<(double f);
      oXDR_Stream& operator<<(long double f);

      // copy
      oXDR_Stream& operator<<(XDR_Streambuf* sb);

      // opaque data inserters
      oXDR_Stream& put(const void* d, size_t l);
      oXDR_Stream& vput(const void* d, size_t l);
      oXDR_Stream& vput
         (const std::vector<unsigned char>& d);

      // array inserters
      template<typename T>
      oXDR_Stream& put_arr(const T* a, size_t l);
      template<typename T>
      oXDR_Stream& vput_arr(const T* a, size_t l);
      template<typename T>
      oXDR_Stream& vput_arr
         (const std::vector<T>& v);


      // unformated output
      oXDR_Stream& put(char_type c);
      oXDR_Stream& write(const char_type* s, 
         std::streamsize n);

      oXDR_Stream& flush(); 

      // seeks
      pos_type tellp();
      oXDR_Stream& seekp(pos_type);
      oXDR_Stream& seekp(off_type, ios_base::seekdir);
   };

   // string inserters
   oXDR_Stream& operator<<
      (oXDR_Stream&, const char* s);
   oXDR_Stream& operator<<
      (oXDR_Stream&, const signed char* s);
   oXDR_Stream& operator<<
      (oXDR_Stream&, const unsigned char* s);

   oXDR_Stream& operator<<
      (oXDR_Stream&, const std::string& str);

   // output stream sentry
   class oXDR_Stream::sentry {
      bool   _ok;
   public: 
      explicit sentry(oXDR_Stream& os);
      ~sentry();
      operator bool() const { return _ok; }
   }; 


   // input / output streams
   class XDR_Stream : public iXDR_Stream, public oXDR_Stream {
   public: 
      XDR_Stream(XDR_Streambuf* sb);
      virtual ~XDR_Stream();
   }; 

} //> namespace


#endif