00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013
00014 BEGIN_GIGABASE_NAMESPACE
00015
00019 class GIGABASE_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**)(this+1); }
00041 };
00042
00046 template<class T>
00047 class dbArray : public dbAnyArray {
00048 friend class dbTableDescriptor;
00049 protected:
00050 T* data;
00051 size_t allocated;
00052
00053 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00054 {
00055 dbArray<T>* array = (dbArray<T>*)aArray;
00056 array->len = length;
00057 if (array->allocated) {
00058 delete[] array->data;
00059 }
00060 if (data != NULL || length == 0) {
00061 array->data = (T*)data;
00062 array->allocated = 0;
00063 } else {
00064 array->data = new T[length];
00065 array->allocated = length;
00066 }
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(STRLITERAL("[]"), 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<T> 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 data = NULL;
00164 }
00165 }
00166
00171 dbArray<T>& operator = (dbArray<T> const& arr) {
00172 if (this == &arr) {
00173 return *this;
00174 }
00175 if (allocated) {
00176 delete[] data;
00177 }
00178 if ((len = arr.len) != 0) {
00179 data = new T[len];
00180 memcpy(data, arr.data, len);
00181 }
00182 allocated = len;
00183 return *this;
00184 }
00185
00190 T const& last() {
00191 assert(len > 0);
00192 return data[len-1];
00193 }
00194
00202 void assign(T const* ptr, size_t size, bool copy = true) {
00203 if (allocated) {
00204 delete[] data;
00205 }
00206 len = size;
00207 if (copy && size != 0) {
00208 data = new T[size];
00209 memcpy(data, ptr, size);
00210 allocated = size;
00211 } else {
00212 data = (T*)ptr;
00213 allocated = 0;
00214 }
00215 }
00216
00222 T const& operator [](size_t index) const {
00223 assert(index < len);
00224 return data[index];
00225 }
00226
00232 void putat(size_t index, T const& value) {
00233 assert(index < len);
00234 if (!allocated) {
00235 T* copy = new T[len];
00236 memcpy(copy, data, len);
00237 data = copy;
00238 allocated = len;
00239 }
00240 data[index] = value;
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
00359 template<class T>
00360 int index(dbArray<T> const& a, T value) {
00361 for (int i = 0, n = a.length(); i < n; i++) {
00362 if (a[i] == value) {
00363 return i;
00364 }
00365 }
00366 return -1;
00367 }
00368
00374 template<class T>
00375 int rindex(dbArray<T> const& a, T value) {
00376 int i = a.length();
00377 while (--i >= 0 && a[i] != value);
00378 return i;
00379 }
00380
00381 END_GIGABASE_NAMESPACE
00382
00383 #endif
00384