00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00054
00055
00056
00057
00058
00059 class HLA_EXPORT __HLAbuffer
00060 {
00061 private:
00062
00063
00064 typedef std::map<char*,__HLAbuffer*> BufferList;
00065 static BufferList gBuffers;
00066
00067
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
00086 bool mUserAllocated;
00087
00088 const void* mShakeThat;
00089 int mShakeValue;
00090
00091 __HLAbuffer(size_t capacity)
00092 : mUserAllocated(false), mShakeThat(NULL)
00093 {
00094 __assert_endianess();
00095
00096 mCapacity = (size_t)(capacity*1.5);
00097 mBegin = (char*)calloc(1, mCapacity);
00098
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
00107 gBuffers[mBegin + mCapacity-1] = this;
00108 }
00109
00110 virtual ~__HLAbuffer()
00111 {
00112 if (!mUserAllocated)
00113 free(mBegin);
00114
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;
00126
00127 newBuffer.mBegin = oldBegin;
00128 newBuffer.mCapacity = oldCapacity;
00129 gBuffers[oldBegin + oldCapacity-1] = &newBuffer;
00130 }
00131
00132 static BufferList::iterator __buffer_iterator(const void* __this)
00133 {
00134
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
00176
00177
00178 inline size_t __padding(size_t size, size_t boundary)
00179 { return boundary - ((size-1)%boundary + 1); }
00180
00181 }
00182
00183 #endif // _HLATYPES_BUFFER_HH
00184
00185
00186