/* C++ interface to the XDR External Data Representation I/O routines
Version 1.47
Copyright (C) 1999-2025 John C. Bowman and Supakorn "Jamie" Rassameemasmuang
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#pragma once
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstdlib>
#if defined(_WIN32)
#include <fmem.h>
#include "win32xdr.h"
typedef __int64 OffsetType;
#define fseeko _fseeki64
#define ftello _ftelli64
#else
#ifndef _ALL_SOURCE
#define _ALL_SOURCE 1
#endif
#include <cstdio>
#include <vector>
#include <algorithm>
#include <sys/types.h>
#include <rpc/types.h>
typedef off_t OffsetType;
#ifdef __APPLE__
#include <rpc/xdr.h>
inline bool_t xdr_long(XDR* __xdrs, long* __lp) {
return xdr_longlong_t(__xdrs, (long long*)__lp);
}
inline bool_t xdr_u_long(XDR* __xdrs, unsigned long* __lp) {
return xdr_u_longlong_t(__xdrs, (unsigned long long*) __lp);
}
#endif
#if defined(__FreeBSD__)
#include <sys/select.h>
extern "C" int fseeko(FILE*, OffsetType, int);
extern "C" OffsetType ftello(FILE*);
extern "C" FILE * open_memstream(char**, size_t*);
#endif
#ifdef _POSIX_SOURCE
#undef _POSIX_SOURCE
#include <rpc/rpc.h>
#define _POSIX_SOURCE
#else
#include <rpc/rpc.h>
#endif
#endif
namespace xdr {
class xbyte {
unsigned char c;
public:
xbyte();
xbyte(unsigned char c0);
xbyte(int c0);
xbyte(unsigned int c0);
int byte() const;
operator unsigned char () const;
};
class xios {
public:
enum io_state {goodbit=0, eofbit=1, failbit=2, badbit=4};
enum open_mode {in=1, out=2, app=8, trunc=16};
enum seekdir {beg=SEEK_SET, cur=SEEK_CUR, end=SEEK_END};
private:
int _state;
public:
int good() const;
int eof() const;
int fail() const;
int bad() const;
void clear(int state = 0);
void set(int flag);
operator void*() const;
int operator!() const;
};
class xstream : public xios {
protected:
FILE *buf;
public:
virtual ~xstream();
xstream();
void precision(int);
xstream& seek(OffsetType pos, seekdir dir=beg);
OffsetType tell();
};
#define IXSTREAM(T,N) ixstream& operator >> (T& x) \
{if(!xdr_##N(&xdri, &x)) set(eofbit); return *this;}
#define OXSTREAM(T,N) oxstream& operator << (T x) \
{if(!xdr_##N(&xdro, &x)) set(badbit); return *this;}
class ixstream : virtual public xstream {
private:
bool singleprecision;
protected:
XDR xdri;
public:
ixstream(bool singleprecision=false);
virtual void open(const char *filename, open_mode=in);
virtual void close();
void closeFile();
ixstream(const char *filename, bool singleprecision=false);
ixstream(const char *filename, open_mode mode, bool singleprecision=false);
virtual ~ixstream();
typedef ixstream& (*imanip)(ixstream&);
ixstream& operator >> (imanip func);
IXSTREAM(int16_t,int16_t);
IXSTREAM(uint16_t,u_int16_t);
IXSTREAM(int32_t,int32_t);
IXSTREAM(uint32_t,u_int32_t);
IXSTREAM(int64_t,int64_t);
IXSTREAM(uint64_t,u_int64_t);
#ifdef __APPLE__
IXSTREAM(long,long);
IXSTREAM(unsigned long,u_long);
#endif
IXSTREAM(char,char);
#ifndef _CRAY
IXSTREAM(unsigned char,u_char);
#endif
IXSTREAM(float,float);
ixstream& operator >> (double& x);
ixstream& operator >> (xbyte& x);
};
class oxstream : virtual public xstream {
private:
bool singleprecision;
protected:
XDR xdro;
public:
oxstream(bool singleprecision=false);
virtual void open(const char *filename, open_mode mode=trunc);
virtual void close();
void closefile();
oxstream(const char *filename, bool singleprecision=false);
oxstream(const char *filename, open_mode mode, bool singleprecision=false);
virtual ~oxstream();
oxstream& flush();
typedef oxstream& (*omanip)(oxstream&);
oxstream& operator << (omanip func);
OXSTREAM(int16_t,int16_t);
OXSTREAM(uint16_t,u_int16_t);
OXSTREAM(int32_t,int32_t);
OXSTREAM(uint32_t,u_int32_t);
OXSTREAM(int64_t,int64_t);
OXSTREAM(uint64_t,u_int64_t);
#ifdef __APPLE__
OXSTREAM(long,long);
OXSTREAM(unsigned long,u_long);
#endif
OXSTREAM(char,char);
#ifndef _CRAY
OXSTREAM(unsigned char,u_char);
#endif
OXSTREAM(float,float);
oxstream& operator << (double x);
oxstream& operator << (xbyte x);
};
class memoxstream : public oxstream
{
private:
#if defined(_WIN32)
fmem fmInstance;
#else
char* buffer=nullptr;
size_t size=0;
#endif
public:
memoxstream(bool singleprecision=false);
~memoxstream() override;
std::vector<uint8_t> createCopyOfCurrentData();
};
class memixstream: public ixstream
{
public:
memixstream(char* data, size_t length, bool singleprecision=false);
explicit memixstream(std::vector<char>& data, bool singleprecision=false);
~memixstream() override;
void close() override;
void open(const char *filename, open_mode = in) override;
};
class ioxstream : public ixstream, public oxstream {
public:
void open(const char *filename, open_mode mode=out) override;
void close() override;
ioxstream();
ioxstream(const char *filename);
ioxstream(const char *filename, open_mode mode);
~ioxstream() override;
};
oxstream& endl(oxstream& s);
oxstream& flush(oxstream& s);
}