00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013
00014 BEGIN_GIGABASE_NAMESPACE
00015
00016 #ifdef index // at some platform index(s,c) is defined strchr(s,x)
00017 #undef index
00018 #endif
00019
00020 #ifdef rindex // at some platform rindex(s,c) is defined strrchr(s,x)
00021 #undef rindex
00022 #endif
00023
00027 class GIGABASE_DLL_ENTRY dbAnyArray {
00028 friend class dbTableDescriptor;
00029 protected:
00030 size_t len;
00031
00032 public:
00033 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00034 {
00035 aArray->len = length;
00036 *(void**)(aArray+1) = data;
00037 }
00042 size_t length() const { return len; }
00043
00048 void const* base() const { return *(void**)(this+1); }
00049 };
00050
00054 template<class T>
00055 class dbArray : public dbAnyArray {
00056 friend class dbTableDescriptor;
00057 protected:
00058 T* data;
00059 size_t allocated;
00060
00061 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00062 {
00063 dbArray<T>* array = (dbArray<T>*)aArray;
00064 array->len = length;
00065 if (array->allocated) {
00066 delete[] array->data;
00067 }
00068 if (data != NULL || length == 0) {
00069 array->data = (T*)data;
00070 array->allocated = 0;
00071 } else {
00072 array->data = new T[length];
00073 array->allocated = length;
00074 }
00075 }
00076
00077 inline void memcpy(T* dst, T const* src, size_t len) {
00078 int n = (int)len;
00079 while (--n >= 0) {
00080 *dst++ = *src++;
00081 }
00082 }
00083
00084 inline void memmove(T* dst, T const* src, size_t len) {
00085 int n = (int)len;
00086 if (dst < src) {
00087 while (--n >= 0) {
00088 *dst++ = *src++;
00089 }
00090 } else {
00091 dst += n;
00092 src += n;
00093 while (--n >= 0) {
00094 *--dst = *--src;
00095 }
00096 }
00097 }
00098
00099 public:
00100 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00101 fd->type = fd->appType = dbField::tpArray;
00102 fd->dbsSize = sizeof(dbVarying);
00103 fd->alignment = 4;
00104 fd->arrayAllocator = arrayAllocator;
00105 return dbDescribeField(new dbFieldDescriptor(STRLITERAL("[]"), 0, sizeof(T), 0),
00106 *(T*)fd);
00107 }
00108
00112 dbArray() {
00113 data = NULL;
00114 len = 0;
00115 allocated = 0;
00116 }
00117
00122 dbArray(size_t size) {
00123 data = (size != 0) ? new T[size] : NULL;
00124 len = size;
00125 allocated = size;
00126 }
00127
00135 dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00136 len = size;
00137 allocated = allocate;
00138 if (allocate != 0) {
00139 assert(allocate >= size);
00140 data = new T[allocate];
00141 memcpy(data, ptr, size);
00142 } else {
00143 data = (T*)ptr;
00144 }
00145 }
00146
00151 dbArray(dbArray<T> const& arr) {
00152 allocated = arr.allocated;
00153 len = arr.len;
00154 if (allocated) {
00155 data = new T[allocated];
00156 memcpy(data, arr.data, len);
00157 } else {
00158 data = arr.data;
00159 }
00160 }
00161
00165 ~dbArray() {
00166 if (allocated) {
00167 delete[] data;
00168 data = NULL;
00169 }
00170 }
00171
00176 dbArray<T>& operator = (dbArray<T> const& arr) {
00177 if (this == &arr) {
00178 return *this;
00179 }
00180 if (allocated) {
00181 delete[] data;
00182 }
00183 if ((len = arr.len) != 0) {
00184 data = new T[len];
00185 memcpy(data, arr.data, len);
00186 }
00187 allocated = len;
00188 return *this;
00189 }
00190
00195 T const& last() {
00196 assert(len > 0);
00197 return data[len-1];
00198 }
00199
00207 void assign(T const* ptr, size_t size, bool copy = true) {
00208 if (allocated) {
00209 delete[] data;
00210 }
00211 len = size;
00212 if (copy && size != 0) {
00213 data = new T[size];
00214 memcpy(data, ptr, size);
00215 allocated = size;
00216 } else {
00217 data = (T*)ptr;
00218 allocated = 0;
00219 }
00220 }
00221
00227 T const& operator [](size_t index) const {
00228 assert(index < len);
00229 return data[index];
00230 }
00231
00237 void putat(size_t index, T const& value) {
00238 assert(index < len);
00239 if (!allocated) {
00240 T* copy = new T[len];
00241 memcpy(copy, data, len);
00242 data = copy;
00243 allocated = len;
00244 }
00245 data[index] = value;
00246 }
00247
00253 T const& getat(size_t index) const {
00254 assert(index < len);
00255 return data[index];
00256 }
00257
00261 void clear() {
00262 if (allocated) {
00263 delete[] data;
00264 }
00265 data = NULL;
00266 len = 0;
00267 allocated = 0;
00268 }
00269
00274 void resize(size_t size) {
00275 if (size > len && size > allocated) {
00276 T* p = new T[size];
00277 memcpy(p, data, len);
00278 if (allocated) {
00279 delete[] data;
00280 }
00281 data = p;
00282 allocated = size;
00283 }
00284 len = size;
00285 }
00286
00291 void append(T const& value) {
00292 insert(value, len);
00293 }
00294
00300 void insert(T const& value, size_t index = 0) {
00301 assert(index <= len);
00302 if (len >= allocated) {
00303 size_t newSize = len == 0 ? 8 : len*2;
00304 T* p = new T[newSize];
00305 memcpy(p, data, index);
00306 p[index] = value;
00307 memcpy(p+index+1, data+index, (len-index));
00308 if (allocated) {
00309 delete[] data;
00310 }
00311 data = p;
00312 allocated = newSize;
00313 } else {
00314 memmove(data+index+1, data+index, (len-index));
00315 data[index] = value;
00316 }
00317 len += 1;
00318 }
00319
00324 void remove(size_t index) {
00325 assert(index < len);
00326 len -= 1;
00327 if (index != len && !allocated) {
00328 T* p = new T[len];
00329 memcpy(p, data, index);
00330 memcpy(p+index, data+index+1, (len-index));
00331 allocated = len;
00332 data = p;
00333 } else {
00334 memmove(data+index, data+index+1, (len-index));
00335 }
00336 }
00337
00342 T const* get() const { return data; }
00343
00348 T* update() {
00349 if (!allocated) {
00350 T* copy = new T[len];
00351 memcpy(copy, data, len);
00352 data = copy;
00353 allocated = len;
00354 }
00355 return data;
00356 }
00357 };
00358
00364 template<class T>
00365 int index(dbArray<T> const& a, T value) {
00366 for (int i = 0, n = a.length(); i < n; i++) {
00367 if (a[i] == value) {
00368 return i;
00369 }
00370 }
00371 return -1;
00372 }
00373
00379 template<class T>
00380 int rindex(dbArray<T> const& a, T value) {
00381 int i = a.length();
00382 while (--i >= 0 && a[i] != value);
00383 return i;
00384 }
00385
00386 END_GIGABASE_NAMESPACE
00387
00388 #endif
00389