00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013
00017 class FASTDB_DLL_ENTRY dbAnyArray {
00018 friend class dbTableDescriptor;
00019 protected:
00020 size_t len;
00021
00022 public:
00023 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00024 {
00025 aArray->len = length;
00026 *(void**)(aArray+1) = data;
00027 }
00032 size_t length() const { return len; }
00033
00038 void const* base() const { return *(void**)(this+1); }
00039 };
00040
00041
00045 template<class T>
00046 class dbArray : public dbAnyArray {
00047 friend class dbTableDescriptor;
00048 protected:
00049 T* data;
00050 size_t allocated;
00051
00052 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00053 {
00054 dbArray* array = (dbArray*)aArray;
00055 array->len = length;
00056 if (array->allocated) {
00057 delete[] array->data;
00058 }
00059 if (data != NULL || length == 0) {
00060 array->data = (T*)data;
00061 array->allocated = 0;
00062 } else {
00063 array->data = new T[length];
00064 array->allocated = length;
00065 }
00066 }
00067
00068 inline void memcpy(T* dst, T const* src, int n) {
00069 while (--n >= 0) {
00070 *dst++ = *src++;
00071 }
00072 }
00073
00074 inline void memmove(T* dst, T const* src, int n) {
00075 if (dst < src) {
00076 while (--n >= 0) {
00077 *dst++ = *src++;
00078 }
00079 } else {
00080 dst += n;
00081 src += n;
00082 while (--n >= 0) {
00083 *--dst = *--src;
00084 }
00085 }
00086 }
00087
00088 public:
00089 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00090 fd->type = fd->appType = dbField::tpArray;
00091 fd->dbsSize = sizeof(dbVarying);
00092 fd->alignment = 4;
00093 fd->arrayAllocator = arrayAllocator;
00094 return dbDescribeField(new dbFieldDescriptor("[]", 0, sizeof(T), 0),
00095 *(T*)fd);
00096 }
00097
00101 dbArray() {
00102 data = NULL;
00103 len = 0;
00104 allocated = 0;
00105 }
00106
00111 dbArray(size_t size) {
00112 if (size != 0) {
00113 data = new T[size];
00114 }
00115 len = size;
00116 allocated = size;
00117 }
00118
00126 dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00127 len = size;
00128 allocated = allocate;
00129 if (allocate != 0) {
00130 assert(allocate >= size);
00131 data = new T[allocate];
00132 memcpy(data, ptr, size);
00133 } else {
00134 data = (T*)ptr;
00135 }
00136 }
00137
00142 dbArray(dbArray const& arr) {
00143 allocated = arr.allocated;
00144 len = arr.len;
00145 if (allocated) {
00146 data = new T[allocated];
00147 memcpy(data, arr.data, len);
00148 } else {
00149 data = arr.data;
00150 }
00151 }
00152
00156 ~dbArray() {
00157 if (allocated) {
00158 delete[] data;
00159 }
00160 }
00161
00166 dbArray& operator = (dbArray const& arr) {
00167 if (this == &arr) {
00168 return *this;
00169 }
00170 if (allocated) {
00171 delete[] data;
00172 }
00173 if ((len = arr.len) != 0) {
00174 data = new T[len];
00175 memcpy(data, arr.data, len);
00176 }
00177 allocated = len;
00178 return *this;
00179 }
00180
00185 T const& last() {
00186 assert(len > 0);
00187 return data[len-1];
00188 }
00189
00197 void assign(T const* ptr, size_t size, bool copy = true) {
00198 if (allocated) {
00199 delete[] data;
00200 }
00201 len = size;
00202 if (copy && size != 0) {
00203 data = new T[size];
00204 memcpy(data, ptr, size);
00205 allocated = size;
00206 } else {
00207 data = (T*)ptr;
00208 allocated = 0;
00209 }
00210 }
00211
00217 T const& operator [](size_t index) const {
00218 assert(index < len);
00219 return data[index];
00220 }
00221
00227 void putat(size_t index, T const& value) {
00228 assert(index < len);
00229 if (!allocated) {
00230 T* copy = new T[len];
00231 memcpy(copy, data, len);
00232 data = copy;
00233 allocated = len;
00234 }
00235 data[index] = value;
00236 }
00237
00238
00244 T const& getat(size_t index) const {
00245 assert(index < len);
00246 return data[index];
00247 }
00248
00252 void clear() {
00253 if (allocated) {
00254 delete[] data;
00255 }
00256 data = NULL;
00257 len = 0;
00258 allocated = 0;
00259 }
00260
00265 void resize(size_t size) {
00266 if (size > len && size > allocated) {
00267 T* p = new T[size];
00268 memcpy(p, data, len);
00269 if (allocated) {
00270 delete[] data;
00271 }
00272 data = p;
00273 allocated = size;
00274 }
00275 len = size;
00276 }
00277
00282 void append(T const& value) {
00283 insert(value, len);
00284 }
00285
00291 void insert(T const& value, size_t index = 0) {
00292 assert(index <= len);
00293 if (len >= allocated) {
00294 size_t newSize = len == 0 ? 8 : len*2;
00295 T* p = new T[newSize];
00296 memcpy(p, data, index);
00297 p[index] = value;
00298 memcpy(p+index+1, data+index, (len-index));
00299 if (allocated) {
00300 delete[] data;
00301 }
00302 data = p;
00303 allocated = newSize;
00304 } else {
00305 memmove(data+index+1, data+index, (len-index));
00306 data[index] = value;
00307 }
00308 len += 1;
00309 }
00310
00315 void remove(size_t index) {
00316 assert(index < len);
00317 len -= 1;
00318 if (index != len && !allocated) {
00319 T* p = new T[len];
00320 memcpy(p, data, index);
00321 memcpy(p+index, data+index+1, (len-index));
00322 allocated = len;
00323 data = p;
00324 } else {
00325 memmove(data+index, data+index+1, (len-index));
00326 }
00327 }
00328
00333 T const* get() const { return data; }
00334 };
00335
00336
00342 template<class T>
00343 int index(dbArray<T> const& a, T value) {
00344 for (int i = 0, n = a.length(); i < n; i++) {
00345 if (a[i] == value) {
00346 return i;
00347 }
00348 }
00349 return -1;
00350 }
00351
00357 template<class T>
00358 int rindex(dbArray<T> const& a, T value) {
00359 int i = a.length();
00360 while (--i >= 0 && a[i] != value);
00361 return i;
00362 }
00363
00364
00365 #endif
00366