00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013
00014 BEGIN_FASTDB_NAMESPACE
00015
00019 class FASTDB_DLL_ENTRY dbAnyArray {
00020 friend class dbTableDescriptor;
00021 protected:
00022 size_t len;
00023
00024 public:
00025 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00026 {
00027 aArray->len = length;
00028 *(void**)(aArray+1) = data;
00029 }
00034 size_t length() const { return len; }
00035
00040 void const* base() const { return *(void*const*)(this+1); }
00041 };
00042
00043
00047 template<class T>
00048 class dbArray : public dbAnyArray {
00049 friend class dbTableDescriptor;
00050 protected:
00051 T* data;
00052 size_t allocated;
00053
00054 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00055 {
00056 dbArray* array = (dbArray*)aArray;
00057 array->len = length;
00058 if (array->allocated) {
00059 delete[] array->data;
00060 }
00061 if (data != NULL || length == 0) {
00062 array->data = (T*)data;
00063 array->allocated = 0;
00064 } else {
00065 array->data = new T[length];
00066 array->allocated = length;
00067 }
00068 }
00069
00070 inline void memcpy(T* dst, T const* src, size_t len) {
00071 int n = (int)len;
00072 while (--n >= 0) {
00073 *dst++ = *src++;
00074 }
00075 }
00076
00077 inline void memmove(T* dst, T const* src, size_t len) {
00078 int n = (int)len;
00079 if (dst < src) {
00080 while (--n >= 0) {
00081 *dst++ = *src++;
00082 }
00083 } else {
00084 dst += n;
00085 src += n;
00086 while (--n >= 0) {
00087 *--dst = *--src;
00088 }
00089 }
00090 }
00091
00092 public:
00093 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00094 fd->type = fd->appType = dbField::tpArray;
00095 fd->dbsSize = sizeof(dbVarying);
00096 fd->alignment = 4;
00097 fd->arrayAllocator = arrayAllocator;
00098 return dbDescribeField(new dbFieldDescriptor("[]", 0, sizeof(T), 0),
00099 *(T*)fd);
00100 }
00101
00105 dbArray() {
00106 data = NULL;
00107 len = 0;
00108 allocated = 0;
00109 }
00110
00115 dbArray(size_t size) {
00116 if (size != 0) {
00117 data = new T[size];
00118 }
00119 len = size;
00120 allocated = size;
00121 }
00122
00130 dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00131 len = size;
00132 allocated = allocate;
00133 if (allocate != 0) {
00134 assert(allocate >= size);
00135 data = new T[allocate];
00136 memcpy(data, ptr, size);
00137 } else {
00138 data = (T*)ptr;
00139 }
00140 }
00141
00146 dbArray(dbArray const& arr) {
00147 allocated = arr.allocated;
00148 len = arr.len;
00149 if (allocated) {
00150 data = new T[allocated];
00151 memcpy(data, arr.data, len);
00152 } else {
00153 data = arr.data;
00154 }
00155 }
00156
00160 ~dbArray() {
00161 if (allocated) {
00162 delete[] data;
00163 }
00164 }
00165
00170 dbArray& operator = (dbArray const& arr) {
00171 if (this == &arr) {
00172 return *this;
00173 }
00174 if (allocated) {
00175 delete[] data;
00176 }
00177 if ((len = arr.len) != 0) {
00178 data = new T[len];
00179 memcpy(data, arr.data, len);
00180 }
00181 allocated = len;
00182 return *this;
00183 }
00184
00189 T const& last() {
00190 assert(len > 0);
00191 return data[len-1];
00192 }
00193
00201 void assign(T const* ptr, size_t size, bool copy = true) {
00202 if (allocated) {
00203 delete[] data;
00204 }
00205 len = size;
00206 if (copy && size != 0) {
00207 data = new T[size];
00208 memcpy(data, ptr, size);
00209 allocated = size;
00210 } else {
00211 data = (T*)ptr;
00212 allocated = 0;
00213 }
00214 }
00215
00221 T const& operator [](size_t index) const {
00222 assert(index < len);
00223 return data[index];
00224 }
00225
00231 void putat(size_t index, T const& value) {
00232 assert(index < len);
00233 if (!allocated) {
00234 T* copy = new T[len];
00235 memcpy(copy, data, len);
00236 data = copy;
00237 allocated = len;
00238 }
00239 data[index] = value;
00240 }
00241
00242
00248 T const& getat(size_t index) const {
00249 assert(index < len);
00250 return data[index];
00251 }
00252
00256 void clear() {
00257 if (allocated) {
00258 delete[] data;
00259 }
00260 data = NULL;
00261 len = 0;
00262 allocated = 0;
00263 }
00264
00269 void resize(size_t size) {
00270 if (size > len && size > allocated) {
00271 T* p = new T[size];
00272 memcpy(p, data, len);
00273 if (allocated) {
00274 delete[] data;
00275 }
00276 data = p;
00277 allocated = size;
00278 }
00279 len = size;
00280 }
00281
00286 void append(T const& value) {
00287 insert(value, len);
00288 }
00289
00295 void insert(T const& value, size_t index = 0) {
00296 assert(index <= len);
00297 if (len >= allocated) {
00298 size_t newSize = len == 0 ? 8 : len*2;
00299 T* p = new T[newSize];
00300 memcpy(p, data, index);
00301 p[index] = value;
00302 memcpy(p+index+1, data+index, (len-index));
00303 if (allocated) {
00304 delete[] data;
00305 }
00306 data = p;
00307 allocated = newSize;
00308 } else {
00309 memmove(data+index+1, data+index, (len-index));
00310 data[index] = value;
00311 }
00312 len += 1;
00313 }
00314
00319 void remove(size_t index) {
00320 assert(index < len);
00321 len -= 1;
00322 if (index != len && !allocated) {
00323 T* p = new T[len];
00324 memcpy(p, data, index);
00325 memcpy(p+index, data+index+1, (len-index));
00326 allocated = len;
00327 data = p;
00328 } else {
00329 memmove(data+index, data+index+1, (len-index));
00330 }
00331 }
00332
00337 T const* get() const { return data; }
00338
00343 T* update() {
00344 if (!allocated) {
00345 T* copy = new T[len];
00346 memcpy(copy, data, len);
00347 data = copy;
00348 allocated = len;
00349 }
00350 return data;
00351 }
00352 };
00353
00354
00360 template<class T>
00361 int index(dbArray<T> const& a, T value) {
00362 for (int i = 0, n = a.length(); i < n; i++) {
00363 if (a[i] == value) {
00364 return i;
00365 }
00366 }
00367 return -1;
00368 }
00369
00375 template<class T>
00376 int rindex(dbArray<T> const& a, T value) {
00377 int i = a.length();
00378 while (--i >= 0 && a[i] != value);
00379 return i;
00380 }
00381
00382 END_FASTDB_NAMESPACE
00383
00384 #endif
00385