An Overlay-based
Virtual Network Substrate
SpoVNet

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

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

Renamed remotely

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