Home Page Toolkit Overview Using GML User Input Services Finger Tracker Calibrator Frame Grabber Service protocol Obtaining GML Installing GML Licence Developer Documentation Tcl/Tk API The GML Canvas Image processing Tcl Scripts Library List of Classes List of Files C/C++ API List of Classes List of Files |
gml_DynamicArray_T.h00001 // gml_DynamicArray_T.h -- 00002 // 00003 // See "gmlDynamicArray.h". 00004 // 00005 // Copyright (c) 1998-2004 CLIPS-IMAG 00006 // 00007 // See the file "gml_LicenseTerms.txt" for information on usage and redistribution 00008 // of this file, and for a DISCLAIMER OF ALL WARRANTIES. 00009 // 00010 // Created on August 29, 1998 (FB). 00011 00012 #include "gml/base/gml_DynamicArray.h" 00013 00014 #include "gml/base/gml_Alloc.h" 00015 00016 00017 static const int cWordBits = 32; // Number of bits per word in the bitmap 00018 // of used slots. 00019 static const int cWordSize = cWordBits / 8; // Size (in bytes) of a word. 00020 static const UInt32 cWordMask = (UInt32) (~ 0); // A word with all bits set. 00021 00022 00023 00024 // gml_TDynamicArray::Init -- 00025 00026 template <class T> 00027 gml_TError gml_TDynamicArray<T>::Init (gml_TBlockSize nbElem, 00028 gml_TBlockSize nbIncrease) 00029 { 00030 gml_TError err = gml_cNoError; 00031 00032 // init data members 00033 fNbIncrease = nbIncrease; 00034 00035 fMem = (T*)NULL; 00036 fNbElem = 0; 00037 fInUse = 0; 00038 00039 fBitmap = (UInt32*)NULL; 00040 fBMSize = 0; 00041 00042 err = this->Allocate (nbElem); 00043 00044 if (err != gml_cNoError) 00045 this->Dispose (); 00046 00047 return err; 00048 } 00049 00050 00051 00052 // gml_TDynamicArray::Dispose -- 00053 00054 template <class T> 00055 void gml_TDynamicArray<T>::Dispose () 00056 { 00057 gml_TestAndFree (fMem); 00058 fNbElem = 0; 00059 fInUse = 0; 00060 00061 gml_TestAndFree (fBitmap); 00062 fBMSize = 0; 00063 } 00064 00065 00066 00067 // gml_TDynamicArray::GetElem -- 00068 00069 template <class T> 00070 T* gml_TDynamicArray<T>::GetElem (gml_TBlockSize* index) 00071 { 00072 gml_TError err = gml_cNoError; 00073 00074 int i = 0; 00075 gml_TBlockSize j = 0; 00076 gml_TBlockSize theIndex; 00077 UInt32* bmWord; 00078 UInt32 theWord; 00079 00080 if (fInUse == fNbElem) 00081 err = this->Allocate (fNbElem + fNbIncrease); 00082 00083 if (err != gml_cNoError) 00084 return (T*)NULL; 00085 00086 bmWord = fBitmap; 00087 while ((j < fBMSize) && (*bmWord == cWordMask)) { 00088 bmWord++; 00089 j += 1; 00090 } 00091 00092 theWord = *bmWord; 00093 while (theWord & ((UInt32)1 << i)) 00094 i++; 00095 00096 // Mark this slot as "used" in the bitmap 00097 00098 *bmWord = theWord | ((UInt32)1 << i); 00099 fInUse ++; 00100 00101 theIndex = (j * cWordBits + i); 00102 if (index != (gml_TBlockSize*)NULL) 00103 *index = theIndex; 00104 00105 return fMem + theIndex; 00106 } 00107 00108 00109 00110 // gml_TDynamicArray::ReleaseElem -- 00111 00112 template <class T> 00113 void gml_TDynamicArray<T>::ReleaseElem (T* elem) 00114 { 00115 gml_TBlockSize elemInd = elem - fMem; 00116 UInt32 j = elemInd / cWordBits; 00117 UInt32 i = elemInd % cWordBits; 00118 00119 fBitmap[j] &= ~((UInt32)1 << i); 00120 fInUse --; 00121 } 00122 00123 00124 00125 00126 // gml_TDynamicArray::Allocate -- 00127 00128 template <class T> 00129 gml_TError gml_TDynamicArray<T>::Allocate (gml_TBlockSize nbElem) 00130 { 00131 gml_TError err; 00132 T* mem = (T*)NULL; 00133 UInt32* bitmap = (UInt32*)NULL; 00134 gml_TBlockSize bmSize; 00135 int div, mod; 00136 00137 if (nbElem == 0) 00138 return gml_cNoError; 00139 00140 // Allocate the new memory blocks for the array and the bitmap of used slots. 00141 00142 if ((err = gml_MallocAndZero (mem, nbElem)) != gml_cNoError) 00143 goto error; 00144 00145 bmSize = (nbElem - 1) / cWordBits + 1; 00146 if ((err = gml_MallocAndZero (bitmap, bmSize)) != gml_cNoError) 00147 goto error; 00148 00149 bzero ((void*)bitmap, bmSize * cWordSize); 00150 00151 // If number of elements in the new array is not a multiple of 00152 // the number of bits in a bitmap word, then set the last (unused) 00153 // bits to "slot in use" (bit = 1). 00154 00155 mod = nbElem % cWordBits; 00156 if (mod != 0) 00157 *(bitmap + (nbElem / cWordBits)) = (cWordMask << mod); 00158 00159 // Copy the old values if necessary (i.e. if this is not the first allocation), 00160 // and free the previous buffers. 00161 // We use memcpy because we know that the buffers don't overlap. 00162 00163 if (fMem != (T*)NULL) { 00164 memcpy ((void*)mem, (void*)fMem, fNbElem * sizeof(T)); 00165 00166 div = fNbElem / cWordBits; 00167 mod = fNbElem % cWordBits; 00168 memcpy ((void*)bitmap, (void*)fBitmap, div * cWordSize); 00169 00170 // If number of elements in the previous array is not a multiple of 00171 // the number of bits in a bitmap word, then clear the unused 00172 // bits while copying the last word. 00173 00174 if (mod != 0) 00175 *(bitmap + div) |= ((*(fBitmap + div)) & (cWordMask >> (cWordBits - mod))); 00176 00177 gml_Free (fMem); 00178 gml_Free (fBitmap); 00179 } 00180 00181 fMem = mem; 00182 fNbElem = nbElem; 00183 00184 fBitmap = bitmap; 00185 fBMSize = bmSize; 00186 00187 return err; 00188 00189 error: 00190 // error handling 00191 gml_TestAndFree (mem); 00192 gml_TestAndFree (bitmap); 00193 00194 return err; 00195 } 00196
Generated on Tue Jun 12 14:03:27 2007 for gml by
Doxygen 1.5.2.
|
Contact: julien (dot) letessier (at) gmail (dot) com.
Copyright (c) 2000-2007 CLIPS-IMAG Laboratory, Grenoble, France. All rights reserved. W3CXHTML 1.0 W3CCSS 2.0 |