00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef CCXX_MISC_H_
00042 #define CCXX_MISC_H_
00043
00044 #ifndef CCXX_CONFIG_H_
00045 #include <cc++/config.h>
00046 #endif
00047
00048 #ifndef CCXX_THREAD_H_
00049 #include <cc++/thread.h>
00050 #endif
00051
00052 #include <fstream>
00053 #include <iostream>
00054
00055 #define KEYDATA_INDEX_SIZE 97
00056 #define KEYDATA_PAGER_SIZE 512
00057 #define KEYDATA_PATH_SIZE 256
00058
00059 #ifdef CCXX_NAMESPACES
00060 namespace ost {
00061 #endif
00062
00063 #if defined(__GNUC__) || !defined(__hpux)
00064 #pragma pack(1)
00065 #endif
00066
00067 typedef struct _keyval
00068 {
00069 struct _keyval *next;
00070 char val[1];
00071 } keyval_t;
00072
00073 typedef struct _keysym
00074 {
00075 struct _keysym *next;
00076 struct _keyval *data;
00077 const char **list;
00078 short count;
00079 char sym[1];
00080 } keysym_t;
00081
00082 typedef struct
00083 {
00084 char *keyword;
00085 char *value;
00086 } KEYDEF;
00087
00088 #if defined(__GNUC__) || !defined(__hpux)
00089 #pragma pack()
00090 #endif
00091
00092 #ifdef WIN32
00093 class CCXX_CLASS_EXPORT MemPager;
00094 class CCXX_CLASS_EXPORT SharedMemPager;
00095 #endif
00096
00112 class MemPager
00113 {
00114 private:
00115 unsigned int pagesize;
00116 unsigned int pages;
00117
00118 struct _page
00119 {
00120 struct _page *next;
00121 int used;
00122 } *page;
00123
00124 protected:
00134 virtual void* first(size_t size);
00135
00143 virtual void* alloc(size_t size);
00144
00154 char* first(char *str);
00155
00165 char* alloc(char *str);
00166
00176 MemPager(int pagesize = 4096);
00177
00181 void purge(void);
00182
00186 virtual ~MemPager();
00187
00188 public:
00195 inline int getPages(void)
00196 {return pages;};
00197 };
00198
00207 class SharedMemPager : public MemPager, public Mutex
00208 {
00209 protected:
00215 SharedMemPager(int pg = 4096);
00216
00220 void purge(void);
00221
00228 void* first(size_t size);
00229
00236 void* alloc(size_t size);
00237 };
00238
00306 class Keydata : protected MemPager
00307 {
00308 private:
00309 static std::ifstream cfgFile;
00310 static char lastpath[KEYDATA_PATH_SIZE + 1];
00311 static int count, sequence;
00312
00313 int link;
00314
00315 keysym_t *keys[KEYDATA_INDEX_SIZE];
00316
00323 unsigned getIndex(const char *sym);
00324
00325 protected:
00326 CCXX_MEMBER_EXPORT(keysym_t*) getSymbol(const char *sym, bool create);
00327
00339 CCXX_MEMBER_EXPORT(void) Load(const char *keypath,
00340 const char *environment = "CONFIG_KEYDATA");
00341
00354 CCXX_MEMBER_EXPORT(void) LoadPrefix(const char *prefix,
00355 const char *keypath, const char *environment = "CONFIG_KEYDATA");
00356
00365 CCXX_MEMBER_EXPORT(void) Load(KEYDEF *pairs);
00366
00367 public:
00371 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Keydata();
00372
00379 CCXX_MEMBER_EXPORT(CCXX_EMPTY) Keydata(const char *keypath, const char *environment="CONFIG_KEYDATA");
00380
00386 CCXX_MEMBER_EXPORT(virtual) ~Keydata();
00387
00395 CCXX_MEMBER_EXPORT(void) Unlink(void);
00396
00405 CCXX_MEMBER_EXPORT(int) getCount(const char *sym);
00406
00414 CCXX_MEMBER_EXPORT(const char*) getFirst(const char *sym);
00415
00423 CCXX_MEMBER_EXPORT(const char*) getLast(const char *sym);
00424
00433 CCXX_MEMBER_EXPORT(int) getIndex(char **data, int max);
00434
00443 CCXX_MEMBER_EXPORT(void) setValue(const char *sym, const char *data);
00444
00452 CCXX_MEMBER_EXPORT(const char * const*) getList(const char *sym);
00453
00460 CCXX_MEMBER_EXPORT(void) clrValue(const char *sym);
00461
00466 inline const char *operator[](const char *keyword)
00467 {return getLast(keyword);};
00468
00473 friend CCXX_EXPORT(void) endKeydata(void);
00474 };
00475
00519 class CCXX_CLASS_EXPORT StringTokenizer {
00520 public:
00526 static const char * const SPACE;
00527
00537
00538 class NoSuchElementException { };
00539
00544 class CCXX_CLASS_EXPORT iterator {
00545 friend class StringTokenizer;
00546 private:
00547 const StringTokenizer *myTok;
00548 const char *start;
00549 const char *tokEnd;
00550 const char *endp;
00551 char *token;
00552
00553
00554 iterator(const StringTokenizer &tok, const char *end)
00555 : myTok(&tok),tokEnd(0),endp(end),token(0) {}
00556
00557 iterator(const StringTokenizer &tok)
00558 : myTok(&tok),tokEnd(0),endp(myTok->str-1),token(0) {
00559 ++(*this);
00560 }
00561 public:
00562 iterator() : myTok(0),start(0),tokEnd(0),endp(0),token(0) {}
00563
00564
00565 virtual ~iterator() { if (token) *token='\0'; delete token; }
00566
00570
00571 iterator(const iterator& i) :
00572 myTok(i.myTok),start(i.start),tokEnd(i.tokEnd),
00573 endp(i.endp),token(0) {}
00574
00578
00579 iterator &operator = (const iterator &i) {
00580 myTok = i.myTok;
00581 start = i.start; endp = i.endp; tokEnd = i.tokEnd;
00582 token = 0;
00583 return *this;
00584 }
00585
00589 iterator &operator ++ () THROWS (NoSuchElementException);
00590
00599 const char* operator * () THROWS (NoSuchElementException);
00600
00607 inline char nextDelimiter() const {
00608 return (tokEnd) ? *tokEnd : '\0';
00609 }
00610
00615
00616 inline bool operator == (const iterator &other) const {
00617 return (endp == other.endp);
00618 }
00619
00624
00625 inline bool operator != (const iterator &other) const {
00626 return (endp != other.endp);
00627 }
00628 };
00629 private:
00630 friend class StringTokenizer::iterator;
00631 const char *str;
00632 const char *delim;
00633 bool skipAll, trim;
00634 iterator itEnd;
00635
00636 public:
00675 StringTokenizer (const char *str,
00676 const char *delim,
00677 bool skipAllDelim = false,
00678 bool trim = false);
00679
00689 StringTokenizer (const char *s);
00690
00694 iterator begin() const {
00695 return iterator(*this);
00696 }
00697
00702 void setDelimiters (const char *d) {
00703 delim = d;
00704 }
00705
00710 iterator begin(const char *d) {
00711 delim = d;
00712 return iterator(*this);
00713 }
00714
00718 const iterator& end() const { return itEnd; }
00719 };
00720
00721 #ifdef CCXX_NAMESPACES
00722 };
00723 #endif
00724
00725 #endif
00726