An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 5719 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.