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 #include "strl.hpp"
00027 #include "uti.h"
00028 #include "wrkbuff.h"
00029
00030
00031
00032 INT _strl_cmp(const String *s1, const String *s2);
00033 INT _strl_rcmp(const String *s1, const String *s2);
00034
00035
00036
00037 int KVStrList::toi( const String &k, const String &v )
00038 {
00039 int n,i;
00040 int val;
00041 i = sscanf(v,"%d%n",&val,&n);
00042 if ((i!=1)||(size_t)n!=v.length())
00043 die_beep("KVStrList: value for key (%s) is not int (%s)",
00044 (const char *)k,(const char *)v);
00045 return val;
00046 }
00047
00048
00049
00050 long KVStrList::tol( const String &k, const String &v )
00051 {
00052 int n,i;
00053 long val;
00054 i = sscanf(v,"%ld%n",&val,&n);
00055 if ((i!=1)||(size_t)n!=v.length())
00056 die_beep("KVStrList: value for key (%s) is not long (%s)",
00057 (const char *)k,(const char *)v);
00058 return val;
00059 }
00060
00061
00062
00063 float KVStrList::tof( const String &k, const String &v)
00064 {
00065 int n,i;
00066 float val;
00067 i = sscanf(v,"%f%n",&val,&n);
00068 if ((i!=1)||(size_t)n!=v.length())
00069 die_beep("KVStrList: value for key (%s) is not float (%s)",
00070 (const char *)k,(const char *)v);
00071 return val;
00072 }
00073
00074
00075
00076 double KVStrList::tod( const String &k, const String &v )
00077 {
00078 int n,i;
00079 double val;
00080 i = sscanf(v,"%lf%n",&val,&n);
00081 if ((i!=1)||(size_t)n!=v.length())
00082 die_beep("KVStrList: value for key (%s) is not double (%s)",
00083 (const char *)k,(const char *)v);
00084 return val;
00085 }
00086
00087
00088
00089 #define INVALID_BOOL_IS_TRUE
00090 BOOL KVStrList::tob( const String &k, const String &v)
00091 {
00092 int x=str2bool((const char*)v,-1);
00093 if (x>0) return TRUE;
00094 if (!x) return FALSE;
00095 #ifdef INVALID_BOOL_IS_TRUE
00096 (void)k;
00097 return TRUE;
00098 #else
00099 die_beep("KVStrList: value for key (%s) is not boolean (%s)",
00100 (const char *)k,(const char *)v);
00101 return FALSE;
00102 #endif
00103 }
00104
00105
00106
00107 const String& KVStrList::val( const String& key ) const
00108 {
00109 Lix p=seek(key);
00110 cdie_beep(!p, "List val(%s): non existant key",(const char*)key);
00111 return itemval(p);
00112 }
00113
00114
00115
00116 int KVStrList::ival( const String &k, int def ) const
00117 {
00118 Lix p = seek(k);
00119 return (p ? toi(k,itemval(p)) : def);
00120 }
00121
00122
00123
00124 long KVStrList::lval( const String &k, long def ) const
00125 {
00126 Lix p = seek(k);
00127 return (p ? tol(k,itemval(p)) : def);
00128 }
00129
00130
00131
00132 float KVStrList::fval( const String &k, float def ) const
00133 {
00134 Lix p = seek(k);
00135 return (p ? tof(k,itemval(p)) : def);
00136 }
00137
00138
00139
00140 double KVStrList::dval( const String &k, double def ) const
00141 {
00142 Lix p = seek(k);
00143 return (p ? tod(k,itemval(p)) : def);
00144 }
00145
00146
00147
00148 BOOL KVStrList::bval( const String &k, BOOL def ) const
00149 {
00150 Lix p = seek(k);
00151 return (p ? tob(k,itemval(p)) : def);
00152 }
00153
00154
00155
00156 const char *KVStrList::val( const String &k, const char *vdef ) const
00157 {
00158 Lix p=seek(k);
00159 if (!p) return vdef;
00160 else return itemval(p);
00161 }
00162
00163
00164
00165 Lix KVStrList::addi( const String &k, int val )
00166 {
00167 WRKBUFF(128);
00168 sprintf(_wrkbuff,"%d",val);
00169 Lix p=add(k,_wrkbuff);
00170 WRKBUFF_FREE();
00171 return p;
00172 }
00173
00174
00175
00176 Lix KVStrList::addui( const String &k, unsigned int val )
00177 {
00178 WRKBUFF(128);
00179 sprintf(_wrkbuff,"%u",val);
00180 Lix p=add(k,_wrkbuff);
00181 WRKBUFF_FREE();
00182 return p;
00183 }
00184
00185
00186
00187 Lix KVStrList::addl( const String &k, long val )
00188 {
00189 WRKBUFF(128);
00190 sprintf(_wrkbuff,"%ld",val);
00191 Lix p=add(k,_wrkbuff);
00192 WRKBUFF_FREE();
00193 return p;
00194 }
00195
00196
00197
00198 Lix KVStrList::addf( const String &k, float val )
00199 {
00200 WRKBUFF(128);
00201 sprintf(_wrkbuff,"%g",(double)val);
00202 Lix p=add(k,_wrkbuff);
00203 WRKBUFF_FREE();
00204 return p;
00205 }
00206
00207
00208
00209 Lix KVStrList::addd( const String &k, double val )
00210 {
00211 WRKBUFF(128);
00212 sprintf(_wrkbuff,"%g",val);
00213 Lix p=add(k,_wrkbuff);
00214 WRKBUFF_FREE();
00215 return p;
00216 }
00217
00218
00219
00220 Lix KVStrList::addb( const String &k, BOOL val )
00221 {
00222 return add(k,bool2str(val));
00223 }
00224
00225
00226
00227 VOID KVStrList::add_prefix( const String &prefix )
00228 {
00229 Lix p;
00230
00231 for (p=first(); p!=0; p=next(p))
00232 _itemkey(p)=prefix+_itemkey(p);
00233 }
00234
00235
00236
00237 VOID KVStrList::remove_prefix( const String &prefix )
00238 {
00239 Lix p;
00240 size_t l=strlen(prefix);
00241
00242 for (p=first(); p!=0; p=next(p)) {
00243 if (!strncmp(_itemkey(p),prefix,l))
00244 _itemkey(p) = ((const char *)_itemkey(p))+l;
00245 }
00246 }
00247
00248
00249
00250 std::ostream& operator << (std::ostream &st, const KVStrList &l)
00251 {
00252 for (Lix p=l.first(); p!=0; p=l.next(p))
00253 st<< "\"" << l.itemkey(p) << "\"" << "="
00254 <<"\"" << l.itemval(p) << "\"" <<std::endl;
00255 return st;
00256 }
00257
00258
00259
00260 VOID KVStrList::add_s( const char *words, const char* sep )
00261 {
00262 static const char *fseparator=" \t\n";
00263
00264 if (!words) return;
00265
00266 size_t lk, lv, lk2;
00267 const char *k;
00268 const char *v;
00269
00270 while (words) {
00271 words += strspn(words,fseparator);
00272 if (!(*words)) break;
00273 k=words; lk=strcspn(k,sep); lk2=strcspn(k,fseparator);
00274 if (lk2<lk) {
00275 lk=lk2;
00276 words+=lk;
00277 if (lk) add(String(k,lk),"");
00278 }
00279 else {
00280 words+=lk;
00281 if (lk) {
00282 BOOL cute=FALSE;
00283 words += strspn(words,sep);
00284 v=words;
00285 if (*v=='"') {
00286 v++;
00287 words++;
00288 cute=TRUE;
00289 lv=strcspn(v,"\"");
00290 }
00291 else
00292 lv=strcspn(v,fseparator);
00293 add(String(k,lk),String(v,lv));
00294 words+=lv;
00295 if (cute && (*words)) words++;
00296 }
00297 }
00298 }
00299 }
00300
00301
00302
00303 VOID KVStrList::add_sf( const char *fwords, const char* sep, ... )
00304 {
00305 va_list argptr;
00306 va_start(argptr, sep);
00307 add_s(fwords,sep,argptr);
00308 va_end(argptr);
00309 }
00310
00311
00312
00313 VOID KVStrList::add_s( const char *fwords, const char* sep, va_list va )
00314 {
00315 WRKBUFF(2048);
00316
00317 if (!fwords) return;
00318 vsprintf(_wrkbuff, fwords, va);
00319 add_s(_wrkbuff,sep);
00320 WRKBUFF_FREE();
00321 }
00322
00323
00324
00325 VOID KVStrList::add_s( const char *wordarray[], const char* sep )
00326 {
00327 const char *k;
00328 const char *v;
00329 size_t lk;
00330
00331 if (!wordarray) return;
00332 while (*wordarray) {
00333 if (sep && (*sep)) {
00334 k= *wordarray; lk=strcspn(k,sep);
00335 if (lk) {
00336 v = *wordarray+lk+ strspn(*wordarray+lk,sep);
00337 add(String(k,lk),v);
00338 }
00339 else add(k,"");
00340 wordarray++;
00341 }
00342 else {
00343 if (*(wordarray+1)) {
00344 add(*wordarray, *(wordarray+1));
00345 wordarray+=2;
00346 }
00347 else {
00348 add(*wordarray, "");
00349 wordarray++;
00350 }
00351 }
00352 }
00353 }
00354
00355
00356
00357 VOID KVStrList::sort( BOOL reverse )
00358 {
00359 if (reverse) sortf(_strl_rcmp);
00360 else sortf(_strl_cmp);
00361 }
00362
00363
00364
00365 BOOL KVStrList::OK ( VOID ) const
00366 {
00367 if (!(l.OK())) return FALSE;
00368 for (Lix p=first(); p!=0; p=next(p))
00369 if (!itemkey(p).OK() || !itemval(p).OK()) return FALSE;
00370 return TRUE;
00371 }
00372
00373