/****************************************************************
File: XDRStream.h
Copyright (c) 1999-2001 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:
XDR_Stream is an iostream that reads and writes XDR.
//#-------------------------------------------------------------|
Notes:
//%*************************************************************/
#ifndef UTIL_XDR_STREAM_H
#define UTIL_XDR_STREAM_H
// configuration info
#include <platform.h>
// Standard C++ headers
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cwchar>
namespace Util {
// uint32_t on all my current platforms
typedef unsigned long XDR_Char;
// We need a traits class for XDR_Char. I could explicitly
// specialize std::char_traits<> but, after doing that
// originally decided against it. In particular, I think
// you want to be careful about adding explicit specializations
// to namespace std. You run a large risk of name conflicts.
struct XDR_Char_Traits {
typedef XDR_Char char_type;
typedef long int_type;
typedef std::streamoff off_type;
typedef std::streampos pos_type;
// not used so removed for now
typedef std::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();
// extra utility functions
static void swap_bytes(char_type& c);
static void pad(char_type& c, int);
};
// The stream buffer class is just a specialization
typedef
std::basic_streambuf<XDR_Char, XDR_Char_Traits> XDR_Streambuf;
// input streams
class iXDR_Stream :
virtual public std::basic_ios<XDR_Char, XDR_Char_Traits>
{
public:
// Types inherited from basic_ios
typedef std::basic_ios<XDR_Char, XDR_Char_Traits> inherited;
typedef XDR_Char char_type;
typedef XDR_Char_Traits traits_type;
typedef traits_type::int_type int_type;
typedef traits_type::pos_type pos_type;
typedef traits_type::off_type off_type;
// Input stream sentry class
class sentry {
bool _ok;
public:
explicit sentry(iXDR_Stream& ixs) : _ok(ixs.good()) {}
~sentry() {}
operator bool() const { return _ok; }
};
// Support for reference semantics
class IdToObjMap {
typedef std::map<long, void*> ObjMap;
ObjMap _objMap;
public:
IdToObjMap();
~IdToObjMap();
void* find(long id);
std::pair<void*, bool> insert(long id,
void* obj);
void*& operator[](long id);
private:
IdToObjMap(const IdToObjMap&);
IdToObjMap& operator=(const IdToObjMap&);
};
class IdToTypeMap {
typedef std::map<long, std::string> TypeMap;
TypeMap _typeMap;
public:
IdToTypeMap();
~IdToTypeMap();
std::string find(long id);
std::pair<std::string,bool> insert
(long id, const std::string& type);
std::string& operator[](long id);
private:
IdToTypeMap(const IdToTypeMap&);
IdToTypeMap& operator=(const IdToTypeMap&);
};
private:
// data
std::streamsize _gcount;
IdToObjMap _id2objMap;
IdToTypeMap _id2typeMap;
public:
// constructor / destructor
explicit iXDR_Stream(XDR_Streambuf* sb);
virtual ~iXDR_Stream();
// standard manipulators
iXDR_Stream& operator>>
(iXDR_Stream& (*pf)(iXDR_Stream&));
iXDR_Stream& operator>>
(inherited& (*pf)(inherited&));
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_opaque(void* d, size_t l);
size_t vget_opaque(void* d, size_t l);
// array extractors
template<typename T>
ptrdiff_t get_array(T* a, ptrdiff_t l);
template<typename T>
ptrdiff_t vget_array(T* a, ptrdiff_t l);
// string extractors
size_t vget_string(char* s, size_t l);
// unformated input
std::streamsize gcount() const { return _gcount; }
int_type get();
iXDR_Stream& get(char_type& c);
iXDR_Stream& read(char_type* s, std::streamsize n);
int sync();
pos_type tellg();
iXDR_Stream& seekg(pos_type);
iXDR_Stream& seekg(off_type, std::ios_base::seekdir);
// Support for reference semantics
IdToObjMap& id2obj() { return _id2objMap; }
IdToTypeMap& id2type() { return _id2typeMap; }
protected:
iXDR_Stream();
};
// opaque data extractors
iXDR_Stream& operator>>
(iXDR_Stream&, std::vector<unsigned char>& data);
// array extractors
template<typename T>
iXDR_Stream& operator>>
(iXDR_Stream&, std::vector<T>& arr);
// 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);
// functions which allocate the data area from the free
// store and return it
// NOTE: clients are responsible for calling delete[] on the
// returned pointer
// NOTE: the 'string' version always null terminates the
// returned string
std::pair<unsigned char*, size_t> vget_opaque
(iXDR_Stream& ixs, size_t max = size_t(-1));
template<typename T> std::pair<T*, ptrdiff_t> vget_array
(iXDR_Stream& ixs, ptrdiff_t max = -1);
std::pair<char*, size_t> vget_string
(iXDR_Stream& ixs, size_t max = size_t(-1));
// optional data
template<typename T> T* get_optional(iXDR_Stream& ixs);
// support for reference semantics
void* get_objId(iXDR_Stream& ixs, long& id);
void map_objId(iXDR_Stream& ixs, long id, void* obj);
// support for polymorphism
std::string get_typeId(iXDR_Stream& ixs, long& id);
void map_typeId(iXDR_Stream& ixs, long id,
const std::string& type);
//
// Output streams
//
class oXDR_Stream :
virtual public std::basic_ios<XDR_Char, XDR_Char_Traits>
{
public:
// Types inherited from basic_ios
typedef std::basic_ios<XDR_Char, XDR_Char_Traits> inherited;
typedef XDR_Char char_type;
typedef XDR_Char_Traits traits_type;
typedef traits_type::int_type int_type;
typedef traits_type::pos_type pos_type;
typedef traits_type::off_type off_type;
// Output stream sentry
class sentry {
bool _ok;
public:
explicit sentry(oXDR_Stream& oxs) : _ok(oxs.good()) {}
~sentry() {}
operator bool() const { return _ok; }
};
// Support for reference semantics
class ObjToIdMap {
typedef std::map<const void*, long> IdMap;
long _id;
IdMap _idMap;
public:
ObjToIdMap();
~ObjToIdMap();
long find(const void* obj);
std::pair<long,bool> insert(const void* obj);
long operator[](const void* obj);
private:
ObjToIdMap(const ObjToIdMap&);
ObjToIdMap& operator=(const ObjToIdMap&);
};
// Support for polymorphism
class TypeToIdMap {
typedef std::map<std::string, long> IdMap;
long _id;
IdMap _idMap;
public:
TypeToIdMap();
~TypeToIdMap();
long find(const std::string& type);
std::pair<long,bool> insert(const std::string& type);
long operator[](const std::string& type);
private:
TypeToIdMap(const TypeToIdMap&);
TypeToIdMap& operator=(const TypeToIdMap&);
};
private:
// data
ObjToIdMap _obj2idMap;
TypeToIdMap _type2idMap;
public:
// 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<<(inherited& (*pf)(inherited&));
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_opaque(const void* d, size_t l);
oXDR_Stream& vput_opaque(const void* d, size_t l);
// array inserters
export template<typename T>
oXDR_Stream& put_array(const T* a, ptrdiff_t l);
export template<typename T>
oXDR_Stream& vput_array(const T* a, ptrdiff_t l);
// string inserters
oXDR_Stream& vput_string(const char* s, size_t l);
// unformated output
oXDR_Stream& put(char_type c);
oXDR_Stream& write(const char_type* s, std::streamsize n);
oXDR_Stream& flush();
pos_type tellp();
oXDR_Stream& seekp(pos_type);
oXDR_Stream& seekp(off_type, ios_base::seekdir);
// Support for reference semantics and polymorphism
ObjToIdMap& obj2id() { return _obj2idMap; }
TypeToIdMap& type2id() { return _type2idMap; }
protected:
oXDR_Stream();
};
// opaque data inserters
oXDR_Stream& operator<<
(oXDR_Stream&, const std::vector<unsigned char>& data);
// array inserters
template<typename T>
oXDR_Stream& operator<<
(oXDR_Stream&, const std::vector<T>& data);
// 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);
// optional data
template<typename T>
oXDR_Stream& put_optional
(oXDR_Stream& oxs, const T* data);
// manipulators
oXDR_Stream& flush(oXDR_Stream&);
// reference objects
bool put_objId
(oXDR_Stream& oxs, const void* obj);
// polymorphic objects
bool put_typeId
(oXDR_Stream& oxs, const std::string& type);
//
// Input / output streams
//
class XDR_Stream :
public iXDR_Stream, public oXDR_Stream {
public:
XDR_Stream(XDR_Streambuf* sb);
virtual ~XDR_Stream();
protected:
XDR_Stream();
};
//
// Inline implemetations
//
//
// XDR_Char_Traits
//
inline void
XDR_Char_Traits::assign
(char_type& c1, const char_type& c2)
{ c1 = c2; }
inline bool
XDR_Char_Traits::eq
(const char_type& c1, const char_type& c2)
{ return c1 == c2; }
inline bool
XDR_Char_Traits::lt
(const char_type& c1, const char_type& c2)
{ return c1 < c2; }
inline XDR_Char_Traits::int_type
XDR_Char_Traits::not_eof(const int_type& c)
{ return (eq_int_type(eof(), c) ? 0 : c); }
inline XDR_Char_Traits::char_type
XDR_Char_Traits::to_char_type(const int_type& c)
{ return c; }
inline XDR_Char_Traits::int_type
XDR_Char_Traits::to_int_type(const char_type& c)
{ return c; }
inline bool
XDR_Char_Traits::eq_int_type
(const int_type& c1, const int_type& c2)
{ return c1 == c2; }
inline XDR_Char_Traits::int_type
XDR_Char_Traits::eof()
{ return -1; }
//
// iXDR_Stream -
// member functions
inline iXDR_Stream&
iXDR_Stream::operator>>
(iXDR_Stream& (*pf)(iXDR_Stream&))
{
pf(*this); return *this;
}
inline iXDR_Stream&
iXDR_Stream::operator>>
(inherited& (*pf)(inherited&))
{
pf(*this); return *this;
}
inline iXDR_Stream&
iXDR_Stream::operator>>
(std::ios_base& (*pf)(std::ios_base&))
{
pf(*this); return *this;
}
// iXDR_Stream -
// non-member functions
inline iXDR_Stream&
operator>>
(iXDR_Stream& xis, signed char* s)
{
return operator>>
(xis, reinterpret_cast<char*>(s));
}
inline iXDR_Stream&
operator>>
(iXDR_Stream& xis, unsigned char* s)
{
return operator>>
(xis, reinterpret_cast<char*>(s));
}
//
// oXDR_Stream -
// member functions
inline oXDR_Stream&
oXDR_Stream::operator<<
(oXDR_Stream& (*pf)(oXDR_Stream&))
{
pf(*this); return *this;
}
inline oXDR_Stream&
oXDR_Stream::operator<<
(inherited& (*pf)(inherited&))
{
pf(*this); return *this;
}
inline oXDR_Stream&
oXDR_Stream::operator<<
(std::ios_base& (*pf)(std::ios_base&))
{
pf(*this); return *this;
}
inline oXDR_Stream&
oXDR_Stream::operator<<(bool n)
{
return operator<<
(static_cast<long>(n ? 1 : 0));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(char n)
{
return operator<<
(static_cast<long>( static_cast<signed char>(n) ));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(signed char n)
{
return operator<<
(static_cast<long>(n));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(unsigned char n)
{
return operator<<
(static_cast<unsigned long>(n));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(short n)
{
return operator<<
(static_cast<long>(n));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(unsigned short n)
{
return operator<<
(static_cast<unsigned long>(n));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(int n)
{
return operator<<
(static_cast<long>(n));
}
inline oXDR_Stream&
oXDR_Stream::operator<<(unsigned int n)
{
return operator<<
(static_cast<unsigned long>(n));
}
//
// oXDR_Stream -
// non-member functions
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs, const std::vector<unsigned char>& d)
{
return oxs.vput_opaque(&d[0], d.size());
}
template<typename T>
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs,
const std::vector<T>& v)
{
return oxs.vput_array(&v[0], v.size());
}
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs, const char* s)
{
return oxs.vput_string(s, ::strlen(s));
}
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs, const signed char* s)
{
return oxs << reinterpret_cast<const char*>(s);
}
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs, const unsigned char* s)
{
return oxs << reinterpret_cast<const char*>(s);
}
inline oXDR_Stream&
operator<<
(oXDR_Stream& oxs, const std::string& str)
{
return oxs.vput_string(str.data(), str.size());
}
//
// oXDR_Stream -
// manipulators
inline oXDR_Stream&
flush(oXDR_Stream& oxs)
{
return oxs.flush();
}
} //> namespace Util
#ifdef EXPORT_NOT_SUPPORTED
#include "XDRStream_reader.hxx"
#include "XDRStream_writer.hxx"
#endif
#endif