missing project/build files
[client-tools.git] / src / external / 3rd / library / platform / utils / Base / Archive.h
blob0a0a162df7939d014e01458c039f19fe5ee78339
1 ////////////////////////////////////////////////////////////////////////////////
2 // The author of this code is Justin Randall
3 //
4 // I have made modifications to the ByteStream
5 // and AutoByteStream classes in order to make them suitable
6 // for use in messaging systems which require objects that
7 // are copyable and assignable. It is also desirable for
8 // the ByteStream object to use a flexible allocator system
9 // that may support multi-threaded programming models.
12 #ifndef BASE_ARCHIVE_H
13 #define BASE_ARCHIVE_H
16 #include <assert.h>
17 #include <string>
18 #include <vector>
19 #include "Platform.h"
20 #include "Mutex.h"
23 #if defined _MT || defined _REENTRANT
24 # define USE_ARCHIVE_MUTEX
25 #endif
27 #ifdef WIN32
28 # include "win32/Archive.h"
29 #elif linux
30 # include "linux/Archive.h"
31 #elif sparc
32 # include "solaris/Archive.h"
33 #else
34 #error /Base/Archive.h: Undefine platform type
35 #endif
37 #ifdef EXTERNAL_DISTRO
38 namespace NAMESPACE
41 #endif
42 namespace Base
45 const unsigned MAX_ARRAY_SIZE = 1024;
48 ////////////////////////////////////////////////////////////////////////////////
50 #if defined(USE_ARCHIVE_MUTEX)
51 extern CMutex ByteStreamMutex;
52 #endif
54 class ByteStream;
56 class ReadIterator
58 public:
59 ReadIterator();
60 ReadIterator(const ReadIterator & source);
61 explicit ReadIterator(const ByteStream & source);
62 ~ReadIterator();
64 ReadIterator & operator = (const ReadIterator & source);
65 void advance (const unsigned int distance);
66 void get (void * target, const unsigned long int readSize);
67 const unsigned int getSize () const;
68 const unsigned char * const getBuffer () const;
69 const unsigned int getReadPosition () const;
71 private:
72 unsigned int readPtr;
73 const ByteStream * stream;
75 class ByteStream
77 public:
78 typedef Base::ReadIterator ReadIterator;
80 private:
81 class Data
83 friend class ByteStream;
84 friend class Base::ReadIterator;
85 public:
86 ~Data();
88 static Data * getNewData();
90 const int getRef () const;
91 void deref ();
92 void ref ();
93 protected:
94 unsigned char * buffer;
95 unsigned long size;
96 private:
97 struct DataFreeList
99 ~DataFreeList()
101 std::vector<ByteStream::Data *>::iterator i;
102 for(i = freeList.begin(); i != freeList.end(); ++i)
104 delete (*i);
107 std::vector<Data *> freeList;
109 Data();
110 //explicit Data(unsigned char * buffer);
111 static std::vector<Data *> & getDataFreeList();
112 static void releaseOldData(Data * oldData);
113 private:
114 int refCount;
117 friend class Base::ReadIterator;
118 public:
119 ByteStream();
120 ByteStream(const unsigned char * const buffer, const unsigned int bufferSize);
121 ByteStream(const ByteStream & source);
122 virtual ~ByteStream();
124 public:
125 ByteStream(ReadIterator & source);
126 ByteStream & operator = (const ByteStream & source);
127 ByteStream & operator = (ReadIterator & source);
128 const ReadIterator & begin() const;
129 void clear();
130 const unsigned char * const getBuffer() const;
131 const unsigned int getSize() const;
132 void put(const void * const source, const unsigned int sourceSize);
134 private:
135 void get(void * target, ReadIterator & readIterator, const unsigned long int readSize) const;
136 void growToAtLeast(const unsigned int targetSize);
137 void reAllocate(const unsigned int newSize);
139 private:
140 unsigned int allocatedSize;
141 ReadIterator beginReadIterator;
142 Data * data;
143 unsigned int size;
148 inline ByteStream::Data::Data() :
149 buffer(0),
150 size(0),
151 refCount(1)
155 inline ByteStream::Data::~Data()
157 #if defined(USE_ARCHIVE_MUTEX)
158 ByteStreamMutex.Lock();
159 #endif
161 refCount = 0;
162 delete[] buffer;
164 #if defined(USE_ARCHIVE_MUTEX)
165 ByteStreamMutex.Unlock();
166 #endif
169 inline void ByteStream::Data::deref()
171 #if defined(USE_ARCHIVE_MUTEX)
172 ByteStreamMutex.Lock();
173 #endif
175 refCount--;
177 #if defined(USE_ARCHIVE_MUTEX)
178 ByteStreamMutex.Unlock();
179 #endif
181 if(refCount < 1)
182 releaseOldData(this);
185 inline std::vector<ByteStream::Data *> & ByteStream::Data::getDataFreeList()
187 static DataFreeList freeList;
188 return freeList.freeList;
191 inline ByteStream::Data * ByteStream::Data::getNewData()
193 #if defined(USE_ARCHIVE_MUTEX)
194 ByteStreamMutex.Lock();
195 #endif
197 Data * result = 0;
198 if(getDataFreeList().empty())
200 result = new Data;
202 else
204 result = getDataFreeList().back();
205 getDataFreeList().pop_back();
207 result->refCount = 1;
209 #if defined(USE_ARCHIVE_MUTEX)
210 ByteStreamMutex.Unlock();
211 #endif
213 return result;
216 inline const int ByteStream::Data::getRef() const
218 return refCount;
221 inline void ByteStream::Data::ref()
223 #if defined(USE_ARCHIVE_MUTEX)
224 ByteStreamMutex.Lock();
225 #endif
227 refCount++;
229 #if defined(USE_ARCHIVE_MUTEX)
230 ByteStreamMutex.Unlock();
231 #endif
234 inline void ByteStream::Data::releaseOldData(ByteStream::Data * oldData)
236 #if defined(USE_ARCHIVE_MUTEX)
237 ByteStreamMutex.Lock();
238 #endif
240 getDataFreeList().push_back(oldData);
241 oldData->refCount = 0;
243 #if defined(USE_ARCHIVE_MUTEX)
244 ByteStreamMutex.Unlock();
245 #endif
248 inline ByteStream::ReadIterator & ByteStream::ReadIterator::operator = (const ByteStream::ReadIterator & rhs)
250 if(&rhs != this)
252 readPtr = rhs.readPtr;
253 stream = rhs.stream;
255 return *this;
258 inline void ByteStream::ReadIterator::get(void * target, const unsigned long int readSize)
260 assert(stream);
261 stream->get(target, *this, readSize);
262 readPtr += readSize;
265 inline const unsigned int ByteStream::ReadIterator::getSize() const
267 assert(stream);
268 return stream->getSize() - readPtr;
271 inline const ByteStream::ReadIterator & ByteStream::begin() const
273 return beginReadIterator;
276 inline void ByteStream::ReadIterator::advance(const unsigned int distance)
278 readPtr += distance;
281 inline const unsigned int ByteStream::ReadIterator::getReadPosition() const
283 return readPtr;
286 inline const unsigned char * const ByteStream::ReadIterator::getBuffer() const
288 if(stream)
289 return &stream->data->buffer[readPtr];
291 return 0;
294 inline void ByteStream::clear()
296 #if defined(USE_ARCHIVE_MUTEX)
297 ByteStreamMutex.Lock();
298 #endif
300 size = 0;
302 #if defined(USE_ARCHIVE_MUTEX)
303 ByteStreamMutex.Unlock();
304 #endif
307 inline const unsigned char * const ByteStream::getBuffer() const
309 return data->buffer;
312 inline const unsigned int ByteStream::getSize() const
314 return size;
317 inline void ByteStream::growToAtLeast(const unsigned int targetSize)
319 if(allocatedSize < targetSize)
321 reAllocate(allocatedSize + allocatedSize + targetSize);
326 ////////////////////////////////////////////////////////////////////////////////
329 inline void get(ByteStream::ReadIterator & source, ByteStream & target)
331 target.put(source.getBuffer(), source.getSize());
332 source.advance(source.getSize());
335 inline void get(ByteStream::ReadIterator & source, double & target)
337 source.get(&target, 8);
338 target = byteSwap(target);
341 inline void get(ByteStream::ReadIterator & source, float & target)
343 source.get(&target, 4);
344 target = byteSwap(target);
347 inline void get(ByteStream::ReadIterator & source, uint64 & target)
349 source.get(&target, 8);
350 target = byteSwap(target);
353 inline void get(ByteStream::ReadIterator & source, int64 & target)
355 source.get(&target, 8);
356 target = byteSwap(target);
359 inline void get(ByteStream::ReadIterator & source, uint32 & target)
361 source.get(&target, 4);
362 target = byteSwap(target);
365 inline void get(ByteStream::ReadIterator & source, int32 & target)
367 source.get(&target, 4);
368 target = byteSwap(target);
371 inline void get(ByteStream::ReadIterator & source, uint16 & target)
373 source.get(&target, 2);
374 target = byteSwap(target);
377 inline void get(ByteStream::ReadIterator & source, int16 & target)
379 source.get(&target, 2);
380 target = byteSwap(target);
383 inline void get(ByteStream::ReadIterator & source, uint8 & target)
385 source.get(&target, 1);
388 inline void get(ByteStream::ReadIterator & source, int8 & target)
390 source.get(&target, 1);
393 inline void get(ByteStream::ReadIterator & source, unsigned char * const target, const unsigned int targetSize)
395 source.get(target, targetSize);
398 inline void get(ByteStream::ReadIterator & source, bool & target)
400 source.get(&target, 1);
404 ////////////////////////////////////////////////////////////////////////////////
407 inline void put(ByteStream & target, ByteStream::ReadIterator & source)
409 target.put(source.getBuffer(), source.getSize());
410 source.advance(source.getSize());
413 inline void put(ByteStream & target, const double value)
415 double temp = byteSwap(value);
416 target.put(&temp, 8);
419 inline void put(ByteStream & target, const float value)
421 float temp = byteSwap(value);
422 target.put(&temp, 4);
425 inline void put(ByteStream & target, const uint64 value)
427 uint64 temp = byteSwap(value);
428 target.put(&temp, 8);
431 inline void put(ByteStream & target, const int64 value)
433 int64 temp = byteSwap(value);
434 target.put(&temp, 8);
437 inline void put(ByteStream & target, const uint32 value)
439 uint32 temp = byteSwap(value);
440 target.put(&temp, 4);
443 inline void put(ByteStream & target, const int32 value)
445 int32 temp = byteSwap(value);
446 target.put(&temp, 4);
449 inline void put(ByteStream & target, const uint16 value)
451 uint16 temp = byteSwap(value);
452 target.put(&temp, 2);
455 inline void put(ByteStream & target, const int16 value)
457 int16 temp = byteSwap(value);
458 target.put(&temp, 2);
461 inline void put(ByteStream & target, const uint8 value)
463 target.put(&value, 1);
466 inline void put(ByteStream & target, const int8 value)
468 target.put(&value, 1);
471 inline void put(ByteStream & target, const bool & source)
473 target.put(&source, 1);
477 inline void put(ByteStream & target, const unsigned char * const source, const unsigned int sourceSize)
479 target.put(source, sourceSize);
482 inline void put(ByteStream & target, const ByteStream & source)
484 target.put(source.begin().getBuffer(), source.begin().getSize());
487 void get(ByteStream::ReadIterator & source, std::string & target);
488 void put(ByteStream & target, const std::string & source);
491 ////////////////////////////////////////////////////////////////////////////////
494 class AutoVariableBase
496 public:
497 AutoVariableBase();
498 virtual ~AutoVariableBase();
500 virtual void pack(ByteStream & target) const = 0;
501 virtual void unpack(ByteStream::ReadIterator & source) = 0;
505 ////////////////////////////////////////////////////////////////////////////////
508 class AutoByteStream
510 public:
511 AutoByteStream();
512 virtual ~AutoByteStream();
513 void addVariable(AutoVariableBase & newVariable);
514 virtual const unsigned int getItemCount() const;
515 virtual void pack(ByteStream & target) const;
516 virtual void unpack(ByteStream::ReadIterator & source);
517 protected:
518 std::vector<AutoVariableBase *> members;
519 private:
520 AutoByteStream(const AutoByteStream & source);
524 ////////////////////////////////////////////////////////////////////////////////
527 template<class ValueType>
528 class AutoVariable : public AutoVariableBase
530 public:
531 AutoVariable();
532 explicit AutoVariable(const ValueType & source);
533 virtual ~AutoVariable();
535 const ValueType & get() const;
536 virtual void pack(ByteStream & target) const;
537 void set(const ValueType & rhs);
538 virtual void unpack(ByteStream::ReadIterator & source);
540 private:
541 ValueType value;
544 template<class ValueType>
545 AutoVariable<ValueType>::AutoVariable() :
546 AutoVariableBase(),
547 value()
551 template<class ValueType>
552 AutoVariable<ValueType>::AutoVariable(const ValueType & source) :
553 AutoVariableBase(),
554 value(source)
558 template<class ValueType>
559 AutoVariable<ValueType>::~AutoVariable()
563 template<class ValueType>
564 const ValueType & AutoVariable<ValueType>::get() const
566 return value;
569 template<class ValueType>
570 void AutoVariable<ValueType>::pack(ByteStream & target) const
572 Base::put(target, value);
575 template<class ValueType>
576 void AutoVariable<ValueType>::set(const ValueType & rhs)
578 value = rhs;
581 template<class ValueType>
582 void AutoVariable<ValueType>::unpack(ByteStream::ReadIterator & source)
584 Base::get(source, value);
588 ////////////////////////////////////////////////////////////////////////////////
591 template<class ValueType>
592 class AutoArray : public AutoVariableBase
594 public:
595 AutoArray();
596 AutoArray(const AutoArray & source);
597 ~AutoArray();
599 const std::vector<ValueType> & get() const;
600 void set(const std::vector<ValueType> & source);
602 virtual void pack(ByteStream & target) const;
603 virtual void unpack(ByteStream::ReadIterator & source);
605 private:
606 std::vector<ValueType> array;
609 template<class ValueType>
610 inline AutoArray<ValueType>::AutoArray()
614 template<class ValueType>
615 inline AutoArray<ValueType>::AutoArray(const AutoArray & source) :
616 array(source.array)
620 template<class ValueType>
621 inline AutoArray<ValueType>::~AutoArray()
625 template<class ValueType>
626 inline const std::vector<ValueType> & AutoArray<ValueType>::get() const
628 return array;
631 template<class ValueType>
632 inline void AutoArray<ValueType>::set(const std::vector<ValueType> & source)
634 array = source;
637 template<class ValueType>
638 inline void AutoArray<ValueType>::pack(ByteStream & target) const
640 unsigned int arraySize = array.size();
641 Base::put(target, arraySize);
643 typename std::vector<ValueType>::const_iterator i;
644 for(i = array.begin(); i != array.end(); ++i)
646 ValueType v = (*i);
647 Base::put(target, v);
651 template<class ValueType>
652 inline void AutoArray<ValueType>::unpack(ByteStream::ReadIterator & source)
654 unsigned int arraySize;
655 Base::get(source, arraySize);
656 ValueType v;
658 if (arraySize > MAX_ARRAY_SIZE)
659 arraySize = 0;
661 for(unsigned int i = 0; i < arraySize; ++i)
663 Base::get(source, v);
664 array.push_back(v);
669 #ifdef EXTERNAL_DISTRO
671 #endif
673 #endif