hobbes
a language, embedded compiler, and runtime for efficient dynamic expression evaluation, data storage and analysis
codec.H
Go to the documentation of this file.
1 
2 #ifndef HOBBES_UTIL_CODEC_HPP_INCLUDED
3 #define HOBBES_UTIL_CODEC_HPP_INCLUDED
4 
5 #include <iostream>
6 #include <vector>
7 #include <map>
8 #include <unistd.h>
9 #include <string.h>
10 
11 namespace hobbes {
12 
13 #define PRIM_CODEC(T) \
14  inline void encode(T x, std::ostream& out) { out.write((const char*)&x, sizeof(x)); } \
15  inline void decode(T* x, std::istream& in) { in.read((char*)x, sizeof(*x)); }
16 
17 PRIM_CODEC(bool);
18 PRIM_CODEC(unsigned char);
19 PRIM_CODEC(char);
20 PRIM_CODEC(short);
21 PRIM_CODEC(int);
22 PRIM_CODEC(long);
23 PRIM_CODEC(size_t);
24 PRIM_CODEC(float);
25 PRIM_CODEC(double);
26 
27 inline void encode(const std::string& x, std::ostream& out) {
28  encode((size_t)x.size(), out);
29  out.write(x.c_str(), x.size());
30 }
31 
32 inline void decode(std::string* x, std::istream& in) {
33  size_t n = 0;
34  decode(&n, in);
35 
36  x->resize(n);
37  in.read(&((*x)[0]), n);
38 }
39 
40 template <typename T>
41  inline void encode(const std::vector<T>& xs, std::ostream& out) {
42  encode((size_t)xs.size(), out);
43  for (typename std::vector<T>::const_iterator x = xs.begin(); x != xs.end(); ++x) {
44  encode(*x, out);
45  }
46  }
47 
48 template <typename T>
49  inline void decode(std::vector<T>* xs, std::istream& in) {
50  size_t sz = 0;
51  decode(&sz, in);
52 
53  for (size_t i = 0; i < sz; ++i) {
54  T x;
55  decode(&x, in);
56  xs->push_back(x);
57  }
58  }
59 
60 template <typename U, typename V>
61  inline void encode(const std::pair<U, V>& p, std::ostream& out) {
62  encode(p.first, out);
63  encode(p.second, out);
64  }
65 
66 template <typename U, typename V>
67  inline void decode(std::pair<U, V>* p, std::istream& in) {
68  decode(&p->first, in);
69  decode(&p->second, in);
70  }
71 
72 template <typename K, typename V>
73  inline void encode(const std::map<K, V>& m, std::ostream& out) {
74  encode(m.size(), out);
75  for (typename std::map<K, V>::const_iterator p = m.begin(); p != m.end(); ++p) {
76  encode(*p, out);
77  }
78  }
79 
80 template <typename K, typename V>
81  inline void decode(std::map<K, V>* m, std::istream& in) {
82  size_t sz = 0;
83  decode(&sz, in);
84 
85  for (size_t i = 0; i < sz; ++i) {
86  std::pair<K, V> p;
87  decode(&p, in);
88 
89  (*m)[p.first] = p.second;
90  }
91  }
92 
93 // shorthand for fd I/O
94 inline void fdread(int fd, char* x, size_t len) {
95  if (len == 0) return;
96 
97  size_t i = 0;
98  do {
99  ssize_t di = read(fd, x + i, len - i);
100 
101  if (di < 0) {
102  if (errno != EINTR) {
103  throw std::runtime_error("Couldn't read pipe: " + std::string(strerror(errno)));
104  }
105  } else if (di == 0) {
106  throw std::runtime_error("Process read error (closed pipe)");
107  } else {
108  i += di;
109  }
110  } while (i < len);
111 }
112 
113 inline void fdread(int fd, unsigned char* x, size_t len) {
114  fdread(fd, (char*)x, len);
115 }
116 
117 inline void fdread(int fd, char* x) {
118  fdread(fd, x, sizeof(char));
119 }
120 
121 inline void fdread(int fd, uint8_t* x) {
122  fdread(fd, x, sizeof(uint8_t));
123 }
124 
125 inline void fdread(int fd, int* x) {
126  fdread(fd, (char*)x, sizeof(int));
127 }
128 
129 inline void fdread(int fd, uint32_t* x) {
130  fdread(fd, (char*)x, sizeof(uint32_t));
131 }
132 
133 inline void fdread(int fd, size_t* x) {
134  fdread(fd, (char*)x, sizeof(size_t));
135 }
136 
137 inline void fdread(int fd, std::string* x) {
138  size_t n = 0;
139  fdread(fd, &n);
140  x->resize(n);
141  fdread(fd, &((*x)[0]), n);
142 }
143 
144 template <typename T>
145 inline void fdread(int fd, std::vector<T>* xs) {
146  size_t n = 0;
147  fdread(fd, &n);
148  xs->resize(n);
149  fdread(fd, &((*xs)[0]), n);
150 }
151 
152 inline void fdwrite(int fd, const char* x, size_t len) {
153  size_t i = 0;
154  while (i < len) {
155  ssize_t c = write(fd, x + i, len - i);
156  if (c < 0) {
157  throw std::runtime_error("Couldn't write to pipe: " + std::string(strerror(errno)));
158  }
159  i += c;
160  }
161 }
162 
163 inline void fdwrite(int fd, const unsigned char* x, size_t len) {
164  fdwrite(fd, (const char*)x, len);
165 }
166 
167 inline void fdwrite(int fd, char x) {
168  fdwrite(fd, (char*)&x, sizeof(char));
169 }
170 
171 inline void fdwrite(int fd, uint8_t x) {
172  fdwrite(fd, (char*)&x, sizeof(uint8_t));
173 }
174 
175 inline void fdwrite(int fd, int x) {
176  fdwrite(fd, (char*)&x, sizeof(int));
177 }
178 
179 inline void fdwrite(int fd, uint32_t x) {
180  fdwrite(fd, (char*)&x, sizeof(uint32_t));
181 }
182 
183 inline void fdwrite(int fd, size_t x) {
184  fdwrite(fd, (char*)&x, sizeof(size_t));
185 }
186 
187 inline void fdwrite(int fd, const std::string& x) {
188  fdwrite(fd, x.size());
189  fdwrite(fd, x.data(), x.size());
190 }
191 
192 template <typename T>
193 inline void fdwrite(int fd, const std::vector<T>& xs) {
194  fdwrite(fd, xs.size());
195  if (xs.size() > 0) fdwrite(fd, &xs[0], xs.size());
196 }
197 
198 // remove a 'bad' mark for an FD and return true iff it was previously marked bad
199 bool unmarkBadFD(int fd);
200 
201 }
202 
203 #endif
204 
void encode(const PrimitivePtr &, std::ostream &)
Definition: expr.C:1674
void fdwrite(int fd, const char *x, size_t len)
Definition: codec.H:152
Definition: boot.H:7
void decode(PrimitivePtr *, std::istream &)
Definition: expr.C:1678
PRIM_CODEC(bool)
void write(imagefile *f, const T &x)
Definition: file.C:188
void fdread(int fd, char *x, size_t len)
Definition: codec.H:94
#define out
Definition: netio.H:19
LexicalAnnotation m(const YYLTYPE &p)
Definition: hexpr.parse.C:127
bool in(T x, const std::set< T > &xs)
Definition: array.H:47
void read(const imagefile *f, T *x)
Definition: file.C:215
bool unmarkBadFD(int fd)
Definition: funcdefs.C:486