12 #ifndef _RD_STREAMOPS_H
13 #define _RD_STREAMOPS_H
21 #include <boost/cstdint.hpp>
22 #include <boost/predef.h>
30 #if defined(BOOST_ENDIAN_LITTLE_BYTE) || defined(BOOST_ENDIAN_LITTLE_WORD)
32 #elif defined(BOOST_ENDIAN_BIG_BYTE)
34 #elif defined(BOOST_ENDIAN_BIG_WORD)
35 #error "Cannot compile on word-swapped big-endian systems"
37 #error "Failed to determine the system endian value"
43 template <
class T,
unsigned int size>
45 if (size < 2)
return value;
54 for (
unsigned int i = 0; i < size; ++i) {
55 out.bytes[i] = in.bytes[size - 1 - i];
69 template <EEndian from, EEndian to,
class T>
72 BOOST_STATIC_ASSERT(
sizeof(T) == 1 ||
sizeof(T) == 2 ||
sizeof(T) == 4 ||
74 if (
sizeof(T) == 1)
return value;
80 if (from == to)
return value;
82 return SwapBytes<T, sizeof(T)>(value);
84 template <EEndian from, EEndian to>
88 template <EEndian from, EEndian to>
92 template <EEndian from, EEndian to>
100 boost::uint32_t num) {
102 unsigned int val, res;
107 if (res < (1 << 7)) {
113 if (res < (1 << 14)) {
114 val = ((res << 2) | 1);
119 if (res < (1 << 21)) {
120 val = ((res << 3) | 3);
125 if (res < (1 << 29)) {
126 val = ((res << 3) | 7);
135 for (bix = 0; bix < nbytes; bix++) {
136 tc = (char)(val & 255);
144 boost::uint32_t val, num;
147 ss.read(&tmp,
sizeof(tmp));
150 if ((val & 1) == 0) {
152 }
else if ((val & 3) == 1) {
153 ss.read((
char *)&tmp,
sizeof(tmp));
154 val |= (
UCHAR(tmp) << 8);
157 }
else if ((val & 7) == 3) {
158 ss.read((
char *)&tmp,
sizeof(tmp));
159 val |= (
UCHAR(tmp) << 8);
160 ss.read((
char *)&tmp,
sizeof(tmp));
161 val |= (
UCHAR(tmp) << 16);
163 offset = (1 << 7) + (1 << 14);
165 ss.read((
char *)&tmp,
sizeof(tmp));
166 val |= (
UCHAR(tmp) << 8);
167 ss.read((
char *)&tmp,
sizeof(tmp));
168 val |= (
UCHAR(tmp) << 16);
169 ss.read((
char *)&tmp,
sizeof(tmp));
170 val |= (
UCHAR(tmp) << 24);
172 offset = (1 << 7) + (1 << 14) + (1 << 21);
174 num = (val >> shift) + offset;
182 boost::uint32_t val, num;
189 if ((val & 1) == 0) {
191 }
else if ((val & 3) == 1) {
194 val |= (
UCHAR(tmp) << 8);
197 }
else if ((val & 7) == 3) {
200 val |= (
UCHAR(tmp) << 8);
203 val |= (
UCHAR(tmp) << 16);
205 offset = (1 << 7) + (1 << 14);
209 val |= (
UCHAR(tmp) << 8);
212 val |= (
UCHAR(tmp) << 16);
215 val |= (
UCHAR(tmp) << 24);
217 offset = (1 << 7) + (1 << 14) + (1 << 21);
219 num = (val >> shift) + offset;
225 template <
typename T>
227 T tval = EndianSwapBytes<HOST_ENDIAN_ORDER, LITTLE_ENDIAN_ORDER>(val);
228 ss.write((
const char *)&tval,
sizeof(T));
232 inline void streamWrite(std::ostream &ss,
const std::string &what) {
233 unsigned int l = rdcast<unsigned int>(what.length());
234 ss.write((
const char *)&l,
sizeof(l));
235 ss.write(what.c_str(),
sizeof(
char) * l);
238 template <
typename T>
240 streamWrite(ss,
static_cast<boost::uint64_t
>(val.size()));
241 for (
size_t i = 0; i < val.size(); ++i)
streamWrite(ss, val[i]);
245 template <
typename T>
248 ss.read((
char *)&tloc,
sizeof(T));
249 loc = EndianSwapBytes<LITTLE_ENDIAN_ORDER, HOST_ENDIAN_ORDER>(tloc);
259 inline void streamRead(std::istream &ss, std::string &what,
int version) {
262 ss.read((
char *)&l,
sizeof(l));
263 char *buff =
new char[l];
264 ss.read(buff,
sizeof(
char) * l);
265 what = std::string(buff, 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) {
326 virtual bool read(std::istream &ss,
RDValue &value)
const = 0;
327 virtual bool write(std::ostream &ss,
const RDValue &value)
const = 0;
331 typedef std::vector<std::shared_ptr<const CustomPropHandler>>
351 for (
auto &handler : handlers) {
352 if (handler->canSerialize(pair.
val)) {
416 for (
auto &handler : handlers) {
417 if (handler->canSerialize(pair.
val)) {
423 streamWrite(ss, std::string(handler->getPropName()));
424 handler->write(ss, pair.
val);
435 bool savePrivate =
false,
436 bool saveComputed =
false,
439 std::set<std::string> propnames(propsToSave.begin(), propsToSave.end());
441 const Dict &dict = props.
getDict();
442 unsigned int count = 0;
443 for (Dict::DataType::const_iterator it = dict.getData().begin();
444 it != dict.getData().end(); ++it) {
445 if (propnames.find(it->key) != propnames.end()) {
454 unsigned int writtenCount = 0;
455 for (Dict::DataType::const_iterator it = dict.getData().begin();
456 it != dict.getData().end(); ++it) {
457 if (propnames.find(it->key) != propnames.end()) {
468 "Estimated property count not equal to written");
494 std::vector<std::string> v;
510 readRDValue<int>(ss, pair.
val);
513 readRDValue<unsigned int>(ss, pair.
val);
516 readRDValue<bool>(ss, pair.
val);
519 readRDValue<float>(ss, pair.
val);
522 readRDValue<double>(ss, pair.
val);
527 dictHasNonPOD =
true;
531 dictHasNonPOD =
true;
534 readRDVecValue<int>(ss, pair.
val);
535 dictHasNonPOD =
true;
538 readRDVecValue<unsigned int>(ss, pair.
val);
539 dictHasNonPOD =
true;
542 readRDVecValue<float>(ss, pair.
val);
543 dictHasNonPOD =
true;
546 readRDVecValue<double>(ss, pair.
val);
547 dictHasNonPOD =
true;
550 std::string propType;
553 for (
auto &handler : handlers) {
554 if (propType == handler->getPropName()) {
555 handler->read(ss, pair.
val);
556 dictHasNonPOD =
true;
576 dict.getData().resize(count);
577 for (
unsigned index = 0; index < count; ++index) {
579 dict.getNonPODStatus(), handlers),
580 "Corrupted property serialization detected");