1 | #ifndef __MARSSTREAMS_H__
|
---|
2 | #define __MARSSTREAMS_H__
|
---|
3 |
|
---|
4 | #include <istream>
|
---|
5 | #include <ostream>
|
---|
6 | #include <vector>
|
---|
7 | #include <list>
|
---|
8 | #include <set>
|
---|
9 | #include <utility>
|
---|
10 | #include <iosfwd>
|
---|
11 |
|
---|
12 | #include "mars_linalg.h"
|
---|
13 | #include "mars_util.h"
|
---|
14 |
|
---|
15 | namespace mars
|
---|
16 | {
|
---|
17 | class ObjectStream
|
---|
18 | {
|
---|
19 | public:
|
---|
20 | #define WRITENUM_IMPL(x) { writeNum(x); return *this; }
|
---|
21 | #define READNUM_IMPL(x) { readNum(x); return *this; }
|
---|
22 |
|
---|
23 | ObjectStream (std::iostream * pIO);
|
---|
24 | ObjectStream (std::istream * pIn);
|
---|
25 | ObjectStream (std::ostream * pOut);
|
---|
26 |
|
---|
27 | ObjectStream & operator << ( const float & f ) WRITENUM_IMPL(f)
|
---|
28 | ObjectStream & operator << ( const double & d ) WRITENUM_IMPL(d)
|
---|
29 | ObjectStream & operator << ( const unsigned long & l) WRITENUM_IMPL(l)
|
---|
30 | ObjectStream & operator << ( const signed long & l) WRITENUM_IMPL(l)
|
---|
31 | ObjectStream & operator << ( const unsigned int & i) WRITENUM_IMPL(i)
|
---|
32 | ObjectStream & operator << ( const signed int & i) WRITENUM_IMPL(i)
|
---|
33 | ObjectStream & operator << ( const unsigned short & s) WRITENUM_IMPL(s)
|
---|
34 | ObjectStream & operator << ( const signed short & s) WRITENUM_IMPL(s)
|
---|
35 | ObjectStream & operator << ( const unsigned char & c) WRITENUM_IMPL(c)
|
---|
36 | ObjectStream & operator << ( const signed char & c) WRITENUM_IMPL(c)
|
---|
37 | //ObjectStream & operator << ( const std::streamoff & so) WRITENUM_IMPL(so)
|
---|
38 | //ObjectStream & operator << ( const std::streampos & sp) WRITENUM_IMPL(sp)
|
---|
39 |
|
---|
40 | ObjectStream & operator << ( const bool & b) WRITENUM_IMPL(static_cast< char > (b ? 1 : 0))
|
---|
41 |
|
---|
42 | ObjectStream & operator << ( const std::string & str )
|
---|
43 | {
|
---|
44 | assert(_pOut != NULL);
|
---|
45 |
|
---|
46 | size_t nLen = str.size();
|
---|
47 |
|
---|
48 | preprocess(nLen);
|
---|
49 |
|
---|
50 | _pOut->write(reinterpret_cast< char * > (&nLen), sizeof(size_t));
|
---|
51 | _pOut->write(str.c_str(), nLen);
|
---|
52 | return *this;
|
---|
53 | }
|
---|
54 |
|
---|
55 | template< typename T >
|
---|
56 | ObjectStream & operator << ( const std::vector< T > & vec)
|
---|
57 | {
|
---|
58 | writeContainer(vec);
|
---|
59 | return *this;
|
---|
60 | }
|
---|
61 | template< typename T >
|
---|
62 | ObjectStream & operator << ( const std::list< T > & lst)
|
---|
63 | {
|
---|
64 | writeContainer(lst);
|
---|
65 | return *this;
|
---|
66 | }
|
---|
67 | template< typename T >
|
---|
68 | ObjectStream & operator << ( const std::set< T > & st)
|
---|
69 | {
|
---|
70 | writeContainer(st);
|
---|
71 | return *this;
|
---|
72 | }
|
---|
73 |
|
---|
74 | template< typename T >
|
---|
75 | ObjectStream & operator << ( const vector2D< T > & v )
|
---|
76 | {
|
---|
77 | operator << (v.x);
|
---|
78 | operator << (v.y);
|
---|
79 | return *this;
|
---|
80 | }
|
---|
81 | template< typename T >
|
---|
82 | ObjectStream & operator << ( const vector3D< T > & v )
|
---|
83 | {
|
---|
84 | operator << (v.x);
|
---|
85 | operator << (v.y);
|
---|
86 | operator << (v.z);
|
---|
87 | return *this;
|
---|
88 | }
|
---|
89 |
|
---|
90 | template< typename T >
|
---|
91 | ObjectStream & operator << ( const BBox< T > & bbox )
|
---|
92 | {
|
---|
93 | operator << (bbox.left);
|
---|
94 | operator << (bbox.top);
|
---|
95 | operator << (bbox.right);
|
---|
96 | operator << (bbox.bottom);
|
---|
97 | return *this;
|
---|
98 | }
|
---|
99 |
|
---|
100 | template< typename T >
|
---|
101 | ObjectStream & operator << ( const Range< T > & range )
|
---|
102 | {
|
---|
103 | operator << (range.minimum);
|
---|
104 | operator << (range.maximum);
|
---|
105 | return *this;
|
---|
106 | }
|
---|
107 | template< typename T >
|
---|
108 | ObjectStream & operator << ( const RangeX< T > & range )
|
---|
109 | {
|
---|
110 | operator << (static_cast< const Range< T > & > (range));
|
---|
111 | operator << (range.step);
|
---|
112 | return *this;
|
---|
113 | }
|
---|
114 |
|
---|
115 | template< typename A, typename B >
|
---|
116 | ObjectStream & operator << (const std::pair< A, B > & pair)
|
---|
117 | { return *this << pair.first << pair.second; }
|
---|
118 |
|
---|
119 | ObjectStream & operator >> ( float & f ) READNUM_IMPL(f)
|
---|
120 | ObjectStream & operator >> ( double & d ) READNUM_IMPL(d)
|
---|
121 | ObjectStream & operator >> ( unsigned long & l) READNUM_IMPL(l)
|
---|
122 | ObjectStream & operator >> ( signed long & l) READNUM_IMPL(l)
|
---|
123 | ObjectStream & operator >> ( unsigned int & i) READNUM_IMPL(i)
|
---|
124 | ObjectStream & operator >> ( signed int & i) READNUM_IMPL(i)
|
---|
125 | ObjectStream & operator >> ( unsigned short & s) READNUM_IMPL(s)
|
---|
126 | ObjectStream & operator >> ( signed short & s) READNUM_IMPL(s)
|
---|
127 | ObjectStream & operator >> ( unsigned char & c) READNUM_IMPL(c)
|
---|
128 | ObjectStream & operator >> ( signed char & c) READNUM_IMPL(c)
|
---|
129 | //ObjectStream & operator >> ( std::streamoff & so) READNUM_IMPL(so)
|
---|
130 | //ObjectStream & operator >> ( std::streampos & sp) READNUM_IMPL(sp)
|
---|
131 |
|
---|
132 | ObjectStream & operator >> ( bool & b)
|
---|
133 | {
|
---|
134 | char c;
|
---|
135 | readNum (c);
|
---|
136 | b = (c && ~0);
|
---|
137 | return *this;
|
---|
138 | }
|
---|
139 |
|
---|
140 | ObjectStream & operator >> ( std::string & str )
|
---|
141 | {
|
---|
142 | assert(_pIn != NULL);
|
---|
143 |
|
---|
144 | size_t nLen;
|
---|
145 |
|
---|
146 | _pIn->read(reinterpret_cast< char * > (&nLen), sizeof(size_t));
|
---|
147 | preprocess(nLen);
|
---|
148 |
|
---|
149 | char * pStr = new char[nLen];
|
---|
150 |
|
---|
151 | _pIn->read(pStr, nLen);
|
---|
152 | str = std::string(pStr, nLen);
|
---|
153 | delete [] pStr;
|
---|
154 | return *this;
|
---|
155 | }
|
---|
156 |
|
---|
157 |
|
---|
158 | template< typename T >
|
---|
159 | ObjectStream & operator >> ( std::vector< T > & vec)
|
---|
160 | {
|
---|
161 | readContainer(vec);
|
---|
162 | return *this;
|
---|
163 | }
|
---|
164 | template< typename T >
|
---|
165 | ObjectStream & operator >> ( std::list< T > & lst)
|
---|
166 | {
|
---|
167 | readContainer(lst);
|
---|
168 | return *this;
|
---|
169 | }
|
---|
170 |
|
---|
171 | template< typename T >
|
---|
172 | ObjectStream & operator >> ( std::set< T > & st)
|
---|
173 | {
|
---|
174 | readContainer(st);
|
---|
175 | return *this;
|
---|
176 | }
|
---|
177 |
|
---|
178 | template< typename T >
|
---|
179 | ObjectStream & operator >> ( vector2D< T > & v )
|
---|
180 | {
|
---|
181 | operator >> (v.x);
|
---|
182 | operator >> (v.y);
|
---|
183 | return *this;
|
---|
184 | }
|
---|
185 | template< typename T >
|
---|
186 | ObjectStream & operator >> ( vector3D< T > & v )
|
---|
187 | {
|
---|
188 | operator >> (v.x);
|
---|
189 | operator >> (v.y);
|
---|
190 | operator >> (v.z);
|
---|
191 | return *this;
|
---|
192 | }
|
---|
193 |
|
---|
194 | template< typename T >
|
---|
195 | ObjectStream & operator >> ( BBox< T > & bbox )
|
---|
196 | {
|
---|
197 | operator >> (bbox.left);
|
---|
198 | operator >> (bbox.top);
|
---|
199 | operator >> (bbox.right);
|
---|
200 | operator >> (bbox.bottom);
|
---|
201 | return *this;
|
---|
202 | }
|
---|
203 |
|
---|
204 | template< typename T >
|
---|
205 | ObjectStream & operator >> ( Range< T > & range )
|
---|
206 | {
|
---|
207 | operator >> (range.minimum);
|
---|
208 | operator >> (range.maximum);
|
---|
209 | return *this;
|
---|
210 | }
|
---|
211 | template< typename T >
|
---|
212 | ObjectStream & operator >> ( RangeX< T > & range )
|
---|
213 | {
|
---|
214 | operator >> (static_cast< Range< T > & > (range));
|
---|
215 | operator >> (range.step);
|
---|
216 | return *this;
|
---|
217 | }
|
---|
218 |
|
---|
219 | template< typename A, typename B >
|
---|
220 | ObjectStream & operator >> (std::pair< A, B > & pair)
|
---|
221 | { return *this >> pair.first >> pair.second; }
|
---|
222 |
|
---|
223 | private:
|
---|
224 | std::istream * _pIn;
|
---|
225 | std::ostream * _pOut;
|
---|
226 |
|
---|
227 | struct Traits
|
---|
228 | {
|
---|
229 | enum Endian
|
---|
230 | {
|
---|
231 | Big,
|
---|
232 | Little
|
---|
233 | } endian;
|
---|
234 | } _traits;
|
---|
235 |
|
---|
236 | static Traits determineTraits ();
|
---|
237 |
|
---|
238 | template< typename T > void writeNum (const T & n, const T = 42)
|
---|
239 | {
|
---|
240 | assert(_pOut != NULL);
|
---|
241 | T val = n;
|
---|
242 |
|
---|
243 | preprocess(val);
|
---|
244 |
|
---|
245 | _pOut->write(reinterpret_cast< const char * > (&val), sizeof(T));
|
---|
246 | }
|
---|
247 | template< typename T > void writeNums (const T * pN, const size_t nCount, const T = 42)
|
---|
248 | {
|
---|
249 | assert(_pOut != NULL);
|
---|
250 | T * pVals = new T[nCount];
|
---|
251 |
|
---|
252 | memcpy (pVals, pN, nCount * sizeof(T));
|
---|
253 |
|
---|
254 | if (_traits.endian == Traits::Big)
|
---|
255 | {
|
---|
256 | for (unsigned int c = 0; c < nCount; ++c)
|
---|
257 | endianFlip (pVals[c]);
|
---|
258 | }
|
---|
259 |
|
---|
260 | size_t nLen = nCount;
|
---|
261 |
|
---|
262 | preprocess(nLen);
|
---|
263 | _pOut->write(reinterpret_cast< const char * > (&nLen), sizeof(size_t));
|
---|
264 | _pOut->write(reinterpret_cast< const char * > (pVals), sizeof(T) * nCount);
|
---|
265 | }
|
---|
266 |
|
---|
267 | template< typename C > void writeContainer (const C & ctr)
|
---|
268 | {
|
---|
269 | writeNum(static_cast< size_t > (ctr.size()));
|
---|
270 | for (typename C::const_iterator i = ctr.begin(); i != ctr.end(); ++i)
|
---|
271 | *this << *i;
|
---|
272 | }
|
---|
273 |
|
---|
274 | template< typename T > void readNum (T & n, const T = 42)
|
---|
275 | {
|
---|
276 | assert(_pIn != NULL);
|
---|
277 |
|
---|
278 | _pIn->read(reinterpret_cast< char * > (&n), sizeof(T));
|
---|
279 | preprocess(n);
|
---|
280 | }
|
---|
281 | template< typename T > void readNums (T *& pN, size_t & nCount, const T = 42)
|
---|
282 | {
|
---|
283 | assert(_pIn != NULL);
|
---|
284 |
|
---|
285 | _pIn->read(reinterpret_cast< char * > (&nCount), sizeof(size_t));
|
---|
286 | preprocess(nCount);
|
---|
287 |
|
---|
288 | pN = new T[nCount];
|
---|
289 | _pIn->read(reinterpret_cast< char * > (pN), sizeof(T) * nCount);
|
---|
290 |
|
---|
291 | if (_traits.endian == Traits::Big)
|
---|
292 | {
|
---|
293 | for (unsigned int c = 0; c < nCount; ++c)
|
---|
294 | endianFlip (pN[c]);
|
---|
295 | }
|
---|
296 | }
|
---|
297 |
|
---|
298 | template< typename C > void readContainer (C & ctr)
|
---|
299 | {
|
---|
300 | typename C::value_type t;
|
---|
301 |
|
---|
302 | size_t nLen;
|
---|
303 | readNum(nLen);
|
---|
304 | ctr.clear();
|
---|
305 | reserve< C, typename C::value_type >(ctr, nLen);
|
---|
306 | for (size_t c = 0; c < nLen; ++c)
|
---|
307 | {
|
---|
308 | *this >> t;
|
---|
309 | ctr.push_back(t);
|
---|
310 | }
|
---|
311 | }
|
---|
312 |
|
---|
313 | template< typename T > void endianFlip (T & val, T = 42) const
|
---|
314 | {
|
---|
315 | char * pData = reinterpret_cast< char * > (&val), cTmp;
|
---|
316 |
|
---|
317 | for (unsigned int i = 0; i < sizeof(T); ++i)
|
---|
318 | {
|
---|
319 | cTmp = pData[i];
|
---|
320 | pData[i] = pData[sizeof(T) - i - 1];
|
---|
321 | pData[sizeof(T) - i - 1] = cTmp;
|
---|
322 | }
|
---|
323 | }
|
---|
324 | template< typename T > void preprocess (T & val, T = 42) const
|
---|
325 | {
|
---|
326 | if (_traits.endian == Traits::Big)
|
---|
327 | endianFlip(val);
|
---|
328 | }
|
---|
329 |
|
---|
330 | template< typename C, typename T > static void reserve (C & ctr, const size_t nCount) {}
|
---|
331 | template< typename T > static void reserve (std::vector< T > & ctr, const size_t nCount)
|
---|
332 | { ctr.reserve(nCount); }
|
---|
333 | };
|
---|
334 | }
|
---|
335 |
|
---|
336 | #endif
|
---|