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