Changeset 15429


Ignore:
Timestamp:
2008-05-14T11:14:32+12:00 (16 years ago)
Author:
mdewsnip
Message:

(Adding new db support) Moved gdbmclass out of infodbclass into its own file.

Location:
gsdl/trunk/lib
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • gsdl/trunk/lib/Makefile.in

    r15420 r15429  
    9090HEADERS = \
    9191  cfgread.h        cnfgable.h       cnfgator.h       display.h \
    92   fileutil.h       gsdlsitecfg.h    gsdltimes.h      gsdltools.h \
    93   gsdlunicode.h    infodbclass.h    md5.h            OIDtools.h \
    94   phrases.h        text_t.h         $(CORBAHEADERS)  gsdlconf.h
     92  fileutil.h       gdbmclass.h      gsdlsitecfg.h    gsdltimes.h \
     93  gsdltools.h      gsdlunicode.h    infodbclass.h    md5.h \
     94  OIDtools.h       phrases.h        text_t.h         $(CORBAHEADERS)  gsdlconf.h
    9595
    9696SOURCES = \
    9797  cfgread.cpp      cnfgable.cpp     cnfgator.cpp     display.cpp \
    98   fileutil.cpp     gsdlsitecfg.cpp  gsdltimes.cpp    gsdltools.cpp \
    99   gsdlunicode.cpp  infodbclass.cpp  md5.cpp          OIDtools.cpp \
    100   phrases.cpp      text_t.cpp       $(CORBASOURCES)
     98  fileutil.cpp     gdbmclass.cpp    gsdlsitecfg.cpp  gsdltimes.cpp \
     99  gsdltools.cpp    gsdlunicode.cpp  infodbclass.cpp  md5.cpp \
     100  OIDtools.cpp     phrases.cpp      text_t.cpp       $(CORBASOURCES)
    101101
    102102OBJECTS = \
    103103  cfgread.o        cnfgable.o       cnfgator.o       display.o \
    104   fileutil.o       gsdlsitecfg.o    gsdltimes.o      gsdltools.o \
    105   gsdlunicode.o    infodbclass.o    md5.o            OIDtools.o \
    106   phrases.o        text_t.o         $(CORBAOBJECTS)
     104  fileutil.o       gdbmclass.o      gsdlsitecfg.o    gsdltimes.o \
     105  gsdltools.o      gsdlunicode.o    infodbclass.o    md5.o \
     106  OIDtools.o       phrases.o        text_t.o         $(CORBAOBJECTS)
    107107
    108108
  • gsdl/trunk/lib/infodbclass.cpp

    r15420 r15429  
    2525
    2626#include "infodbclass.h"
    27 #include "unitool.h"
    28 #include "gsdlunicode.h"
    29 #include "fileutil.h"
    30 #include "OIDtools.h"
    31 #include <stdlib.h>
    3227
    3328
     
    151146  return &((*here).second);
    152147}
    153 
    154 
    155 
    156 gdbmclass::~gdbmclass()
    157 {
    158   closedatabase();
    159 }
    160 
    161 // returns true if opened
    162 bool gdbmclass::opendatabase (const text_t &filename, int mode, int num_retrys,
    163 #ifdef __WIN32__
    164                   bool need_filelock
    165 #else
    166                               bool
    167 #endif
    168                   )
    169 {
    170   text_t data_location;
    171   int block_size = 512;
    172  
    173   if (gdbmfile != NULL) {
    174     if (openfile == filename) return true;
    175     else closedatabase ();
    176   }
    177 
    178   openfile = filename;
    179  
    180   char *namebuffer = filename.getcstr();
    181   do {
    182 #ifdef __WIN32__
    183     gdbmfile = gdbm_open (namebuffer, block_size, mode, 00664, NULL, (need_filelock) ? 1 : 0);
    184 #else
    185     gdbmfile = gdbm_open (namebuffer, block_size, mode, 00664, NULL);
    186 #endif
    187     --num_retrys;
    188   } while (num_retrys>0 && gdbmfile==NULL &&
    189        (gdbm_errno==GDBM_CANT_BE_READER || gdbm_errno==GDBM_CANT_BE_WRITER));
    190   delete []namebuffer;
    191  
    192   if (gdbmfile == NULL && logout != NULL) {
    193     outconvertclass text_t2ascii;
    194     (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
    195   }
    196 
    197   return (gdbmfile != NULL);
    198 }
    199 
    200 
    201 void gdbmclass::closedatabase ()
    202 {
    203   if (gdbmfile == NULL) return;
    204  
    205   gdbm_close (gdbmfile);
    206   gdbmfile = NULL;
    207   openfile.clear();
    208 }
    209 
    210 
    211 // returns true on success
    212 bool gdbmclass::setinfo (const text_t &key, const infodbclass &info)
    213 {
    214   if (gdbmfile == NULL) return false;
    215 
    216   text_t subkey;
    217   text_t data;
    218 
    219   // get all the keys and values
    220   infodbclass::const_iterator info_here = info.begin();
    221   infodbclass::const_iterator info_end = info.end();
    222   while (info_here != info_end) {
    223     // add the key
    224     subkey.clear();
    225     subkey.push_back('<');
    226     text_t::const_iterator subkey_here = (*info_here).first.begin();
    227     text_t::const_iterator subkey_end = (*info_here).first.end();
    228     while (subkey_here != subkey_end) {
    229       if (*subkey_here == '>') {
    230     subkey.push_back('\\'); subkey.push_back('>');
    231       } else if (*subkey_here == '\n') {
    232     subkey.push_back('\\'); subkey.push_back('n');
    233       } else if (*subkey_here == '\r') {
    234     subkey.push_back('\\'); subkey.push_back('r');
    235       } else if (*subkey_here == '\\') {
    236     subkey.push_back('\\'); subkey.push_back('\\');
    237       } else {
    238     subkey.push_back (*subkey_here);
    239       }
    240       ++subkey_here;
    241     }
    242     subkey.push_back('>');
    243 
    244     // add the values
    245     text_tarray::const_iterator subvalue_here = (*info_here).second.begin();
    246     text_tarray::const_iterator subvalue_end = (*info_here).second.end();
    247     while (subvalue_here != subvalue_end) {
    248       data += subkey;
    249      
    250       text_t::const_iterator thissubvalue_here = (*subvalue_here).begin();
    251       text_t::const_iterator thissubvalue_end = (*subvalue_here).end();
    252       while (thissubvalue_here != thissubvalue_end) {
    253     if (*thissubvalue_here == '>') {
    254       data.push_back('\\'); data.push_back('>');
    255     } else if (*thissubvalue_here == '\n') {
    256       data.push_back('\\'); data.push_back('n');
    257     } else if (*thissubvalue_here == '\r') {
    258       data.push_back('\\'); data.push_back('r');
    259     } else if (*thissubvalue_here == '\\') {
    260       data.push_back('\\'); data.push_back('\\');
    261     } else {
    262       data.push_back (*thissubvalue_here);
    263     }
    264    
    265     ++thissubvalue_here;
    266       }
    267      
    268       data.push_back('\n');
    269       ++subvalue_here;
    270     }
    271 
    272     ++info_here;
    273   }
    274 
    275   // store the value
    276   datum key_data;
    277   datum data_data;
    278 
    279   // get a utf-8 encoded c string of the unicode key
    280   key_data.dptr = (to_utf8(key)).getcstr();
    281   if (key_data.dptr == NULL) {
    282     if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
    283     return false;
    284   }
    285   key_data.dsize = strlen (key_data.dptr);
    286 
    287   data_data.dptr = (to_utf8(data)).getcstr();
    288   if (data_data.dptr == NULL) {
    289     if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
    290     delete []key_data.dptr;
    291     return false;
    292   }
    293   data_data.dsize = strlen (data_data.dptr);
    294 
    295   int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
    296   delete []key_data.dptr;
    297   delete []data_data.dptr;
    298 
    299   return (ret == 0);
    300 }
    301 
    302 
    303 //returns true on success
    304 bool gdbmclass::setinfo (const text_t &key, const text_t &data)
    305 {
    306   if (gdbmfile == NULL) return false;
    307  
    308   // store the value
    309   datum key_data;
    310   datum data_data;
    311 
    312   // get a utf-8 encoded c string of the unicode key
    313   key_data.dptr = (to_utf8(key)).getcstr();
    314   if (key_data.dptr == NULL) {
    315     if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
    316     return false;
    317   }
    318   key_data.dsize = strlen (key_data.dptr);
    319 
    320   data_data.dptr = (to_utf8(data)).getcstr();
    321   if (data_data.dptr == NULL) {
    322     if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
    323     delete []key_data.dptr;
    324     return false;
    325   }
    326   data_data.dsize = strlen (data_data.dptr);
    327 
    328   int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
    329   delete []key_data.dptr;
    330   delete []data_data.dptr;
    331 
    332   return (ret == 0);
    333 }
    334 
    335 
    336 void gdbmclass::deletekey (const text_t &key)
    337 {
    338   if (gdbmfile == NULL) return;
    339 
    340   // get a utf-8 encoded c string of the unicode key
    341   datum key_data;
    342   key_data.dptr = (to_utf8(key)).getcstr();
    343   if (key_data.dptr == NULL) return;
    344   key_data.dsize = strlen (key_data.dptr);
    345 
    346   // delete the key
    347   gdbm_delete (gdbmfile, key_data);
    348 
    349   // free up the key memory
    350   delete []key_data.dptr;
    351 }
    352 
    353 
    354 // getfirstkey and getnextkey are used for traversing the database
    355 // no insertions or deletions should be carried out while traversing
    356 // the database. when there are no keys left to visit in the database
    357 // an empty string is returned.
    358 text_t gdbmclass::getfirstkey ()
    359 {
    360   if (gdbmfile == NULL) return g_EmptyText;
    361 
    362   // get the first key
    363   datum firstkey_data = gdbm_firstkey (gdbmfile);
    364   if (firstkey_data.dptr == NULL) return g_EmptyText;
    365 
    366   // convert it to text_t
    367   text_t firstkey;
    368   firstkey.setcarr (firstkey_data.dptr, firstkey_data.dsize);
    369   free (firstkey_data.dptr);
    370   return to_uni(firstkey);  // convert to unicode
    371 }
    372 
    373 
    374 text_t gdbmclass::getnextkey (const text_t &key)
    375 {
    376   if (gdbmfile == NULL || key.empty()) return g_EmptyText;
    377 
    378   // get a utf-8 encoded c string of the unicode key
    379   datum key_data;
    380   key_data.dptr = (to_utf8(key)).getcstr();
    381   if (key_data.dptr == NULL) return g_EmptyText;
    382   key_data.dsize = strlen (key_data.dptr);
    383  
    384   // get the next key
    385   datum nextkey_data = gdbm_nextkey (gdbmfile, key_data);
    386   if (nextkey_data.dptr == NULL) {
    387     delete []key_data.dptr;
    388     return g_EmptyText;
    389   }
    390 
    391   // convert it to text_t
    392   text_t nextkey;
    393   nextkey.setcarr (nextkey_data.dptr, nextkey_data.dsize);
    394   free (nextkey_data.dptr);
    395   delete []key_data.dptr;
    396   return to_uni(nextkey);  // convert to unicode
    397 }
    398 
    399 
    400 // replaces the .fc, .lc, .pr, .rt, .ns and .ps syntax (first child,
    401 // last child, parent, root, next sibling, previous sibling)
    402 // it expects child, parent, etc. to exist if syntax has been used
    403 // so you should test before using
    404 text_t gdbmclass::translate_OID (const text_t &inOID, infodbclass &info)
    405 {
    406   if (inOID.size() < 4) return inOID;
    407   if (findchar (inOID.begin(), inOID.end(), '.') == inOID.end()) return inOID;
    408 
    409   text_t OID = inOID;
    410   text_tarray tailarray;
    411   text_t tail = substr (OID.end()-3, OID.end());
    412   if (tail == ".rt") {
    413     get_top (inOID, OID);
    414     return OID;
    415   }
    416   while (tail == ".fc" || tail == ".lc" || tail == ".pr" ||
    417      tail == ".ns" || tail == ".ps") {
    418     tailarray.push_back(tail);
    419     OID.erase (OID.end()-3, OID.end());
    420     tail = substr (OID.end()-3, OID.end());
    421     if (tail == ".rt") {
    422       get_top (inOID, OID);
    423       return OID;
    424     }
    425   }
    426 
    427   if (tailarray.empty()) return inOID;
    428   text_tarray::const_iterator begin = tailarray.begin();
    429   text_tarray::const_iterator here = tailarray.end() - 1;
    430 
    431   while (here >= begin) {
    432 
    433     if (*here == ".fc")
    434       get_first_child (OID, info);
    435     else if (*here == ".lc")
    436       get_last_child (OID, info);
    437     else if (*here == ".pr")
    438       OID = get_parent (OID);
    439     else if (*here == ".ns")
    440       get_next_sibling (OID, info);
    441     else if (*here == ".ps")
    442       get_previous_sibling (OID, info);
    443    
    444     if (here == begin)
    445       break;
    446     --here;
    447   }
    448 
    449   return OID;
    450 }
    451 
    452 
    453 void gdbmclass::get_first_child (text_t &OID, infodbclass &info)
    454 {
    455   text_t firstchild;
    456   if (getinfo (OID, info)) {
    457     text_t &contains = info["contains"];
    458     if (!contains.empty()) {
    459       text_t parent = OID;
    460       getdelimitstr (contains.begin(), contains.end(), ';', firstchild);
    461       if (firstchild.empty()) OID = contains;
    462       else OID = firstchild;
    463       if (*(OID.begin()) == '"') translate_parent (OID, parent);
    464     }
    465   }
    466 }
    467 
    468 
    469 void gdbmclass::get_last_child (text_t &OID, infodbclass &info)
    470 {
    471   text_tarray children;
    472   if (getinfo (OID, info)) {
    473     text_t &contains = info["contains"];
    474     if (!contains.empty()) {
    475       text_t parent = OID;
    476       splitchar (contains.begin(), contains.end(), ';', children);
    477       OID = children.back();
    478       if (*(OID.begin()) == '"') translate_parent (OID, parent);
    479     }
    480   }
    481 }
    482 
    483  
    484 void gdbmclass::get_next_sibling (text_t &OID, infodbclass &info)
    485 {
    486   text_tarray siblings;
    487   text_t parent = get_parent (OID);
    488          
    489   if (getinfo (parent, info)) {
    490     text_t &contains = info["contains"];
    491     if (!contains.empty()) {
    492       splitchar (contains.begin(), contains.end(), ';', siblings);
    493       text_tarray::const_iterator here = siblings.begin();
    494       text_tarray::const_iterator end = siblings.end();
    495       text_t shrunk_OID = OID;
    496       shrink_parent (shrunk_OID);
    497       while (here != end) {
    498     if (*here == shrunk_OID && (here+1 != end)) {
    499       OID = *(here+1);
    500       if (*(OID.begin()) == '"') translate_parent (OID, parent);
    501       break;
    502     }
    503     ++here;
    504       }
    505     }
    506   }
    507 }
    508 
    509 
    510 void gdbmclass::get_previous_sibling (text_t &OID, infodbclass &info)
    511 {
    512   text_tarray siblings;
    513   text_t parent = get_parent (OID);
    514 
    515   if (getinfo (parent, info)) {
    516     text_t &contains = info["contains"];
    517     if (!contains.empty()) {
    518       splitchar (contains.begin(), contains.end(), ';', siblings);
    519       text_tarray::const_iterator here = siblings.begin();
    520       text_tarray::const_iterator end = siblings.end();
    521       text_t shrunk_OID = OID;
    522       shrink_parent (shrunk_OID);
    523       while (here != end) {
    524     if (*here == shrunk_OID && (here != siblings.begin())) {
    525       OID = *(here-1);
    526       if (*(OID.begin()) == '"') translate_parent (OID, parent);
    527       break;
    528     }
    529     ++here;
    530       }
    531     }
    532   }
    533 }
    534 
    535 
    536 // returns true on success
    537 bool gdbmclass::getinfo (const text_t& key, infodbclass &info)
    538 {
    539   text_t data;
    540  
    541   if (!getkeydata (key, data)) return false;
    542   text_t::iterator here = data.begin ();
    543   text_t::iterator end = data.end ();
    544  
    545   text_t ikey, ivalue;
    546   info.clear (); // reset info
    547  
    548   while (getinfoline (here, end, ikey, ivalue)) {
    549     info.addinfo (ikey, ivalue);
    550   }
    551  
    552   return true;
    553 }
    554 
    555 
    556 // returns true if exists
    557 bool gdbmclass::exists (const text_t& key)
    558 {
    559   text_t data;
    560   return getkeydata (key, data);
    561 }
    562 
    563 
    564 // returns true on success
    565 bool gdbmclass::getkeydata (const text_t& key, text_t &data)
    566 {
    567   datum key_data;
    568   datum return_data;
    569 
    570   if (gdbmfile == NULL) return false;
    571  
    572   // get a utf-8 encoded c string of the unicode key
    573   key_data.dptr = (to_utf8(key)).getcstr();
    574   if (key_data.dptr == NULL) {
    575     if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
    576     return false;
    577   }
    578   key_data.dsize = strlen (key_data.dptr);
    579  
    580   // fetch the result
    581   return_data = gdbm_fetch (gdbmfile, key_data);
    582   delete []key_data.dptr;
    583  
    584   if (return_data.dptr == NULL) return false;
    585 
    586   data.setcarr (return_data.dptr, return_data.dsize);
    587   free (return_data.dptr);
    588   data = to_uni(data);  // convert to unicode
    589 
    590   return true;
    591 }
    592 
    593 
    594 // returns true on success
    595 bool gdbmclass::getinfoline (text_t::iterator &here, text_t::iterator end,
    596                  text_t &key, text_t &value)
    597 {
    598   key.clear();
    599   value.clear();
    600 
    601   // ignore white space
    602   while (here != end && is_unicode_space (*here)) ++here;
    603 
    604   // get the '<'
    605   if (here == end || *here != '<') return false;
    606   ++here;
    607  
    608   // get the key
    609   while (here != end && *here != '>') {
    610     key.push_back(*here);
    611     ++here;
    612   }
    613  
    614   // get the '>'
    615   if (here == end || *here != '>') return false;
    616   ++here;
    617  
    618   // get the value
    619   while (here != end && *here != '\n') {
    620     if (*here == '\\') {
    621       // found escape character
    622       ++here;
    623       if (here != end) {
    624     if (*here == 'n') value.push_back ('\n');
    625     else if (*here == 'r') value.push_back ('\r');
    626     else value.push_back(*here);
    627       }
    628 
    629     } else {
    630       // a normal character
    631       value.push_back(*here);
    632     }
    633 
    634     ++here;
    635   }
    636 
    637   return true;
    638 }
  • gsdl/trunk/lib/infodbclass.h

    r15420 r15429  
    4141#  include <iostream>
    4242#  include <fstream>
    43 #endif
    44 
    45 #ifdef __WIN32__
    46 
    47 #ifdef __cplusplus
    48   extern "C" {
    49 #endif
    50 #include "autoconf.h"
    51 #include "systems.h"
    52 #include "gdbmconst.h"
    53 #include "gdbm.h"
    54 #ifdef __cplusplus
    55   }
    56 #endif
    57 
    58 #else
    59 #include <gdbm.h>
    6043#endif
    6144
     
    138121
    139122
    140 class gdbmclass {
    141 public:
    142   gdbmclass() {gdbmfile = NULL; logout = &cerr;};
    143   ~gdbmclass();
    144  
    145   // returns true if opened
    146   bool opendatabase (const text_t &filename, int mode, int num_retrys,
    147              bool need_filelock);
    148   void closedatabase ();
    149 
    150   // replaces the .c, .p, .n, .l syntax (child, parent, next, previous)
    151   // it expects child, parent, etc. to exist if syntax has been used
    152   // so you should test before using
    153   text_t translate_OID (const text_t &OID, infodbclass &info);
    154 
    155   // returns true on success
    156   bool getinfo (const text_t& key, infodbclass &info);
    157   void setlogout (ostream *thelogout) {logout = thelogout;}
    158 
    159   // returns true if exists
    160   bool exists (const text_t& key);
    161 
    162   // returns true on success
    163   bool setinfo (const text_t &key, const infodbclass &info);
    164   // returns true on success
    165   bool setinfo (const text_t &key, const text_t &data);
    166 
    167   void deletekey (const text_t &key);
    168 
    169   // getfirstkey and getnextkey are used for traversing the database
    170   // no insertions or deletions should be carried out while traversing
    171   // the database. when there are no keys left to visit in the database
    172   // an empty string is returned.
    173   text_t getfirstkey ();
    174   text_t getnextkey (const text_t &key);
    175 
    176     // returns true on success
    177   bool getkeydata (const text_t& key, text_t &data);
    178 
    179 protected:
    180   text_t openfile;
    181   GDBM_FILE gdbmfile;
    182   ostream *logout;
    183 
    184   void get_first_child (text_t &OID, infodbclass &info);
    185   void get_last_child (text_t &OID, infodbclass &info);
    186   void get_next_sibling (text_t &OID, infodbclass &info);
    187   void get_previous_sibling (text_t &OID, infodbclass &info);
    188 
    189 
    190   // returns true on success
    191   bool getinfoline (text_t::iterator &here, text_t::iterator end,
    192            text_t &key, text_t &value);
    193 };
    194 
    195 
    196123#endif
  • gsdl/trunk/lib/win32.mak

    r15420 r15429  
    7373HEADERS = \
    7474  cfgread.h        cnfgable.h       cnfgator.h       display.h \
    75   fileutil.h       gsdlsitecfg.h    gsdltimes.h      gsdltools.h \
    76   gsdlunicode.h    infodbclass.h    md5.h            OIDtools.h \
    77   phrases.h        text_t.h         gsdlconf.h
     75  fileutil.h       gdbmclass.h      gsdlsitecfg.h    gsdltimes.h \
     76  gsdltools.h      gsdlunicode.h    infodbclass.h    md5.h \
     77  OIDtools.h       phrases.h        text_t.h         gsdlconf.h
    7878
    7979SOURCES = \
    8080  cfgread.cpp      cnfgable.cpp     cnfgator.cpp     display.cpp \
    81   fileutil.cpp     gsdlsitecfg.cpp  gsdltimes.cpp    gsdltools.cpp \
    82   gsdlunicode.cpp  infodbclass.cpp  md5.cpp          OIDtools.cpp \
    83   phrases.cpp      text_t.cpp
     81  fileutil.cpp     gdbmclass.cpp    gsdlsitecfg.cpp  gsdltimes.cpp \
     82  gsdltools.cpp    gsdlunicode.cpp  infodbclass.cpp  md5.cpp \
     83  OIDtools.cpp     phrases.cpp      text_t.cpp
    8484
    8585OBJECTS = \
    8686  cfgread.o        cnfgable.o       cnfgator.o       display.o \
    87   fileutil.o       gsdlsitecfg.o    gsdltimes.o      gsdltools.o \
    88   gsdlunicode.o    infodbclass.o    md5.o            OIDtools.o \
    89   phrases.o        text_t.o
     87  fileutil.o       gdbmclass.o      gsdlsitecfg.o    gsdltimes.o \
     88  gsdltools.o      gsdlunicode.o    infodbclass.o    md5.o \
     89  OIDtools.o       phrases.o        text_t.o
     90
    9091
    9192all: gsdllib.lib
Note: See TracChangeset for help on using the changeset viewer.