LOST  0.0.1
LOST: Open-source Star Tracker
serialize-helpers.hpp
Go to the documentation of this file.
1 
17 #ifndef SERIALIZE_HELPERS_H
18 #define SERIALIZE_HELPERS_H
19 
20 #include <string.h>
21 
22 #include <utility>
23 #include <vector>
24 #include <algorithm>
25 
26 #include "decimal.hpp"
27 
28 namespace lost {
29 
31 public:
34  SerializeContext() : SerializeContext(false, false) { }
35 
38  std::vector<unsigned char> buffer;
39 };
40 
42 public:
43  explicit DeserializeContext(const unsigned char *buffer) : buffer(buffer), cursor(buffer) { }
44 
45  size_t GetOffset() const {
46  return cursor - buffer;
47  }
48 
49  void MoveForward(size_t howMuch) {
50  cursor += howMuch;
51  }
52 
53  const unsigned char *GetCursor() {
54  return cursor;
55  }
56 
57 private:
58  const unsigned char *buffer;
59  const unsigned char *cursor;
60 };
61 
63 template <typename T>
64 void SwapEndianness(unsigned char *buffer) {
65  for (int i = 0; i < (int)(sizeof(T)/2); i++) {
66  std::swap(buffer[i], buffer[sizeof(T)-1-i]);
67  }
68 }
69 
73 template <typename T>
74 void SwapEndiannessIfNecessary(unsigned char *buffer, SerializeContext *ser) {
75  if (ser->swapIntegerEndianness) {
76  SwapEndianness<T>(buffer);
77  }
78 }
79 
80 // template specializations
81 
82 template <>
83 inline void SwapEndiannessIfNecessary<decimal>(unsigned char *buffer, SerializeContext *ser) {
84  if (ser->swapDecimalEndianness) {
85  SwapEndianness<decimal>(buffer);
86  }
87 }
88 
90 template <typename T>
92  des->MoveForward((sizeof(T) - des->GetOffset()%sizeof(T))%sizeof(T));
93 }
94 
95 template <typename T>
97  DeserializePadding<T>(des);
98  const T *result = (T *)des->GetCursor(); // endianness should have been taken care of during serialization
99  des->MoveForward(sizeof(T));
100  return *result;
101 }
102 
104 template <typename T>
105 const T *DeserializeArray(DeserializeContext *des, long arrLength) {
106  DeserializePadding<T>(des); // Perhaps we should always 8-align arrays? Does that possibly make
107  // any offset calculation or accesses faster?
108  const T *result = (T *)des->GetCursor();
109  des->MoveForward(sizeof(T)*arrLength);
110  return result;
111 }
112 
113 template <typename T>
115  for (int i = ser->buffer.size(); i%sizeof(T) != 0; i++) {
116  ser->buffer.push_back(0);
117  }
118 }
119 
120 template <typename T>
121 void SerializePrimitive(SerializeContext *ser, const T &val) {
122  unsigned char buf[sizeof(T)];
123  memcpy(&buf, &val, sizeof(T));
124  SwapEndiannessIfNecessary<T>(buf, ser);
125  SerializePadding<T>(ser);
126  std::copy(buf, buf+sizeof(T), std::back_inserter(ser->buffer));
127 }
128 
129 }
130 
131 #endif
DeserializeContext(const unsigned char *buffer)
const unsigned char * GetCursor()
void MoveForward(size_t howMuch)
std::vector< unsigned char > buffer
SerializeContext(bool swapIntegerEndianness, bool swapDecimalEndianness)
LOST starting point.
void SerializePadding(SerializeContext *ser)
void SwapEndiannessIfNecessary< decimal >(unsigned char *buffer, SerializeContext *ser)
T DeserializePrimitive(DeserializeContext *des)
void SwapEndiannessIfNecessary(unsigned char *buffer, SerializeContext *ser)
Swap the endianness of a value if necessary.
void SerializePrimitive(SerializeContext *ser, const T &val)
void SwapEndianness(unsigned char *buffer)
Unconditionally swap the endianness of a value (uses sizeof T).
void DeserializePadding(DeserializeContext *des)
Move the cursor forward past any padding that would appear before a value of type T.
const T * DeserializeArray(DeserializeContext *des, long arrLength)
return an array of items as a pointer. Will point into the buffer (mmap style).