Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef Buffer_INCLUDE_ONCE
00033 #define Buffer_INCLUDE_ONCE
00034
00035 #include <vlCore/Object.hpp>
00036 #include <string.h>
00037
00038 namespace vl
00039 {
00040
00041
00042
00046 class Buffer: public Object
00047 {
00048 public:
00049 typedef enum
00050 {
00051 UserAllocatedBuffer,
00052 AutoAllocatedBuffer
00053 } EAllocationMode;
00054
00055 public:
00056 virtual const char* className() { return "vl::Buffer"; }
00057 Buffer()
00058 {
00059 VL_DEBUG_SET_OBJECT_NAME()
00060 mPtr = NULL;
00061 mByteCount = 0;
00062 mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
00063 mAllocationMode = AutoAllocatedBuffer;
00064 }
00065 Buffer(const Buffer& other): Object(other)
00066 {
00067 VL_DEBUG_SET_OBJECT_NAME()
00068 mPtr = NULL;
00069 mByteCount = 0;
00070 mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
00071 mAllocationMode = AutoAllocatedBuffer;
00072
00073 *this = other;
00074 }
00075 Buffer& operator=(const Buffer& other)
00076 {
00077 if ( mAllocationMode == AutoAllocatedBuffer)
00078 {
00079
00080 mAlignment = other.mAlignment;
00081
00082 resize(other.bytesUsed());
00083
00084 memcpy(mPtr, other.ptr(), bytesUsed());
00085 }
00086 else
00087 {
00088 VL_CHECK(mPtr);
00089 VL_CHECK(other.mPtr);
00090 VL_CHECK(mByteCount == other.mByteCount);
00091 memcpy(mPtr, other.ptr(), bytesUsed());
00092 }
00093 return *this;
00094 }
00095
00096
00097 void swap(Buffer& other)
00098 {
00099
00100 unsigned char* tmp_ptr = mPtr;
00101 size_t tmp_byte_count = mByteCount;
00102 size_t tmp_alignment = mAlignment;
00103
00104 mPtr = other.mPtr;
00105 mByteCount = other.mByteCount;
00106 mAlignment = other.mAlignment;
00107
00108 other.mPtr = tmp_ptr;
00109 other.mByteCount = tmp_byte_count;
00110 other.mAlignment = tmp_alignment;
00111 }
00112
00113 ~Buffer()
00114 {
00115 clear();
00116 }
00117
00118 void clear()
00119 {
00120 if ( mAllocationMode == AutoAllocatedBuffer )
00121 alignedFree(mPtr);
00122 mPtr = NULL;
00123 mByteCount = 0;
00124 }
00125
00126
00127 void resize(size_t byte_count, size_t alignment = 0)
00128 {
00129 VL_CHECK( mAllocationMode == AutoAllocatedBuffer );
00130
00131 if (byte_count == 0)
00132 {
00133 clear();
00134 return;
00135 }
00136
00137 alignment = alignment >= 1 ? alignment : mAlignment;
00138 if ( byte_count != mByteCount || alignment != mAlignment)
00139 {
00140 mAlignment = alignment;
00141
00142 unsigned char* ptr = NULL;
00143 if (byte_count)
00144 ptr = (unsigned char*)alignedMalloc(byte_count, mAlignment);
00145 if (mPtr)
00146 {
00147 if (byte_count)
00148 {
00149 size_t min = mByteCount < byte_count ? mByteCount : byte_count;
00150
00151 memcpy(ptr, mPtr, min);
00152 }
00153
00154 alignedFree(mPtr);
00155 }
00156
00157 mPtr = ptr;
00158
00159 mByteCount = byte_count;
00160 }
00161 }
00162
00170 void setUserAllocatedBuffer(void* ptr, size_t bytes)
00171 {
00172 clear();
00173 mPtr = (unsigned char*)ptr;
00174 mByteCount = bytes;
00175 mAlignment = 0;
00176 mAllocationMode = UserAllocatedBuffer;
00177 }
00178
00179 void setAllocationMode( EAllocationMode mode )
00180 {
00181 if ( mAllocationMode != mode )
00182 {
00183 clear();
00184 mAllocationMode = mode;
00185
00186 mPtr = 0;
00187 mByteCount = 0;
00188 mAlignment = 0;
00189 }
00190 }
00191
00192 EAllocationMode allocationMode() const { return mAllocationMode; }
00193
00194 size_t bytesUsed() const { return mByteCount; }
00195
00196 bool empty() const { return mByteCount == 0; }
00197
00198 unsigned char* ptr() { return mPtr; }
00199
00200 const unsigned char* ptr() const { return mPtr; }
00201
00202 size_t alignment() const { return mAlignment; }
00203
00204
00205
00206 static void *alignedMalloc(size_t bytes, size_t alignment)
00207 {
00208
00209 if ( alignment & (alignment-1))
00210 return NULL;
00211
00212 size_t actual_byte_count = bytes + alignment - 1;
00213
00214
00215 actual_byte_count += sizeof(int);
00216
00217
00218 char *original_ptr = new char[actual_byte_count];
00219
00220 if (original_ptr == NULL)
00221 return NULL;
00222
00223
00224 char *base_ptr = (char *)original_ptr + sizeof(int);
00225
00226
00227 #if 1
00228
00229 unsigned long long long_long_ptr = base_ptr - (char*)0;
00230 while( long_long_ptr % alignment ) ++long_long_ptr;
00231 void *aligned_ptr = (char*)0 + long_long_ptr;
00232 #else
00233
00234 void *aligned_ptr = (void *) (((unsigned long long)base_ptr + alignment - 1) & ~((unsigned long long)alignment - 1));
00235 #endif
00236
00237
00238 int delta = (int)((char*)aligned_ptr - (char*)original_ptr);
00239
00240
00241 *((int *)aligned_ptr - 1) = delta;
00242
00243 return aligned_ptr;
00244 }
00245
00246 static void alignedFree(void *ptr)
00247 {
00248 if (ptr == NULL)
00249 return;
00250
00251
00252 int delta = *( (int *)ptr - 1);
00253
00254
00255 char *original_ptr = (char*)ptr - delta;
00256
00257
00258 delete [] original_ptr;
00259 }
00260
00261 protected:
00262 unsigned char* mPtr;
00263 size_t mByteCount;
00264 size_t mAlignment;
00265 EAllocationMode mAllocationMode;
00266 };
00267
00268 }
00269
00270 #endif