12 #ifndef _RD_STREAMOPS_H 13 #define _RD_STREAMOPS_H 21 #include <boost/cstdint.hpp> 22 #include <boost/detail/endian.hpp> 30 #if defined(BOOST_LITTLE_ENDIAN) 32 #elif defined(BOOST_BIG_ENDIAN) 35 #error "Failed to determine the system endian value" 41 template <
class T,
unsigned int size>
53 for (
unsigned int i = 0; i < size; ++i) {
54 out.bytes[i] = in.bytes[size - 1 - i];
68 template <EEndian from, EEndian to,
class T>
71 BOOST_STATIC_ASSERT(
sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
73 if (
sizeof(T) == 1)
return value;
79 if (from == to)
return value;
81 return SwapBytes<T, sizeof(T)>(value);
83 template <EEndian from, EEndian to>
87 template <EEndian from, EEndian to>
91 template <EEndian from, EEndian to>
99 boost::uint32_t num) {
101 unsigned int val, res;
106 if (res < (1 << 7)) {
112 if (res < (1 << 14)) {
113 val = ((res << 2) | 1);
118 if (res < (1 << 21)) {
119 val = ((res << 3) | 3);
124 if (res < (1 << 29)) {
125 val = ((res << 3) | 7);
134 for (bix = 0; bix < nbytes; bix++) {
135 tc = (char)(val & 255);
143 boost::uint32_t val, num;
146 ss.read(&tmp,
sizeof(tmp));
149 if ((val & 1) == 0) {
151 }
else if ((val & 3) == 1) {
152 ss.read((
char *)&tmp,
sizeof(tmp));
153 val |= (
UCHAR(tmp) << 8);
156 }
else if ((val & 7) == 3) {
157 ss.read((
char *)&tmp,
sizeof(tmp));
158 val |= (
UCHAR(tmp) << 8);
159 ss.read((
char *)&tmp,
sizeof(tmp));
160 val |= (
UCHAR(tmp) << 16);
162 offset = (1 << 7) + (1 << 14);
164 ss.read((
char *)&tmp,
sizeof(tmp));
165 val |= (
UCHAR(tmp) << 8);
166 ss.read((
char *)&tmp,
sizeof(tmp));
167 val |= (
UCHAR(tmp) << 16);
168 ss.read((
char *)&tmp,
sizeof(tmp));
169 val |= (
UCHAR(tmp) << 24);
171 offset = (1 << 7) + (1 << 14) + (1 << 21);
173 num = (val >> shift) + offset;
181 boost::uint32_t val, num;
188 if ((val & 1) == 0) {
190 }
else if ((val & 3) == 1) {
193 val |= (
UCHAR(tmp) << 8);
196 }
else if ((val & 7) == 3) {
199 val |= (
UCHAR(tmp) << 8);
202 val |= (
UCHAR(tmp) << 16);
204 offset = (1 << 7) + (1 << 14);
208 val |= (
UCHAR(tmp) << 8);
211 val |= (
UCHAR(tmp) << 16);
214 val |= (
UCHAR(tmp) << 24);
216 offset = (1 << 7) + (1 << 14) + (1 << 21);
218 num = (val >> shift) + offset;
224 template <
typename T>
226 T tval = EndianSwapBytes<HOST_ENDIAN_ORDER, LITTLE_ENDIAN_ORDER>(val);
227 ss.write((
const char *)&tval,
sizeof(T));
231 inline void streamWrite(std::ostream &ss,
const std::string &what) {
232 unsigned int l = rdcast<unsigned int>(what.length());
233 ss.write((
const char *)&l,
sizeof(l));
234 ss.write(what.c_str(),
sizeof(char) * l);
237 template <
typename T>
239 streamWrite(ss, static_cast<boost::uint64_t>(val.size()));
240 for (
size_t i = 0; i < val.size(); ++i)
streamWrite(ss, val[i]);
244 template <
typename T>
247 ss.read((
char *)&tloc,
sizeof(T));
248 loc = EndianSwapBytes<LITTLE_ENDIAN_ORDER, HOST_ENDIAN_ORDER>(tloc);
258 inline void streamRead(std::istream &ss, std::string &what,
int version) {
261 ss.read((
char *)&l,
sizeof(l));
262 char *buff =
new char[l + 1];
263 ss.read(buff,
sizeof(
char) * l);
271 boost::uint64_t size;
275 for (
size_t i = 0; i < size; ++i)
streamRead(ss, val[i]);
280 boost::uint64_t size;
284 for (
size_t i = 0; i < size; ++i)
streamRead(ss, val[i], version);
288 inline std::string
getLine(std::istream *inStream) {
290 std::getline(*inStream, res);
291 if ((res.length() > 0) && (res[res.length() - 1] ==
'\r')) {
292 res.erase(res.length() - 1);
297 inline std::string
getLine(std::istream &inStream) {
391 std::cerr <<
"Failed to write " << pair.
key << std::endl;
398 bool savePrivate=
false,
bool saveComputed=
false) {
400 std::set<std::string> propnames(propsToSave.begin(), propsToSave.end());
403 unsigned int count = 0;
404 for(Dict::DataType::const_iterator it = dict.getData().begin();
405 it != dict.getData().end();
407 if(
isSerializable(*it) && propnames.find(it->key) != propnames.end()) {
414 unsigned int writtenCount = 0;
415 for(Dict::DataType::const_iterator it = dict.getData().begin();
416 it != dict.getData().end();
418 if (propnames.find(it->key) != propnames.end()) {
428 POSTCONDITION(count==writtenCount,
"Estimated property count not equal to written");
454 std::vector<std::string> v;
478 readRDVecValue<int>(ss, pair.
val);
481 readRDVecValue<unsigned int>(ss, pair.
val);
484 readRDVecValue<float>(ss, pair.
val);
487 readRDVecValue<double>(ss, pair.
val);
502 for(
unsigned index = 0; index<count; ++index) {
504 "Corrupted property serialization detected");
#define POSTCONDITION(expr, mess)
static const boost::uint64_t VecDoubleTag
static const boost::uint64_t UnsignedIntTag
T EndianSwapBytes(T value)
#define CHECK_INVARIANT(expr, mess)
const DataType & getData() const
Access to the underlying data.
T rdvalue_cast(RDValue v)
static const boost::uint64_t DoubleTag
double rdvalue_cast< double >(RDValue v)
void streamRead(std::istream &ss, T &loc)
does a binary read of an object from a stream
void readRDValueString(std::istream &ss, RDValue &value)
void readRDValue(std::istream &ss, RDValue &value)
boost::uint32_t readPackedIntFromStream(std::stringstream &ss)
Reads an integer from a stream in packed format and returns the result.
static const boost::uint64_t FloatTag
boost::uint32_t pullPackedIntFromString(const char *&text)
bool streamWriteProps(std::ostream &ss, const RDProps &props, bool savePrivate=false, bool saveComputed=false)
bool rdvalue_cast< bool >(RDValue v)
void streamReadStringVec(std::istream &ss, std::vector< std::string > &val, int version)
static const boost::uint64_t StringTag
void readRDVecValue(std::istream &ss, RDValue &value)
static const boost::uint64_t VecIntTag
static const boost::uint64_t VecUnsignedIntTag
unsigned int rdvalue_cast< unsigned int >(RDValue v)
const Dict & getDict() const
gets the underlying Dictionary
static const boost::uint64_t VecStringTag
bool streamReadProp(std::istream &ss, Dict::Pair &pair)
unsigned int streamReadProps(std::istream &ss, RDProps &props)
void streamWriteVec(std::ostream &ss, const T &val)
#define RDUNUSED_PARAM(x)
float rdvalue_cast< float >(RDValue v)
static const boost::uint64_t IntTag
int rdvalue_cast< int >(RDValue v)
bool isSerializable(const Dict::Pair &pair)
static const boost::uint64_t BoolTag
void streamWrite(std::ostream &ss, const T &val)
does a binary write of an object to a stream
std::string getLine(std::istream *inStream)
grabs the next line from an instream and returns it.
STR_VECT getPropList(bool includePrivate=true, bool includeComputed=true) const
returns a list with the names of our properties
boost::uint64_t getTag() const
static const boost::uint64_t VecFloatTag
void appendPackedIntToStream(std::stringstream &ss, boost::uint32_t num)
Packs an integer and outputs it to a stream.
void readRDStringVecValue(std::istream &ss, RDValue &value)
The Dict class can be used to store objects of arbitrary type keyed by strings.
std::vector< std::string > STR_VECT
void streamReadVec(std::istream &ss, T &val)
bool streamWriteProp(std::ostream &ss, const Dict::Pair &pair)