00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <ctype.h>
00017 #include <errno.h>
00018 #include <limits.h>
00019 #include <float.h>
00020
00021 #include "CTB.hxx"
00022 #include "CTB_Trace.hxx"
00023 #include "CTBcstringBase.hxx"
00024 #include "CTBnum.hxx"
00025
00031
00033
00034 void CTBcstringBase::Copy(char* c_dst, CTBint i_size,
00035 const char* c_src)
00036 {
00037 CTB_Trace("CTBcstringBase::Copy(char*,CTBint,const char*)");
00038
00039 if (c_src) {
00040 strncpy(c_dst,c_src,i_size-1);
00041 c_dst[i_size-1] = 0;
00042 } else {
00043 c_dst[0] = 0;
00044 }
00045 return;
00046 }
00047
00048
00050
00051 void CTBcstringBase::Copy(char* c_dst, CTBint i_size,
00052 const char* c_src, CTBint i_offset, CTBint i_length)
00053 {
00054 CTB_Trace("CTBcstringBase::Copy(char*,CTBint,const char*,CTBint,CTBint)");
00055
00056 if (c_src) {
00057 CTBint i_lsrc = CTBmin(i_length,i_size-1);
00058 strncpy(c_dst,c_src+i_offset,i_lsrc);
00059 c_dst[i_lsrc] = 0;
00060 } else {
00061 c_dst[0] = 0;
00062 }
00063 return;
00064 }
00065
00066
00068
00069 void CTBcstringBase::Append(char* c_dst, CTBint i_size,
00070 const char* c_src)
00071 {
00072 CTB_Trace("CTBcstringBase::Append(char*,CTBint,const char*)");
00073
00074 if (c_src) {
00075 CTBint i_ldst = strlen(c_dst);
00076 strncpy(c_dst+i_ldst,c_src,i_size-i_ldst-1);
00077 c_dst[i_size-1] = 0;
00078 }
00079 return;
00080 }
00081
00082
00084
00085 void CTBcstringBase::Append(char* c_dst, CTBint i_size,
00086 const char* c_src, CTBint i_offset, CTBint i_length)
00087 {
00088 CTB_Trace("CTBcstringBase::Append(char*,CTBint,const char*,CTBint,CTBint)");
00089
00090 if (c_src) {
00091 CTBint i_ldst = strlen(c_dst);
00092 CTBint i_lsrc;
00093
00094 if (i_length < 0) i_length = strlen(c_src+i_offset);
00095 i_lsrc = CTBmin(i_size-i_ldst-1,i_length);
00096 strncpy(c_dst+i_ldst,c_src+i_offset,i_lsrc);
00097 c_dst[i_ldst+i_lsrc] = 0;
00098 }
00099 return;
00100 }
00101
00102
00104
00105 void CTBcstringBase::Trim(char* c_dst, CTBint)
00106
00107 {
00108 CTB_Trace("CTBcstringBase::Trim(char*,CTBint)");
00109
00110 CTBint i_length = strlen(c_dst);
00111 char* pc_cur;
00112 char* pc_out = c_dst;
00113
00114 if (i_length == 0) return;
00115
00116 pc_cur = c_dst + i_length -1;
00117 for ( ; i_length > 0; i_length--) {
00118 if (!isspace(*pc_cur)) break;
00119 pc_cur--;
00120 }
00121
00122 pc_cur = c_dst;
00123 for ( ; i_length > 0; i_length--) {
00124 if (!isspace(*pc_cur)) break;
00125 pc_cur++;
00126 }
00127
00128
00129
00130
00131 if (pc_cur == c_dst) {
00132 c_dst[i_length] = 0;
00133 } else {
00134 for ( ; i_length > 0; i_length--) *pc_out++ = *pc_cur++;
00135 *pc_out = 0;
00136 }
00137
00138 return;
00139 }
00140
00141
00143
00144 void CTBcstringBase::Toupper(char* c_dst, CTBint i_size)
00145 {
00146 CTB_Trace("CTBcstringBase::Toupper(char*,CTBint)");
00147
00148 for (CTBint i = 0; i < i_size; i++) {
00149 char c = c_dst[i];
00150 if (c == 0) break;
00151 c_dst[i] = _toupper(c);
00152 }
00153 return;
00154 }
00155
00156
00158
00159 void CTBcstringBase::Tolower(char* c_dst, CTBint i_size)
00160 {
00161 CTB_Trace("CTBcstringBase::Tolower(char*,CTBint)");
00162
00163 for (CTBint i = 0; i < i_size; i++) {
00164 char c = c_dst[i];
00165 if (c == 0) break;
00166 c_dst[i] = _tolower(c);
00167 }
00168 }
00169
00170
00172
00179 static const char* trim_to_buffer(const char* c_src, CTBint i_size,
00180 char* c_buf, CTBint i_bufsize)
00181 {
00182 if (i_size < 0) return c_src;
00183
00184 const char* pc_cur = c_src + i_size -1;
00185
00186 for ( ; i_size > 0; i_size--) {
00187 if (!isspace(*pc_cur)) break;
00188 pc_cur--;
00189 }
00190
00191 pc_cur = c_src;
00192 for ( ; i_size > 0; i_size--) {
00193 if (!isspace(*pc_cur)) break;
00194 pc_cur++;
00195 }
00196
00197
00198
00199
00200 if (i_size >= i_bufsize) return 0;
00201
00202 strncpy(c_buf,pc_cur,i_size);
00203 c_buf[i_size] = 0;
00204 return c_buf;
00205 }
00206
00207
00209
00222 bool CTBcstringBase::Get(const char* c_src, CTBint i_size,
00223 long& i_val, int i_base)
00224 {
00225 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,long&,int)");
00226
00227 char c_buf[256];
00228 char* pc_end;
00229 char c;
00230 long i_tmp;
00231
00232 if (c_src == 0 || i_size == 0) {
00233 i_val = 0;
00234 return true;
00235 }
00236
00237 c_src = trim_to_buffer(c_src,i_size,c_buf,256);
00238 if (c_src == 0) return false;
00239
00240 errno = 0;
00241 i_tmp = strtol(c_src,&pc_end,i_base);
00242
00243 if (errno != 0) return false;
00244 if (pc_end != 0) {
00245 while ((c = *pc_end++)) {
00246 if (!isspace(c)) return false;
00247 }
00248 }
00249
00250 i_val = i_tmp;
00251 return true;
00252 }
00253
00254
00256
00257 bool CTBcstringBase::Get(const char* c_src, CTBint i_size,
00258 unsigned long& i_val, int i_base)
00259 {
00260 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,unsigned long&,int)");
00261
00262 char c_buf[256];
00263 char* pc_end;
00264 char c;
00265 unsigned long i_tmp;
00266
00267 if (c_src == 0 || i_size == 0) {
00268 i_val = 0;
00269 return true;
00270 }
00271
00272 c_src = trim_to_buffer(c_src,i_size,c_buf,256);
00273 if (c_src == 0) return false;
00274
00275 errno = 0;
00276 i_tmp = strtoul(c_src,&pc_end,i_base);
00277
00278 if (errno != 0) return false;
00279 if (pc_end != 0) {
00280 while ((c = *pc_end++)) {
00281 if (!isspace(c)) return false;
00282 }
00283 }
00284
00285 i_val = i_tmp;
00286 return true;
00287 }
00288
00289
00291
00292 bool CTBcstringBase::Get(const char* c_src, CTBint i_size,
00293 int& i_val, int i_base)
00294 {
00295 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,int&,int)");
00296
00297 long i_tmp;
00298
00299 if (!Get(c_src,i_size,i_tmp,i_base)) return false;
00300
00301 if (i_tmp < INT_MIN || i_tmp > INT_MAX) return false;
00302 i_val = i_tmp;
00303 return true;
00304 }
00305
00306
00308
00309 bool CTBcstringBase::Get(const char* c_src, CTBint i_size,
00310 unsigned int& i_val, int i_base)
00311 {
00312 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,unsigned int&,int)");
00313
00314 unsigned long i_tmp;
00315
00316 if (!Get(c_src,i_size,i_tmp,i_base)) return false;
00317
00318 if (i_tmp > UINT_MAX) return false;
00319 i_val = i_tmp;
00320 return true;
00321 }
00322
00323
00325
00326 bool CTBcstringBase::Get(const char* c_src, CTBint i_size, double& d_val)
00327 {
00328 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,double&)");
00329
00330 char c_buf[256];
00331 char* pc_end;
00332 char c;
00333 double d_tmp;
00334
00335 if (c_src == 0 || i_size == 0) {
00336 d_val = 0.;
00337 return true;
00338 }
00339
00340 c_src = trim_to_buffer(c_src,i_size,c_buf,256);
00341 if (c_src == 0) return false;
00342
00343 errno = 0;
00344 d_tmp = strtod(c_src,&pc_end);
00345
00346 if (errno != 0) return false;
00347 if (pc_end != 0) {
00348 while ((c = *pc_end++)) {
00349 if (!isspace(c)) return false;
00350 }
00351 }
00352
00353 d_val = d_tmp;
00354 return true;
00355 }
00356
00357
00359
00360 bool CTBcstringBase::Get(const char* c_src, CTBint i_size, float& f_val)
00361 {
00362 CTB_Trace("CTBcstringBase::Get(const char*,CTBint,float&)");
00363
00364 double d_tmp;
00365
00366 if (!Get(c_src,i_size,d_tmp)) return false;
00367
00368 if (d_tmp < -FLT_MAX || d_tmp > FLT_MAX) return false;
00369 f_val = d_tmp;
00370 return true;
00371 }
00372
00373
00375
00376 CTBint CTBcstringBase::Locate(const char* c_src, CTBint, char c_char)
00377
00378 {
00379 CTB_Trace("CTBcstringBase::Locate(const char*,CTBint,char)");
00380
00381 const char* pc_char = strchr(c_src,c_char);
00382 if (pc_char) return pc_char - c_src;
00383 return strlen(c_src);
00384 }
00385
00386
00388
00389 int CTBcstringBase::NField(const char* c_src, CTBint,
00390 const char* c_delim)
00391
00392 {
00393 CTB_Trace("CTBcstringBase::NField(const char*,CTBint,const char*)");
00394 int i_length = strlen(c_src);
00395
00396 if (i_length == 0) return 0;
00397
00398 if (!c_delim || c_delim[0] == 0) {
00399
00400 const char* pc_cur;
00401 int i_cnt = 0;
00402
00403 pc_cur = c_src + i_length -1;
00404 for ( ; i_length > 0; i_length--) {
00405 if (!isspace(*pc_cur)) break;
00406 pc_cur--;
00407 }
00408 pc_cur = c_src;
00409 for ( ; i_length > 0; i_length--) {
00410 if (!isspace(*pc_cur)) break;
00411 pc_cur++;
00412 }
00413
00414 if (i_length == 0) return 0;
00415
00416 for ( ; i_length > 0 ; ) {
00417 for ( ; i_length > 0; i_length--) {
00418 if (isspace(*pc_cur)) break;
00419 pc_cur++;
00420 }
00421 for ( ; i_length > 0; i_length--) {
00422 if (!isspace(*pc_cur)) break;
00423 pc_cur++;
00424 }
00425 i_cnt++;
00426 }
00427 return i_cnt;
00428 }
00429
00430 if (c_delim[1] == 0) {
00431 const char* pc_cur = c_src;
00432 int i_cnt = 1;
00433 char c_del = c_delim[0];
00434 for ( ; i_length > 0; i_length--) if (*pc_cur++ == c_del) i_cnt++;
00435 return i_cnt;
00436 } else {
00437 const char* pc_cur = c_src;
00438 int i_cnt = 1;
00439 for ( ; i_length > 0; i_length--) if (InSet(*pc_cur++,c_delim)) i_cnt++;
00440 return i_cnt;
00441 }
00442 return 0;
00443 }
00444
00445
00447
00448 bool CTBcstringBase::LocateField( const char* c_src, CTBint,
00449 CTBint& i_foffset, CTBint& i_flength,
00450 CTBint i_ind, const char* c_delim)
00451
00452 {
00453 CTB_Trace("CTBcstringBase::LocateField(const char*,CTBint,CTBint&,CTBint&,CTBint,const char*)");
00454 int i_length = strlen(c_src);
00455
00456 i_foffset = i_length;
00457 i_flength = 0;
00458
00459 if (i_ind < 0) return false;
00460
00461 if (!c_delim || c_delim[0] == 0) {
00462
00463 const char* pc_cur;
00464 const char* pc_beg;
00465
00466 pc_cur = c_src + i_length -1;
00467 for ( ; i_length > 0; i_length--) {
00468 if (!isspace(*pc_cur)) break;
00469 pc_cur--;
00470 }
00471 pc_cur = c_src;
00472 for ( ; i_length > 0; i_length--) {
00473 if (!isspace(*pc_cur)) break;
00474 pc_cur++;
00475 }
00476
00477 for ( ; ; i_ind--) {
00478 pc_beg = pc_cur;
00479 for ( ; i_length > 0; i_length--) {
00480 if (isspace(*pc_cur)) break;
00481 pc_cur++;
00482 }
00483 if (i_ind == 0) {
00484 i_foffset = pc_beg - c_src;
00485 i_flength = pc_cur - pc_beg;
00486 return true;
00487 }
00488 if (i_length == 0) return false;
00489 for ( ; i_length > 0; i_length--) {
00490 if (!isspace(*pc_cur)) break;
00491 pc_cur++;
00492 }
00493 }
00494 }
00495
00496 if (c_delim[1] == 0) {
00497 const char* pc_cur = c_src;
00498 const char* pc_beg;
00499 char c = c_delim[0];
00500
00501 for ( ; ; i_ind--) {
00502 pc_beg = pc_cur;
00503 for ( ; i_length > 0; i_length--) {
00504 if (*pc_cur == c) break;
00505 pc_cur++;
00506 }
00507 if (i_ind == 0) {
00508 i_foffset = pc_beg - c_src;
00509 i_flength = pc_cur - pc_beg;
00510 return true;
00511 }
00512 if (i_length == 0) return false;
00513 i_length--; pc_cur++;
00514 }
00515
00516 } else {
00517 const char* pc_cur = c_src;
00518 const char* pc_beg;
00519 for ( ; ; i_ind--) {
00520 pc_beg = pc_cur;
00521 for ( ; i_length > 0; i_length--) {
00522 if (InSet(*pc_cur,c_delim)) break;
00523 pc_cur++;
00524 }
00525 if (i_ind == 0) {
00526 i_foffset = pc_beg - c_src;
00527 i_flength = pc_cur - pc_beg;
00528 return true;
00529 }
00530 if (i_length == 0) return false;
00531 i_length--; pc_cur++;
00532 }
00533 }
00534
00535 return false;
00536 }
00537
00538
00540
00541 bool CTBcstringBase::CopyField(char* c_dst, CTBint i_size,
00542 const char* c_src, CTBint i_ind,
00543 const char* c_delim)
00544 {
00545 CTB_Trace("CTBcstringBase::CopyField(const char*,CTBint,const char*,CTBint,const char*)");
00546 CTBint i_foffset;
00547 CTBint i_flength;
00548 bool b_found = LocateField(c_src,-1,i_foffset,i_flength,i_ind,c_delim);
00549
00550 if (b_found) {
00551 Copy(c_dst,i_size,c_src,i_foffset,i_flength);
00552 } else {
00553 c_dst[0] = 0;
00554 }
00555 return b_found;
00556 }
00557
00558
00560
00561 bool CTBcstringBase::GetLine(char* c_dst, CTBint i_size, istream& is)
00562 {
00563 CTB_Trace("CTBcstringBase::GetLine(const char*,CTBint,istream&)");
00564
00565 if (c_dst == 0 || i_size == 0) return false;
00566 c_dst[0] = 0;
00567 if (!is) return false;
00568
00569 is.getline(c_dst,i_size);
00570 return !is.fail();
00571 }
00572
00573
00575
00576 bool CTBcstringBase::FromStream(char* c_dst, CTBint i_size, istream& is)
00577 {
00578 CTB_Trace("CTBcstringBase::FromStream(const char*,CTBint,istream&)");
00579 int i_width = is.width();
00580
00581 if (c_dst == 0 || i_size == 0) return false;
00582 c_dst[0] = 0;
00583 if (!is) return false;
00584
00585 if (i_width == 0) {
00586 i_width = i_size;
00587 } else {
00588 if (i_width > i_size) i_width = i_size;
00589 }
00590 is >> setw(i_width) >> c_dst;
00591
00592 return !is.fail();
00593 }
00594
00595
00596
00597 #if (defined(CTB__OutLine) || defined(CTBcstringBase__OutLine))
00598 #define inline
00599 #include "CTBcstringBase.icc"
00600 #undef inline
00601 #endif
00602
00603
00604
00605
00606
00607
00608
00609
00610