source: source/ariba/utility/serialization/DataStream.hpp@ 5660

Last change on this file since 5660 was 5638, checked in by Christoph Mayer, 15 years ago

adress detection aufgeräumt, network info für bleutooth, data stream (hopeful crash fix), logging auf maemo nur warn, ...

File size: 17.5 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef DATASTREAM_HPP_
40#define DATASTREAM_HPP_
41
42//== Library includes ==
43#include <boost/cstdint.hpp>
44#include <boost/type_traits/make_unsigned.hpp>
45
46#include <cassert>
47#include <iostream>
48#include <vector>
49#include <string.h>
50
51#ifndef SERIALIZATION_NS
52#define SERIALIZATION_NS ariba::utility::serialization
53#define SERIALIZATION_NS_INT SERIALIZATION_NS::internal
54
55/* some words on the namespaces */
56#define SERIALIZATION_NS_BEGIN() \
57 namespace ariba { \
58 namespace utility { \
59 namespace serialization {
60
61#define SERIALIZATION_NS_END() \
62 } } }
63#endif
64
65//== forward declarations ==
66SERIALIZATION_NS_BEGIN()
67
68// data stream template forward declaration
69template<Mode __mode, int __variant = DEFAULT_V, typename T = uint8_t>
70class DataStreamTpl;
71
72// internal explicit serialization forward declaration
73namespace internal {
74 template<typename T> class ITpl;
75 template<typename T> ITpl<T> I( T& value, size_t length = sizeof(T)*8 );
76 class cI;
77 class T;
78 class cT;
79}
80
81// virtual serialization forward declaration
82bool data_serialization( Mode mode, VSerializeable* obj, Data& data, int variant = DEFAULT_V );
83Data data_serialize( const VSerializeable* obj, int variant = DEFAULT_V );
84bool data_deserialize( VSerializeable* obj, Data& data, int variant = DEFAULT_V );
85size_t data_length( const VSerializeable* obj, int variant = DEFAULT_V );
86
87SERIALIZATION_NS_END()
88
89//== Internal includes ==
90#include "../internal/Utilities.hpp"
91
92//== Local includes ==
93#include "Serialization.hpp"
94#include "DataUtilities.hpp"
95#include "Data.hpp"
96
97SERIALIZATION_NS_BEGIN()
98
99/**
100 *
101 */
102template<Mode __mode, int __variant, typename T>
103class DataStreamTpl {
104
105 template<typename X>
106 friend class SERIALIZATION_NS_INT::ITpl;
107 friend class SERIALIZATION_NS_INT::cI;
108 friend class SERIALIZATION_NS_INT::T;
109 friend class SERIALIZATION_NS_INT::cT;
110
111 template<Mode _a, int _b, typename _c>
112 friend std::ostream& operator<<( std::ostream&, DataStreamTpl<_a, _b, _c>& );
113
114private:
115 /* index in the buffer */
116 size_t index;
117
118 /* binary buffer */
119 DataTpl<T> bits;
120
121 /* support serializers */
122 template<class X>
123 finline void add(const X& ser, if_is_base_of( ExplicitSerializer, X )) {
124 ser.SERIALIZATION_METHOD_NAME(*this);
125 }
126
127 template<class X>
128 finline void remove(const X& ser, if_is_base_of( ExplicitSerializer, X )) {
129 ser.SERIALIZATION_METHOD_NAME(*this);
130 }
131
132 /* support serializeables */
133 template<class X>
134 finline void add( X& obj, if_is_base_of( Serializeable, X ) ) {
135 get_serializer<__variant>(obj).SERIALIZATION_METHOD_NAME(*this);
136 }
137
138 template<class X>
139 finline void add( const X& obj, if_is_base_of( Serializeable, X ) ) {
140 get_serializer<__variant>((X&)obj).SERIALIZATION_METHOD_NAME(*this);
141 }
142
143 template<class X>
144 finline void remove( X& obj, if_is_base_of( Serializeable, X ) ) {
145 get_serializer<__variant>(obj).SERIALIZATION_METHOD_NAME(*this);
146 }
147
148 /* support uints */
149 template<typename X>
150 finline void add(X& obj, if_uint(X)) {
151 if (!isMeasure())
152// bitcpy( obj, 0, bits.getBuffer(), index);
153 bitcpy( obj, 0, bits.getBuffer(), index, sizeof(X)*8 );
154 index += sizeof(X) * 8;
155 }
156
157 template<typename X>
158 finline void remove(X& obj, if_uint(X)) {
159 //if (!isMeasure()) bits[index].get(obj);
160 if (!isMeasure())
161 bitcpy( bits.getBuffer(), index, obj, 0, sizeof(X)*8 );
162 index += sizeof(X) * 8;
163 }
164
165 /* support signed ints */
166 template<typename X>
167 finline void add(X& sobj, if_int(X)) {
168 typedef typename boost::make_unsigned<X>::type UX;
169 UX& obj = *((UX*)&sobj);
170 if (!isMeasure())
171 bitcpy( sobj, 0, bits.getBuffer(), index);
172 index += sizeof(X) * 8;
173 }
174
175 template<typename X>
176 finline void remove(X& sobj, if_int(X)) {
177 typedef typename boost::make_unsigned<X>::type UX;
178 UX& obj = *((UX*)&sobj);
179 if (!isMeasure()) bits[index].get(obj);
180 index += sizeof(X) * 8;
181 }
182
183 /* support boolean types */
184 finline void add( bool& obj ) {
185 if (!isMeasure()) bits[index] = obj;
186 index += 1;
187 }
188
189 finline void remove( bool& obj ) {
190 if (!isMeasure()) bits[index].get(obj);
191 index += 1;
192 }
193
194 /* support vserializeables */
195 finline void add( const VSerializeable* obj ) {
196 if (!isMeasure()) {
197 Data data = data_serialize( (VSerializeable*)obj, __variant );
198 add(data); data.release();
199 } else {
200 index += data_length( obj, __variant );
201 }
202 }
203
204 finline void remove( VSerializeable* obj ) {
205 Data data( bits.getBuffer() + index / 8, getRemainingLength() );
206 size_t length = obj->SERIALIZATION_METHOD_NAME( __mode, data, __variant );
207 index += length;
208 }
209
210 finline void remove( const VSerializeable* obj ) {
211 throw "NOT SUPPORTED!";
212 }
213
214 /* data stream typedef */
215 typedef DataStreamTpl<__mode, __variant, T> _DataStream;
216
217public:
218
219 finline DataStreamTpl() : bits() {
220 index = 0;
221 }
222
223 finline DataStreamTpl( Data& binary ) : bits(binary) {
224 index = 0;
225 }
226
227 finline DataStreamTpl( _DataStream& stream ) {
228 throw "Error: DataStreams can not be copied.";
229 }
230
231 /**
232 * Returns the current mode of the data stream
233 *
234 * @return the current mode of the data stream
235 */
236 finline Mode getMode() const {
237 return __mode;
238 }
239
240 /**
241 * Returns true, if this is a measure of data length
242 *
243 * @return true, if this is a measure of data length
244 */
245 finline bool isMeasure() {
246 return __mode == MEASURE;
247 }
248
249 finline bool isSerializer() {
250 return (__mode == SERIALIZE) || isMeasure();
251 }
252
253 finline bool isDeserializer() {
254 return __mode == DESERIALIZE;
255 }
256
257 /**
258 * Returns the variants that are used.
259 *
260 * @return The variants that are used.
261 */
262 finline int getVariant() const {
263 return __variant;
264 }
265
266 /**
267 * Returns the remaining length.
268 * This method is only applicable in deserialize mode.
269 *
270 * @return The remaining length of the stream.
271 */
272 finline size_t getRemainingLength() const {
273 return bits.getLength() - index;
274 }
275
276 /**
277 * Returns the remaining data in the data buffer.
278 * This method is only applicable in deserialize mode.
279 *
280 * @return The remaining data in the data buffer.
281 */
282 finline Data getRemainingData( size_t length ) {
283 Data subData = Data(bits.getBuffer() + index / bits.word_width, length);
284 index += length;
285 return subData;
286 }
287
288 /**
289 * Returns the current length of the stream.
290 * This method is only applicable in serialize mode.
291 *
292 * @return The current length of the stream.
293 */
294 finline size_t getCurrentLength() const {
295 return index;
296 }
297
298 /**
299 * Resets the index of the stream
300 */
301 finline void reset(Mode mode = UNDEFINED) {
302 this->index = 0;
303 this->mode = mode;
304 }
305
306 /**
307 * Returns a mark of the current position in the stream
308 */
309 finline size_t mark() const {
310 return index;
311 }
312
313 /**
314 * Seeks to the given position
315 */
316 finline void seek( size_t idx ) {
317 index = idx;
318 }
319
320 /**
321 * Assures that the given length is available in the
322 * buffer.
323 */
324 finline void ensureLength( size_t size ) {
325 if (!isMeasure()) bits.ensureLength( size + index );
326 }
327
328 /**
329 * Returns a binary object, of the current stream content
330 */
331 finline Data getData() {
332 bits.setLength(index);
333 return bits;
334 }
335
336 finline uint8_t* bytes( size_t length ) {
337 assert((index%bits.word_width)==0);
338 if (!isMeasure()) {
339 bits.ensureLength( index + length * 8);
340 uint8_t* buffer = (uint8_t*)bits.getBuffer()+(index/bits.word_width);
341 index += length*8;
342 return buffer;
343 } else {
344 index += length*8;
345 return NULL;
346 }
347 }
348
349 /**
350 * deserialises or serializes an object depending on the bit-streams mode
351 */
352 template<typename X>
353 finline _DataStream& operator&&( X& obj ) {
354 if (isSerializer()) add(obj); else if (isDeserializer()) remove(obj);
355 return *this;
356 }
357
358 template<typename X>
359 finline _DataStream& operator&&( const X& obj ) {
360 if (isSerializer()) add(obj); else if (isDeserializer()) remove(obj);
361 return *this;
362 }
363
364 template<typename X>
365 finline _DataStream& operator&&( X* obj ) {
366 if (isSerializer()) add(obj); else if (isDeserializer()) remove(obj);
367 return *this;
368 }
369
370 template<typename X>
371 finline _DataStream& operator&&( const X* obj ) {
372 if (isSerializer()) add(obj); else if (isDeserializer()) remove(obj);
373 return *this;
374 }
375};
376
377//--------------------------------------------------------------------------
378
379template<Mode _a, int _b, typename _c>
380std::ostream& operator<<( std::ostream& stream,
381 DataStreamTpl<_a, _b, _c>& binaryStream ) {
382 stream << binaryStream.bits << "";
383 return stream;
384}
385
386//--------------------------------------------------------------------------
387
388namespace internal {
389 using_serialization;
390
391 /* integer support - I( value, length ) */
392 template<typename T>
393 class ITpl : public ExplicitSerializer {
394 private:
395 T& value;
396 size_t length;
397 public:
398 finline ITpl( T& _value, size_t _length = sizeof(T)*8 )
399 : value(_value), length(_length) {}
400
401 sznMethodBegin(X)
402 if (X.isSerializer()) {
403 if (!X.isMeasure())
404 X.bits[X.index].set( value, length );
405 X.index += length;
406 } else {
407 X.bits[X.index].get(value,length);
408 X.index += length;
409 }
410 sznMethodEnd()
411 };
412
413 template<typename T>
414 finline ITpl<T> I( T& value, size_t length ) {
415 return ITpl<T>(value, length);
416 }
417
418 /* const int support - cI( uintmax_t ) */
419 class cI : public ExplicitSerializer {
420 private:
421 const uintmax_t value;
422 size_t length;
423 public:
424 finline cI( const uintmax_t _value, size_t _length )
425 : value(_value), length(_length) {}
426
427 sznMethodBegin(X)
428 if (X.isSerializer()) {
429 if (!X.isMeasure())
430 X.bits[X.index].set(value,length);
431 X.index += length;
432 } else {
433 uintmax_t _value = 0;
434 X.bits[X.index].get(_value,length);
435 if (_value != value) break;
436 X.index += length;
437 }
438 sznMethodEnd()
439 };
440
441 /* const char* support - cT( const char* ) */
442 class cT : public ExplicitSerializer {
443 private:
444 const char* text;
445
446 public:
447 finline cT( const char* _text )
448 : text(_text) {}
449
450 sznMethodBegin(X)
451 if (X.isSerializer()) {
452 size_t length = strlen(text);
453 if (!X.isMeasure()) {
454 for (size_t i=0; i<length; i++)
455 X.bits[X.index+i*8] = (uint8_t)text[i];
456 }
457 X.index += length * 8;
458 } else {
459 size_t length = strlen(text);
460 for (size_t i=0; i<length; i++) {
461 char c = 0;
462 X.bits[X.index+i*8].get(c);
463 if (c!=text[i]) break;
464 }
465 }
466 sznMethodEnd()
467 };
468
469 /* string and char* support, T( char* | std::string ) */
470 class T : public ExplicitSerializer {
471 private:
472 bool isCharP;
473 char** text;
474 std::string* string;
475 int length;
476
477 public:
478 finline T( char*& _text, int length = -1 ) :
479 text(&_text), string(NULL) {
480 this->isCharP = true;
481 this->length = length;
482 }
483
484 finline T( std::string& _string, int length = -1 ) :
485 text(NULL), string(&_string) {
486 this->isCharP = false;
487 this->length = length;
488 }
489
490 sznMethodBegin(X)
491 if (X.isSerializer()) {
492 char* textp = isCharP ? *text : (char*)string->c_str();
493 size_t plength = length!= -1 ? length : strlen(textp);
494 if (!X.isMeasure()) {
495 size_t i;
496 for (i=0; i<plength && textp[i]!=0; i++)
497 X.bits[X.index+i*8] = (uint8_t)textp[i];
498 if (length==-1) X.bits[X.index+i*8] = (uint8_t)0;
499 }
500 X.index += plength * 8 + ((length == -1) ? 8 : 0);
501 } else {
502 std::string s;
503 size_t i = 0;
504 while (length == -1 || i < (size_t)length) {
505 uint8_t c = 0;
506 X.bits[X.index].get(c); X.index += 8;
507 if (c == 0 && length == -1) break;
508 s += (char)c;
509 i++;
510 }
511 if (isCharP) *text = strdup(s.c_str());
512 else string->assign(s);
513 }
514 sznMethodEnd()
515 };
516
517 /* array and vector support */
518 template<typename T>
519 class ArrayTpl : public ExplicitSerializer {
520 private:
521 T*& v;
522 size_t l;
523
524 public:
525 finline ArrayTpl( T*& array, size_t length ) :
526 v(0), l(length) {}
527
528 sznMethodBegin(X)
529 if (X.isDeserializer()) v = new T[l];
530 for (size_t i=0; i<l; i++) X && v[i];
531 sznMethodEnd()
532 };
533
534 template<typename T>
535 class VectorTpl : public ExplicitSerializer {
536 private:
537 std::vector<T>& v;
538 size_t l;
539
540 public:
541 finline VectorTpl( std::vector<T>& vec, size_t length ) :
542 v(vec), l(length) {}
543
544 sznMethodBegin(X)
545 if (X.isDeserializer()) v.resize(l);
546 for (size_t i=0; i<l; i++) X && v[i];
547 sznMethodEnd()
548 };
549
550 template<typename X, typename T>
551 finline X V( T& x ) {
552 throw "ERROR: No vector serializer for this type";
553 }
554
555 template<typename T>
556 finline ArrayTpl<T> A( T*& array, size_t length ) {
557 return ArrayTpl<T>(array,length);
558 }
559
560 template<typename T>
561 finline VectorTpl<T> A( std::vector<T>& array, size_t length ) {
562 return VectorTpl<T>(array,length);
563 }
564
565 /* allocated virtual object support */
566 template<typename T>
567 class VOTpl : ExplicitSerializer {
568 private:
569 int variant;
570 T*& obj;
571 public:
572 finline VOTpl( T*& mobj, int variant ) : obj(mobj) {
573 }
574 sznMethodBegin(X)
575 if (X.isSerializer()) {
576 if (obj!=NULL) X && obj;
577 } else {
578 obj = new T();
579 X && obj;
580 }
581 sznMethodEnd()
582 };
583
584 template<typename T>
585 finline VOTpl<T> VO( T*& obj, int variant = DEFAULT_V ) {
586 return VOTpl<T>(obj,variant);
587 }
588
589 /* allocated non-virtual object serialization support */
590 template<typename T>
591 class OTpl : ExplicitSerializer {
592 private:
593 int variant;
594 T*& obj;
595 public:
596 finline OTpl( T*& mobj, int variant ) : obj(mobj) {
597 }
598 sznMethodBegin(X)
599 if (X.isSerializer()) {
600 if (obj!=NULL) X && *obj;
601 } else {
602 obj = new T();
603 X && *obj;
604 }
605 sznMethodEnd()
606 };
607
608 template<typename T>
609 finline OTpl<T> O( T*& obj, int variant = DEFAULT_V ) {
610 return OTpl<T>(obj,variant);
611 }
612
613} // namespace internal
614
615//--------------------------------------------------------------------------
616
617//= static serialization =
618//= get length =
619
620template<int __variant, typename X> finline
621size_t data_length_v( const X& obj ) {
622 DataStreamTpl<MEASURE, __variant> stream;
623 return (stream && (X&)obj).getCurrentLength();
624}
625
626template<typename X> finline
627size_t data_length( const X& obj ) {
628 return data_length_v<DEFAULT_V>(obj);
629}
630
631template<Mode __mode, int __variant, typename X> finline
632size_t data_serialization_v( X& obj, Data& data,
633 if_is_base_of(Serializeable, X) ) {
634 if (__mode == SERIALIZE) {
635 DataStreamTpl<SERIALIZE, __variant> stream;
636 size_t len = data_length_v<__variant>(obj);
637 stream.ensureLength( len );
638 return (data = (stream && obj).getData()).getLength();
639 } else {
640 DataStreamTpl<DESERIALIZE, __variant> stream( data );
641 return (stream && obj).getCurrentLength();
642 }
643}
644
645template<Mode __mode, int __variant, typename X>
646size_t slow_data_serialization_v( X& obj, Data& data,
647 if_is_base_of(Serializeable, X) ) {
648 return slow_data_serialization_v<__mode,__variant>(obj,data);
649}
650
651template<Mode __mode, typename X>
652size_t data_serialization( X& obj, Data& data,
653 if_is_base_of( Serializeable, X ) ) {
654 return slow_data_serialization_v<__mode, DEFAULT_V>( obj, data );
655}
656
657template<int __variant, typename X>
658Data data_serialize_v( const X& obj, if_is_base_of(Serializeable, X) ) {
659 Data data; data_serialization_v<SERIALIZE, __variant>( (X&)obj, data );
660 return data;
661}
662
663template<typename X>
664Data data_serialize( const X& obj, if_is_base_of(Serializeable, X) ) {
665 return data_serialize_v<DEFAULT_V>(obj);
666}
667
668template<int __variant, typename X>
669size_t data_deserialize_v( X& obj, Data data, if_is_base_of(Serializeable, X) ) {
670 return data_serialization_v<DESERIALIZE,__variant>( obj, data );
671}
672
673template<typename X>
674size_t data_deserialize( X& obj, Data data,
675 if_is_base_of(Serializeable, X) ) {
676 return data_deserialize_v<DEFAULT_V>(obj, data);
677}
678
679//= virtual serialization =
680
681finline bool data_serialization( VSerializeable* obj, Data& data,
682 Mode mode, int variant /*= DEFAULT_V*/) {
683 size_t length = obj->SERIALIZATION_METHOD_NAME( mode, data, variant );
684 return length != 0;
685}
686
687finline Data data_serialize( const VSerializeable* obj,
688 int variant /*= DEFAULT_V*/) {
689 Data data;
690 data_serialization( (VSerializeable*)obj, data, SERIALIZE, variant );
691 return data;
692}
693
694finline bool data_deserialize( VSerializeable* obj, Data& data,
695 int variant /*= DEFAULT_V*/) {
696 return data_serialization( obj, data, DESERIALIZE, variant );
697}
698
699finline size_t data_length( const VSerializeable* obj, int variant /*= DEFAULT_V*/) {
700 return ((VSerializeable*)obj)->SERIALIZATION_METHOD_NAME( MEASURE,
701 (Data&)Data::UNSPECIFIED, variant );
702}
703
704//--------------------------------------------------------------------------
705
706SERIALIZATION_NS_END()
707
708#endif /* DATASTREAM_HPP_ */
Note: See TracBrowser for help on using the repository browser.