00001
00002
00003
00004 #ifndef _ARR_H
00005 #define _ARR_H
00006
00007 #include "util.h"
00008 #include "var.h"
00009 #include "str.h"
00010
00011 namespace jvar
00012 {
00013
00020 class BArray
00021 {
00022 public:
00023 typedef int (*Compare)(const void*, const void*);
00024
00031 BArray(size_t elemsize, Compare comp) :
00032 mMemPtr(NULL),
00033 mElemSize((int)elemsize),
00034 mMaxLen(0),
00035 mComp(comp),
00036 mCountLocal(0),
00037 mFlags(0)
00038 {
00039 mCountPtr = &mCountLocal;
00040 }
00041 ~BArray()
00042 {
00043 }
00049 inline BArray(const BArray& src)
00050 {
00051 copyFrom((BArray&)src, false, false);
00052 }
00058 inline BArray(BArray& src)
00059 {
00060 copyFrom(src, false, false);
00061 }
00062 inline BArray& operator=(const BArray& src)
00063 {
00064 copyFrom((BArray&)src, false, false);
00065 return *this;
00066 }
00067 inline BArray& operator=(const BArray* src)
00068 {
00069 copyFrom((BArray&)*src, false, false);
00070 return *this;
00071 }
00072
00080 void useFixedMem(void* memptr, int* countptr, int maxlen);
00081
00085 void clear();
00086
00093 void* insert(int pos, const void* elem);
00094
00102 inline void* append(const void* elem)
00103 {
00104 return insert(length(), elem);
00105 }
00106
00114 inline void* add(const void* elem)
00115 {
00116 return addOrModify(elem, false);
00117 }
00118
00127 void* addOrModify(const void* elem, bool modifyfound = true);
00128
00136 bool remove(int pos);
00137
00143 bool remove(const void* elem);
00144
00152 void* find(const void* elem);
00153
00160 inline void* get(int pos)
00161 {
00162 return (char*)mMemPtr + pos * mElemSize;
00163 }
00164
00170 inline int length()
00171 {
00172 return *mCountPtr;
00173 }
00174
00180 inline bool full()
00181 {
00182 return (*mCountPtr >= mMaxLen);
00183 }
00184
00190 inline void sort(Compare comp = NULL)
00191 {
00192 if (comp == NULL)
00193 {
00194 comp = mComp;
00195 }
00196 assert(comp);
00197 qsort(mMemPtr, *mCountPtr, mElemSize, comp);
00198 }
00199
00208 inline bool findPos(const void* findelem, int& pos)
00209 {
00210 return binSearch(findelem, pos);
00211 }
00212
00218 inline void reserve(int elemcount)
00219 {
00220 if (elemcount > mMaxLen)
00221 {
00222 ensureAlloc(elemcount);
00223 }
00224 }
00225
00226 private:
00227 void* mMemPtr;
00228 int mElemSize;
00229 int* mCountPtr;
00230 int mMaxLen;
00231 Compare mComp;
00232 int mCountLocal;
00233 Buffer mBuf;
00234
00235 public:
00239 uint mFlags;
00240
00241 public:
00242 enum
00243 {
00247 FLAG_FIXEDBUF = 0x1
00248 };
00249
00250 protected:
00251 void copyFrom(BArray& src, bool alloconly, bool move);
00252 bool binSearch(const void* findelem, int& pos);
00253 void ensureAlloc(int desiredlen);
00254
00255
00256 };
00257
00267 template <class T>
00268 class Iter
00269 {
00270 public:
00271 Iter() :
00272 mPos(-1),
00273 mObj(NULL),
00274 mKey(NULL)
00275 {
00276 }
00280 inline T* operator->()
00281 {
00282 return mObj;
00283 }
00287 inline T& operator*()
00288 {
00289 return *mObj;
00290 }
00294 inline T* operator&()
00295 {
00296 return mObj;
00297 }
00301 inline int pos()
00302 {
00303 return mPos;
00304 }
00308 inline const char* key()
00309 {
00310 return mKey;
00311 }
00312
00313 public:
00315 int mPos;
00316 T* mObj;
00317 const char* mKey;
00319 };
00320
00321
00328 template <class T>
00329 class ObjArray : public BArray
00330 {
00331 public:
00332 inline ObjArray() :
00333 BArray(sizeof(T), NULL),
00334 mSupportImpl(NULL)
00335 {
00336 }
00337
00338 inline ObjArray(Compare comp) :
00339 BArray(sizeof(T), comp),
00340 mSupportImpl(NULL)
00341 {
00342 }
00343
00344 inline ObjArray(const ObjArray& src) :
00345 BArray(sizeof(T), NULL)
00346 {
00347 copyFrom((ObjArray&)src);
00348 }
00349
00350 inline ObjArray(ObjArray& src) :
00351 BArray(sizeof(T), NULL)
00352 {
00353 copyFrom(src);
00354 }
00355
00356 inline ObjArray& operator=(const ObjArray& src)
00357 {
00358 copyFrom((ObjArray&)src);
00359 return *this;
00360 }
00361 inline ObjArray& operator=(const ObjArray* src)
00362 {
00363 copyFrom(*src);
00364 return *this;
00365 }
00366
00367 ~ObjArray()
00368 {
00369
00370
00371 for (int i = 0; i < BArray::length(); i++)
00372 {
00373 T* obj = (T*)BArray::get(i);
00374 obj->~T();
00375 }
00376
00377 delete mSupportImpl;
00378 }
00379
00387 inline T* insert(int pos)
00388 {
00389 T* obj = (T*)BArray::insert(pos, NULL);
00390
00391
00392
00393 return new(obj) T();
00394 }
00395
00404 inline T* insertCustom(int pos)
00405 {
00406
00407 return (T*)BArray::insert(pos, NULL);
00408 }
00409
00415 inline T* append()
00416 {
00417 T* obj = (T*)BArray::append(NULL);
00418
00419
00420
00421 return new(obj) T();
00422 }
00423
00432 T* addOrModify(const T* keyelem, bool modifyfound = true)
00433 {
00434 int pos;
00435
00436 if (BArray::binSearch(keyelem, pos))
00437 {
00438 if (modifyfound)
00439 {
00440 return get(pos);
00441 }
00442 else
00443 {
00444 return NULL;
00445 }
00446 }
00447
00448 T* obj = (T*)BArray::insert(pos, NULL);
00449
00450
00451
00452 return new(obj) T(*keyelem);
00453 }
00454
00462 inline T* add(const T* keyelem)
00463 {
00464 return addOrModify(keyelem, false);
00465 }
00466
00474 inline bool remove(const T* keyelem)
00475 {
00476 int pos;
00477 if (!binSearch(keyelem, pos))
00478 {
00479 return false;
00480 }
00481 return remove(pos);
00482 }
00483
00491 inline bool remove(int pos)
00492 {
00493 T* obj = get(pos);
00494 if (obj == NULL)
00495 {
00496 return NULL;
00497 }
00498
00499
00500
00501 obj->~T();
00502
00503
00504
00505 return BArray::remove(pos);
00506 }
00507
00515 inline T* find(const T* elem)
00516 {
00517 return (T*)BArray::find(elem);
00518 }
00519
00527 inline T* get(int pos)
00528 {
00529
00530
00531 if ((uint)pos >= length())
00532 {
00533 return NULL;
00534 }
00535 return (T*)BArray::get(pos);
00536 }
00537
00545 bool forEach(Iter<T>& iter)
00546 {
00547 iter.mPos++;
00548 if (iter.mPos < length())
00549 {
00550 iter.mObj = get(iter.mPos);
00551
00552
00553
00554 return true;
00555 }
00556 return false;
00557 }
00558
00566 bool forEachReverse(Iter<T>& iter)
00567 {
00568 if (iter.mPos == -1)
00569 {
00570 iter.mPos = length();
00571 }
00572 iter.mPos--;
00573 if (iter.mPos >= 0)
00574 {
00575 iter.mObj = get(iter.mPos);
00576
00577 return true;
00578 }
00579 return false;
00580 }
00581
00583 inline InterfaceImpl* setSupportImpl(InterfaceImpl* impl)
00584 {
00585 delete mSupportImpl;
00586 mSupportImpl = impl;
00587 return mSupportImpl;
00588 }
00589
00590 inline InterfaceImpl* getSupportImpl()
00591 {
00592 return mSupportImpl;
00593 }
00596 protected:
00598 InterfaceImpl* mSupportImpl;
00601 private:
00602
00603 void copyFrom(ObjArray& src)
00604 {
00605
00606
00607 BArray::copyFrom(src, true, false);
00608
00609
00610
00611 for (int i = 0; i < BArray::length(); i++)
00612 {
00613 T* obj = (T*)BArray::get(i);
00614 T* srcobj = (T*)src.get(i);
00615
00616
00617
00618 new(obj) T(*srcobj);
00619 }
00620
00621
00622
00623 if (src.mSupportImpl)
00624 {
00625 delete mSupportImpl;
00626 mSupportImpl = src.mSupportImpl->newImpl();
00627 }
00628 }
00629 };
00630
00631
00636 template <class T>
00637 class PropArray
00638 {
00639 public:
00640 PropArray() :
00641 mData(NULL),
00642 mIndex(NULL),
00643 mSupp(NULL)
00644 {
00645 mData.reserve(INITSIZE);
00646 mIndex.reserve(INITSIZE);
00647 }
00648
00649 ~PropArray()
00650 {
00651 }
00652
00661 T* addOrModify(const char* keyname, bool modifyfound = true)
00662 {
00663
00664 int pos;
00665
00666 if (indexFindPos(keyname, pos))
00667 {
00668
00669
00670
00671 if (modifyfound)
00672 {
00673 DataElem* dat = indexGet(pos);
00674 if (dat)
00675 {
00676 return &(dat->value);
00677 }
00678 }
00679 return NULL;
00680 }
00681
00682
00683
00684
00685 int addloc = mData.length();
00686
00687 DataElem* dat = mData.insert(addloc);
00688
00689
00690
00691 dat->key.set(keyname);
00692
00693
00694
00695 int* index = mIndex.insert(pos);
00696 if (index)
00697 {
00698 *index = addloc;
00699 }
00700
00701
00702
00703 return &(dat->value);
00704 }
00705
00713 inline T* add(const char* keyname)
00714 {
00715 return addOrModify(keyname, false);
00716 }
00717
00725 inline bool remove(const char* keyname)
00726 {
00727 int pos;
00728 if (indexFindPos(keyname, pos))
00729 {
00730 int* index = mIndex.get(pos);
00731 if (index)
00732 {
00733 mIndex.remove(pos);
00734 return mData.remove(*index);
00735 }
00736 }
00737 return false;
00738 }
00739
00747 inline T* get(const char* keyname)
00748 {
00749 int pos;
00750 if (indexFindPos(keyname, pos))
00751 {
00752 DataElem* dat = indexGet(pos);
00753 if (dat)
00754 {
00755 return &(dat->value);
00756 }
00757 }
00758
00759 return NULL;
00760 }
00761
00769 inline T* get(int pos)
00770 {
00771 DataElem* dat = mData.get(pos);
00772 if (dat)
00773 {
00774 return &(dat->value);
00775 }
00776 return NULL;
00777 }
00778
00786 inline const char* getKey(int pos)
00787 {
00788 DataElem* dat = mData.get(pos);
00789 if (dat)
00790 {
00791 return dat->key.get();
00792 }
00793 return NULL;
00794 }
00795
00801 inline int length()
00802 {
00803 return mData.length();
00804 }
00805
00813 bool forEachSort(Iter<T>& iter)
00814 {
00815 iter.mPos++;
00816 if (iter.mPos < mIndex.length())
00817 {
00818 DataElem* dat = indexGet(iter.mPos);
00819 if (dat)
00820 {
00821 iter.mObj = &(dat->value);
00822 iter.mKey = dat->key.get();
00823 return true;
00824 }
00825 }
00826 return false;
00827 }
00828
00836 bool forEach(Iter<T>& iter)
00837 {
00838 iter.mPos++;
00839 if (iter.mPos < mData.length())
00840 {
00841 DataElem* dat = mData.get(iter.mPos);
00842 if (dat)
00843 {
00844 iter.mObj = &(dat->value);
00845 iter.mKey = dat->key.get();
00846 return true;
00847 }
00848 }
00849 return false;
00850 }
00851
00855 inline void clear()
00856 {
00857 mData.clear();
00858 mIndex.clear();
00859 mClassName.clear();
00860 mSupp = NULL;
00861 }
00862
00864 inline void setClassName(const char* name)
00865 {
00866 mClassName.set(name);
00867 }
00868 inline const char* getClassName()
00869 {
00870 return mClassName.get();
00871 }
00872
00873 inline void setSuppData(void* supp)
00874 {
00875 mSupp = supp;
00876 }
00877 inline void* getSuppData()
00878 {
00879 return mSupp;
00880 }
00881 inline InterfaceImpl* setSupportImpl(InterfaceImpl* impl)
00882 {
00883 return mData.setSupportImpl(impl);
00884 }
00885
00886 inline InterfaceImpl* getSupportImpl()
00887 {
00888 return mData.getSupportImpl();
00889 }
00892 private:
00893 enum
00894 {
00895 INITSIZE = 2,
00896 FIXEDSTRSIZE = 24
00897 };
00898
00899 typedef FixedStr<FIXEDSTRSIZE> PropKeyStr;
00900 struct DataElem
00901 {
00902 PropKeyStr key;
00903 T value;
00904 };
00905
00906 ObjArray<DataElem> mData;
00907 ObjArray<int> mIndex;
00908 PropKeyStr mClassName;
00909 void* mSupp;
00910
00911 private:
00912
00913 bool indexFindPos(const char* findelem, int& pos)
00914 {
00915 if (mIndex.length() == 0 || findelem == NULL)
00916 {
00917 pos = 0;
00918 return false;
00919 }
00920
00921 int low = 0;
00922 int high = mIndex.length() - 1;
00923 while (low <= high)
00924 {
00925 int mid = (low + high) / 2;
00926
00927
00928
00929
00930 DataElem* dat = indexGet(mid);
00931
00932 int res = strcmp(dat->key.get(), findelem);
00933
00934 if (res == 0)
00935 {
00936 pos = mid;
00937 return true;
00938 }
00939 else if (res < 0)
00940 {
00941 low = mid + 1;
00942 }
00943 else
00944 {
00945 high = mid - 1;
00946 }
00947 }
00948
00949 pos = low;
00950 return false;
00951 }
00952
00953 inline DataElem* indexGet(int pos)
00954 {
00955 int* index = mIndex.get(pos);
00956 if (index)
00957 {
00958 return mData.get(*index);
00959 }
00960 return NULL;
00961 }
00962 };
00963
00964
00968 class StrArray : public ObjArray<std::string>
00969 {
00970 public:
00971 StrArray() :
00972 ObjArray(StrArray::compare)
00973 {
00974 }
00975
00983 inline std::string* add(const char* keyelem)
00984 {
00985 std::string s(keyelem);
00986 return ObjArray<std::string>::add(&s);
00987 }
00995 inline bool remove(const char* keyelem)
00996 {
00997 std::string s(keyelem);
00998 return ObjArray<std::string>::remove(&s);
00999 }
01007 inline std::string* find(const char* elem)
01008 {
01009 std::string s(elem);
01010 return ObjArray<std::string>::find(&s);
01011 }
01012
01013 public:
01014 static
01015 int compare(const void* e1, const void* e2)
01016 {
01017 const std::string* s1 = (std::string*)e1;
01018 const std::string* s2 = (std::string*)e2;
01019
01020 return s1->compare(s2->c_str());
01021 }
01022 };
01023
01024
01028 class KeywordArray
01029 {
01030 public:
01031 struct Entry
01032 {
01033 const char* keyword;
01034 uint value;
01035 };
01036
01043 KeywordArray(const Entry* arr, size_t arrsize) :
01044 mArr(arr),
01045 mArrSize(arrsize)
01046 {
01047 assert(arr && arrsize != 0);
01048 }
01049
01057 uint toValue(const char* keyword)
01058 {
01059 assert(keyword);
01060 for (size_t i = 0; i < mArrSize; i++)
01061 {
01062 if (strcasecmp(keyword, mArr[i].keyword) == 0)
01063 {
01064 return mArr[i].value;
01065 }
01066 }
01067 return (uint)-1;
01068 }
01069
01077 const char* toKeyword(uint value)
01078 {
01079 for (size_t i = 0; i < mArrSize; i++)
01080 {
01081 if (value == mArr[i].value)
01082 {
01083 return mArr[i].keyword;
01084 }
01085 }
01086 return NULL;
01087 }
01088
01089 private:
01090 const Entry* mArr;
01091 size_t mArrSize;
01092 };
01093
01094 }
01095
01096 #endif // _ARR_H