HLAbuffer.hh

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 // HLAbuffer.hh - IEEE 1516.2 compliant datatypes
00003 // Copyright (C) 2008  Petr Gotthard <petr.gotthard@centrum.cz>
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License version 2.1, as published by the Free Software Foundation.
00008 //
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 //
00014 // $Id: HLAbuffer.hh,v 1.9 2009/04/02 19:58:10 erk Exp $
00015 // ----------------------------------------------------------------------------
00016 
00017 #ifndef _HLATYPES_BUFFER_HH
00018 #define _HLATYPES_BUFFER_HH
00019 
00020 #include <iostream>
00021 #include <map>
00022 #include <stdexcept>
00023 #include <cstdlib>
00024 
00025 #ifdef _MSC_VER
00026 typedef unsigned __int64  uint64_t;
00027 typedef __int64           int64_t;
00028 typedef unsigned __int32  uint32_t;
00029 typedef __int32           int32_t;
00030 typedef unsigned __int16  uint16_t;
00031 typedef __int16           int16_t;
00032 typedef unsigned __int8   uint8_t;
00033 typedef __int8            int8_t;
00034 #else
00035 #include <inttypes.h>
00036 #endif
00037 
00038 #if defined(_WIN32)
00039     #pragma warning(disable: 4251)
00040     #if defined(HLA_EXPORTS)
00041         #define HLA_EXPORT __declspec(dllexport)
00042     #else
00043         #define HLA_EXPORT __declspec(dllimport)
00044     #endif
00045 #else
00046     #define HLA_EXPORT
00047 #endif
00048 
00049 namespace libhla {
00050 
00051 HLA_EXPORT std::ostream& __print_buffer(std::ostream& stream, const void *buffer, size_t length);
00052 
00053 /* Caution:
00054  * This implementation assumes that there are no compiler-generated data in
00055  * the heap memory allocated for the __HLAbuffer struct.
00056  * All structures must have no virtual functions and no non-static members.
00057  */
00058 
00059 class HLA_EXPORT __HLAbuffer
00060 {
00061 private:
00062     // static buffer for all instantiations of the HLAdata template
00063     // indexed by "last pointers", i.e. pointers to the last byte in the buffer
00064     typedef std::map<char*,__HLAbuffer*> BufferList;
00065     static BufferList gBuffers;
00066 
00067     // used to verify that user set correct endianess
00068     static const bool __is_big_endian();
00069     static const bool __is_little_endian();
00070 
00071     void __assert_endianess()
00072     {
00073 #ifdef HOST_IS_BIG_ENDIAN
00074         if (!__is_big_endian())
00075             throw std::runtime_error("compile without -DHOST_IS_BIG_ENDIAN");
00076 #else
00077         if (!__is_little_endian())
00078             throw std::runtime_error("compile with -DHOST_IS_BIG_ENDIAN");
00079 #endif
00080     }
00081 
00082 public:
00083     char *mBegin;
00084     size_t mCapacity;
00085     // no automatic free() and realloc() for user allocated memory
00086     bool mUserAllocated;
00087     // parameters used during dynamic resizing
00088     const void* mShakeThat;
00089     int mShakeValue;
00090 
00091     __HLAbuffer(size_t capacity)
00092      : mUserAllocated(false), mShakeThat(NULL)
00093     {
00094         __assert_endianess();
00095         // exponential growth: capacity *= 1.5
00096         mCapacity = (size_t)(capacity*1.5);
00097         mBegin = (char*)calloc(1, mCapacity);
00098         // store "this" to a global table
00099         gBuffers[mBegin + mCapacity-1] = this;
00100     }
00101 
00102     __HLAbuffer(void *begin, size_t capacity)
00103       : mBegin((char*)begin), mCapacity(capacity), mUserAllocated(true), mShakeThat(NULL)
00104     {
00105         __assert_endianess();
00106         // store "this" to a global table
00107         gBuffers[mBegin + mCapacity-1] = this;
00108     }
00109 
00110     virtual ~__HLAbuffer()
00111     {
00112         if (!mUserAllocated)
00113             free(mBegin);
00114         // remove "this" from the global table
00115         gBuffers.erase(__buffer_iterator(mBegin));
00116     }
00117 
00118     void __exchange_buffers(__HLAbuffer& newBuffer)
00119     {
00120         char* oldBegin = mBegin;
00121         size_t oldCapacity = mCapacity;
00122 
00123         mBegin = newBuffer.mBegin;
00124         mCapacity = newBuffer.mCapacity;
00125         gBuffers[mBegin + mCapacity-1] = this; // update
00126 
00127         newBuffer.mBegin = oldBegin;
00128         newBuffer.mCapacity = oldCapacity;
00129         gBuffers[oldBegin + oldCapacity-1] = &newBuffer; // update
00130     }
00131 
00132     static BufferList::iterator __buffer_iterator(const void* __this)
00133     {
00134         // find the first pointer not less than "this", the last pointer
00135         BufferList::iterator result = gBuffers.lower_bound((char*)__this);
00136         if (result == gBuffers.end())
00137             throw std::runtime_error("HLAdata: bad pointer");
00138         return result;
00139     }
00140 
00141     static __HLAbuffer& __buffer(const void* __this)
00142     { return *(__buffer_iterator(__this)->second); }
00143 
00144 #ifndef NDEBUG
00145     static void __check_memory(const void* __this, size_t size)
00146     {
00147         const __HLAbuffer& buffer = __buffer(__this);
00148         if ((char*)__this + size > (char*)buffer.mBegin + buffer.mCapacity)
00149             throw std::length_error("HLAdata: data buffer overflow");
00150     }
00151 #endif
00152 
00153     virtual const size_t size() const = 0;
00154     virtual void __shake(const void* __that, int value, long resize) = 0;
00155 
00156     static void shake(const void* __that, int value, long resize)
00157     { __buffer(__that).__shake(__that, value, resize); }
00158 
00159     const char* data() const
00160     { return mBegin; }
00161 
00162     std::ostream& print(std::ostream& stream)
00163     {
00164 #ifndef NDEBUG
00165         __check_memory(mBegin, size());
00166 #endif
00167         return __print_buffer(stream, mBegin, size());
00168     }
00169 };
00170 
00171 #ifndef MAX
00172 #define MAX(a,b) (((a)>(b))?(a):(b))
00173 #endif
00174 
00175 /* Calculate the smallest nonnegative value of P that satisfies the following
00176  * formula: (offset+size+P) mod boundary = 0
00177  */
00178 inline size_t __padding(size_t size, size_t boundary)
00179 { return boundary - ((size-1)%boundary + 1); }
00180 
00181 } // namespace libhla
00182 
00183 #endif // _HLATYPES_BUFFER_HH
00184 
00185 // $Id: HLAbuffer.hh,v 1.9 2009/04/02 19:58:10 erk Exp $
00186 

Generated on Thu Apr 30 15:53:49 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5