close Warning: Can't use blame annotator:
No changeset 2259 in the repository

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

Last change on this file since 5618 was 5284, checked in by mies, 15 years ago

+ added new transport modules and adapted ariba to them
+ exchange endpoint descriptors an link establishment
+ clean up of base communication
+ link establishment with in the presence of multiple endpoints
+ local discovery for ipv6, ipv4 and bluetooth mac addresses

File size: 17.5 KB
RevLine 
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()); else *string = s;
512 }
513 sznMethodEnd()
514 };
515
516 /* array and vector support */
517 template<typename T>
518 class ArrayTpl : public ExplicitSerializer {
519 private:
520 T*& v;
521 size_t l;
522
523 public:
524 finline ArrayTpl( T*& array, size_t length ) :
525 v(0), l(length) {}
526
527 sznMethodBegin(X)
528 if (X.isDeserializer()) v = new T[l];
529 for (size_t i=0; i<l; i++) X && v[i];
530 sznMethodEnd()
531 };
532
533 template<typename T>
534 class VectorTpl : public ExplicitSerializer {
535 private:
536 std::vector<T>& v;
537 size_t l;
538
539 public:
540 finline VectorTpl( std::vector<T>& vec, size_t length ) :
541 v(vec), l(length) {}
542
543 sznMethodBegin(X)
544 if (X.isDeserializer()) v.resize(l);
545 for (size_t i=0; i<l; i++) X && v[i];
546 sznMethodEnd()
547 };
548
549 template<typename X, typename T>
550 finline X V( T& x ) {
551 throw "ERROR: No vector serializer for this type";
552 }
553
554 template<typename T>
555 finline ArrayTpl<T> A( T*& array, size_t length ) {
556 return ArrayTpl<T>(array,length);
557 }
558
559 template<typename T>
560 finline VectorTpl<T> A( std::vector<T>& array, size_t length ) {
561 return VectorTpl<T>(array,length);
562 }
563
564 /* allocated virtual object support */
565 template<typename T>
566 class VOTpl : ExplicitSerializer {
567 private:
568 int variant;
569 T*& obj;
570 public:
571 finline VOTpl( T*& mobj, int variant ) : obj(mobj) {
572 }
573 sznMethodBegin(X)
574 if (X.isSerializer()) {
575 if (obj!=NULL) X && obj;
576 } else {
577 obj = new T();
578 X && obj;
579 }
580 sznMethodEnd()
581 };
582
583 template<typename T>
584 finline VOTpl<T> VO( T*& obj, int variant = DEFAULT_V ) {
585 return VOTpl<T>(obj,variant);
586 }
587
588 /* allocated non-virtual object serialization support */
589 template<typename T>
590 class OTpl : ExplicitSerializer {
591 private:
592 int variant;
593 T*& obj;
594 public:
595 finline OTpl( T*& mobj, int variant ) : obj(mobj) {
596 }
597 sznMethodBegin(X)
598 if (X.isSerializer()) {
599 if (obj!=NULL) X && *obj;
600 } else {
601 obj = new T();
602 X && *obj;
603 }
604 sznMethodEnd()
605 };
606
607 template<typename T>
608 finline OTpl<T> O( T*& obj, int variant = DEFAULT_V ) {
609 return OTpl<T>(obj,variant);
610 }
611
612} // namespace internal
613
614//--------------------------------------------------------------------------
615
616//= static serialization =
617//= get length =
618
619template<int __variant, typename X> finline
620size_t data_length_v( const X& obj ) {
621 DataStreamTpl<MEASURE, __variant> stream;
622 return (stream && (X&)obj).getCurrentLength();
623}
624
625template<typename X> finline
626size_t data_length( const X& obj ) {
627 return data_length_v<DEFAULT_V>(obj);
628}
629
630template<Mode __mode, int __variant, typename X> finline
631size_t data_serialization_v( X& obj, Data& data,
632 if_is_base_of(Serializeable, X) ) {
633 if (__mode == SERIALIZE) {
634 DataStreamTpl<SERIALIZE, __variant> stream;
635 size_t len = data_length_v<__variant>(obj);
636 stream.ensureLength( len );
637 return (data = (stream && obj).getData()).getLength();
638 } else {
639 DataStreamTpl<DESERIALIZE, __variant> stream( data );
640 return (stream && obj).getCurrentLength();
641 }
642}
643
644template<Mode __mode, int __variant, typename X>
645size_t slow_data_serialization_v( X& obj, Data& data,
646 if_is_base_of(Serializeable, X) ) {
647 return slow_data_serialization_v<__mode,__variant>(obj,data);
648}
649
650template<Mode __mode, typename X>
651size_t data_serialization( X& obj, Data& data,
652 if_is_base_of( Serializeable, X ) ) {
653 return slow_data_serialization_v<__mode, DEFAULT_V>( obj, data );
654}
655
656template<int __variant, typename X>
657Data data_serialize_v( const X& obj, if_is_base_of(Serializeable, X) ) {
658 Data data; data_serialization_v<SERIALIZE, __variant>( (X&)obj, data );
659 return data;
660}
661
662template<typename X>
663Data data_serialize( const X& obj, if_is_base_of(Serializeable, X) ) {
664 return data_serialize_v<DEFAULT_V>(obj);
665}
666
667template<int __variant, typename X>
668size_t data_deserialize_v( X& obj, Data data, if_is_base_of(Serializeable, X) ) {
669 return data_serialization_v<DESERIALIZE,__variant>( obj, data );
670}
671
672template<typename X>
673size_t data_deserialize( X& obj, Data data,
674 if_is_base_of(Serializeable, X) ) {
675 return data_deserialize_v<DEFAULT_V>(obj, data);
676}
677
678//= virtual serialization =
679
680finline bool data_serialization( VSerializeable* obj, Data& data,
681 Mode mode, int variant /*= DEFAULT_V*/) {
682 size_t length = obj->SERIALIZATION_METHOD_NAME( mode, data, variant );
683 return length != 0;
684}
685
686finline Data data_serialize( const VSerializeable* obj,
687 int variant /*= DEFAULT_V*/) {
688 Data data;
689 data_serialization( (VSerializeable*)obj, data, SERIALIZE, variant );
690 return data;
691}
692
693finline bool data_deserialize( VSerializeable* obj, Data& data,
694 int variant /*= DEFAULT_V*/) {
695 return data_serialization( obj, data, DESERIALIZE, variant );
696}
697
698finline size_t data_length( const VSerializeable* obj, int variant /*= DEFAULT_V*/) {
699 return ((VSerializeable*)obj)->SERIALIZATION_METHOD_NAME( MEASURE,
700 (Data&)Data::UNSPECIFIED, variant );
701}
702
703//--------------------------------------------------------------------------
704
705SERIALIZATION_NS_END()
706
707#endif /* DATASTREAM_HPP_ */
Note: See TracBrowser for help on using the repository browser.