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 #include "w_defines.h"
00031
00032
00033
00034 #include <w_base.h>
00035 #include <cctype>
00036 #include <iostream>
00037
00038
00039 enum states { start, sgned, leadz,
00040 new_hex, new_oct, new_dec,
00041 is_hex, is_oct, is_dec,
00042 end, error, no_hex, no_state };
00043
00044
00045 enum charclass { zero=0, one=1, two=2, three=3, four=4,
00046 five=5, six=6, seven=7, eight=8,
00047 nine=9, ten=10, eleven=11,
00048 twelve=12, thirteen=13, fourteen=14, fifteen=15,
00049 exx, JJJJ, eofile, white, sign, no_charclass
00050 };
00051
00052 static int equiv[127] = {
00053
00054
00055 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, white,
00056
00057 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00058
00059 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00060
00061 JJJJ, JJJJ, white, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00062
00063 JJJJ, JJJJ, JJJJ, sign, JJJJ, sign, JJJJ, JJJJ, zero, one,
00064
00065 two , three, four, five, six, seven, eight, nine, JJJJ, JJJJ,
00066
00067 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, ten, eleven, twelve, thirteen, fourteen,
00068
00069 fifteen, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00070
00071 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, exx, JJJJ,
00072
00073 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, ten, eleven, twelve,
00074
00075 thirteen, fourteen, fifteen, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00076
00077 JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ,
00078
00079 exx, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ, JJJJ
00080 };
00081
00082 typedef enum states XTABLE[no_charclass][no_state];
00083 static enum states table_unknown[no_charclass][no_state] =
00084 {
00085
00086
00087 { leadz, leadz, leadz, is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error },
00088
00089 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00090 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00091 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00092 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00093 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00094 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00095 { new_dec,new_dec,new_oct,is_hex, is_oct, is_dec, is_hex, is_oct, is_dec, error},
00096
00097 { new_dec,new_dec,new_dec,is_hex, end, is_dec, is_hex, is_oct, is_dec,error },
00098 { new_dec,new_dec,new_dec,is_hex, end, is_dec, is_hex, is_oct, is_dec,error },
00099
00100 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00101 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00102 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00103 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00104 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00105 { error,error,new_hex,is_hex, end, end, is_hex, end, end, error },
00106
00107 { error, error, new_hex,end, end, end, end, end, end, error },
00108
00109 { error, error, end, no_hex, end, end, end, end, end, error },
00110
00111 { error, error, end, no_hex, end, end, end, end, end, error },
00112
00113 { start, error, end, end, end, end, end, end, end, error },
00114
00115 { sgned, error, end, no_hex, end, end, end, end, end, error },
00116 };
00117
00118 static enum states table_base16[no_charclass][no_state] =
00119 {
00120
00121
00122 { leadz, leadz, leadz, is_hex, error, error, is_hex, error, error, error },
00123
00124 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00125 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00126 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00127 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00128 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00129 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00130 { is_hex,is_hex, is_hex, is_hex, error, error, is_hex, error, error, error },
00131
00132 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00133 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00134
00135 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00136 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00137 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00138 { is_hex, is_hex, is_hex, is_hex, error,error, is_hex, error, error, error },
00139 { is_hex, is_hex, is_hex, is_hex, error,error,is_hex, error, error, error },
00140 { is_hex, is_hex, is_hex, is_hex, error,error,is_hex, error, error, error },
00141
00142 { error, error, new_hex, end, error,error, end, error, error, error },
00143
00144 { error, error, end, no_hex, error,error, end, error, error, error },
00145
00146 { error, error, end, no_hex, error,error, end, error, error, error },
00147
00148 { start, error, end, no_hex, error,error, end, error, error, error },
00149
00150 { sgned, error, end, no_hex, error,error, end, error, error, error },
00151 };
00152
00153 static enum states table_base8[no_charclass][no_state] =
00154 {
00155
00156
00157 { leadz, leadz, leadz, error, error, error, error, is_oct, error, error },
00158
00159 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00160 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00161 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00162 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00163 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00164 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00165 { is_oct,is_oct, is_oct, error, error, error, error, is_oct, error,error },
00166
00167 { end, error, end, error, error, error, error, end, error, error },
00168 { end, error, end, error, error, error, error, end, error, error },
00169
00170 { end, error, end, error, error,error, error, end, error, error },
00171 { end, error, end, error, error,error, error, end, error, error },
00172 { end, error, end, error, error,error, error, end, error, error },
00173 { end, error, end, error, error,error, error, end, error, error },
00174 { end, error, end, error, error,error, error, end, error, error },
00175 { end, error, end, error, error,error, error, end, error, error },
00176
00177 { error, error, new_hex,end, error,error, end, error, error, error },
00178
00179 { error, error, end, error, error,error, error, end, error, error },
00180
00181 { error, error, end, error, error,error, error, end, error, error },
00182
00183 { start, error, end, error, error,error, error, end, error, error },
00184
00185 { sgned, error, end, error, error,error, error, end, error, error },
00186 };
00187
00188 static enum states table_base10[no_charclass][no_state] =
00189 {
00190
00191
00192
00193
00194 { leadz, leadz, leadz, error, error, error, error, is_oct, is_dec, error },
00195
00196 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00197 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00198 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00199 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00200 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00201 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00202 { is_dec,is_dec, is_dec, error, error, error, error, error, is_dec,error },
00203
00204 { is_dec,is_dec, end, error, error, error, error, end, is_dec,error },
00205 { is_dec,is_dec, end, error, error, error, error, end, is_dec,error },
00206
00207 { end, error, end, error, error,error, error, end, error, error },
00208 { end, error, end, error, error,error, error, end, error, error },
00209 { end, error, end, error, error,error, error, end, error, error },
00210 { end, error, end, error, error,error, error, end, error, error },
00211 { end, error, end, error, error,error, error, end, error, error },
00212 { end, error, end, error, error,error, error, end, error, error },
00213
00214 { error, error, new_hex, end, error,error, end, error, error, error },
00215
00216 { error, error, end, error, error,error, error, error, end, error },
00217
00218 { error, error, end, error, error,error, error, error, end, error },
00219
00220 { start, error, end, error, error,error, error, error, end, error },
00221
00222 { sgned, error, end, error, error,error, error, error, end, error },
00223 };
00224
00225
00226
00227
00228
00229 #ifdef __GNUG__
00230 #define IOS_BACK(stream,ch) (void) stream.unget()
00231 #else
00232 #define IOS_BACK(stream,ch) (void) stream.seekg(-1, ios::cur)
00233 #endif
00234
00235 #if defined( __GNUG__)
00236 #define IOS_FAIL(stream) stream.setstate(ios::failbit)
00237 #else
00238 #define IOS_FAIL(stream) stream.setstate(ios_base::failbit)
00239 #endif
00240
00241
00242 typedef ios::fmtflags ios_fmtflags;
00243
00244
00245
00246
00247 # define LONGLONGCONSTANT(i) i##LL
00248 # define ULONGLONGCONSTANT(i) i##ULL
00249
00250
00251
00252 w_base_t::uint8_t thresh_hex_unsigned =
00253 ULONGLONGCONSTANT(0xf000000000000000);
00254 w_base_t::uint8_t thresh_hex_signed =
00255 LONGLONGCONSTANT(0xf800000000000000);
00256 w_base_t::uint8_t thresh_dec_unsigned =
00257 ULONGLONGCONSTANT(1844674407370955161) ;
00258 w_base_t::uint8_t thresh_dec_signed =
00259 LONGLONGCONSTANT(922337203685477580);
00260 w_base_t::uint8_t thresh2_dec_unsigned =
00261 ULONGLONGCONSTANT(18446744073709551610) ;
00262 w_base_t::uint8_t thresh2_dec_signed =
00263 LONGLONGCONSTANT(9223372036854775800);
00264 w_base_t::uint8_t thresh_oct_unsigned =
00265 ULONGLONGCONSTANT(0xe000000000000000);
00266 w_base_t::uint8_t thresh_oct_signed =
00267 LONGLONGCONSTANT(0xf000000000000000);
00268
00269
00270
00271
00272
00273 istream &
00274 w_base_t::_scan_uint8(
00275 istream& i,
00276 w_base_t::uint8_t &u8,
00277 bool chew_white,
00278 bool is_signed,
00279 bool& range_err
00280 )
00281 {
00282 w_base_t::uint8_t thresh=0,
00283 thresh2=0 ,
00284 thresh3=0, thresh4=0;
00285 w_base_t::uint8_t value = 0;
00286
00287 bool negate = false;
00288 int e=0;
00289 int base=0;
00290 bool skip_white = true;
00291 states s = start;
00292 streampos tell_start = i.tellg();
00293 int chewamt = chew_white? 1 : 0;
00294 XTABLE *table=0;
00295
00296 range_err = false;
00297 {
00298
00299 ios_fmtflags old = i.flags();
00300 skip_white = ((old & ios::skipws) != 0);
00301 switch(old & ios::basefield) {
00302 case int(0):
00303 base = 0;
00304 table = &table_unknown;
00305 break;
00306
00307 case ios::hex:
00308 base = 4;
00309 table = &table_base16;
00310 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00311 break;
00312
00313 case ios::oct:
00314 base = 3;
00315 table = &table_base8;
00316 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00317 break;
00318
00319 case ios::dec:
00320 base = 10;
00321 table = &table_base10;
00322 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00323 thresh2 = is_signed? thresh2_dec_signed : thresh2_dec_unsigned;
00324 thresh3 = is_signed? (negate? 8: 7) : 5;
00325 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00326 break;
00327 default:
00328 W_FATAL(fcINTERNAL);
00329 break;
00330 }
00331 }
00332
00333 int ich;
00334 char ch;
00335 while (s < end) {
00336 ch = 0;
00337
00338 ich = i.get();
00339 if (ich != EOF) {
00340 ch = char(ich);
00341
00342 if(isspace(ch)) {
00343 e = white;
00344 } else {
00345 e = equiv[unsigned(ch)];
00346 }
00347 }
00348 else
00349 e = eofile;
00350
00351
00352
00353
00354
00355 s = (*table)[e][s];
00356
00357 switch(s) {
00358 case start:
00359
00360 if(!skip_white) {
00361 s = end;
00362 }
00363 tell_start += chewamt;
00364 break;
00365
00366 case sgned:
00367 if(ch == '-') {
00368 negate = true;
00369 if(thresh3!=0) thresh3 = is_signed? (negate? 8: 7) : 5;
00370 }
00371 break;
00372
00373 case leadz:
00374
00375
00376
00377
00378 break;
00379
00380 case new_hex:
00381
00382 if(base && (base != 4)) {
00383
00384 IOS_BACK(i, ch);
00385 s = end;
00386 break;
00387 }
00388 w_assert9(base == 0 || base == 4);
00389 if((base == 0) && (e != exx)) {
00390
00391 IOS_BACK(i, ch);
00392 s = end;
00393 break;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403 base = 4;
00404 if(e != exx) {
00405 IOS_BACK(i, ch);
00406 } else {
00407
00408
00409 tell_start = i.tellg();
00410 tell_start -= 1;
00411 }
00412 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00413 break;
00414
00415 case new_oct:
00416
00417 if(base==0 || base == 3) {
00418
00419 base = 3;
00420 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00421 } else if(base == 10) {
00422 s = new_dec;
00423 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00424 thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
00425 thresh3 = is_signed? (negate? 8: 7) : 5;
00426 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00427 } else {
00428 w_assert9(base == 4);
00429 s = new_hex;
00430 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00431 }
00432 IOS_BACK(i, ch);
00433 break;
00434
00435 case new_dec:
00436
00437
00438
00439 if(e == eight || e == nine) {
00440 if(base && base != 10) {
00441
00442 IOS_BACK(i, ch);
00443 s = end;
00444 break;
00445 }
00446 }
00447 if(base==0 || base == 10) {
00448
00449 base = 10;
00450 thresh = is_signed? thresh_dec_signed : thresh_dec_unsigned;
00451 thresh2= is_signed?thresh2_dec_signed : thresh2_dec_unsigned;
00452 thresh3 = is_signed? (negate? 8: 7) : 5;
00453 thresh4 = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00454 } else if(base == 3) {
00455 s = new_oct;
00456 thresh = is_signed? thresh_oct_signed : thresh_oct_unsigned;
00457 } else {
00458 w_assert9(base == 4);
00459 thresh = is_signed? thresh_hex_signed : thresh_hex_unsigned;
00460 s = new_hex;
00461 }
00462 IOS_BACK(i, ch);
00463 break;
00464
00465 case is_hex:
00466 w_assert9(base == 4);
00467
00468
00469 case is_oct:
00470 if(value & thresh) {
00471 range_err = true;
00472
00473
00474 break;
00475 }
00476
00477 value <<= base;
00478 value += int(e);
00479 break;
00480
00481 case is_dec:
00482 w_assert9(base == 10);
00483 if(value & thresh4) {
00484 if(value > thresh2) {
00485
00486 range_err = true;
00487
00488
00489 break;
00490 }
00491 value *= base;
00492 if((value - thresh2) + unsigned(e) > thresh3) {
00493
00494 range_err = true;
00495
00496
00497 break;
00498 }
00499 } else {
00500
00501 value *= base;
00502 }
00503 value += unsigned(e);
00504 break;
00505
00506 case error:
00507 IOS_FAIL(i);
00508 i.seekg(tell_start);
00509 s = end;
00510 break;
00511
00512 case no_hex:
00513 i.seekg(tell_start);
00514 s = end;
00515 break;
00516
00517 case end:
00518 IOS_BACK(i, ch);
00519 break;
00520
00521 case no_state:
00522 W_FATAL(fcINTERNAL);
00523 break;
00524 }
00525 }
00526 if(range_err) {
00527
00528 u8 = negate ?
00529 ( is_signed? w_base_t::int8_min : w_base_t::uint8_max) :
00530 ( is_signed? w_base_t::int8_max : w_base_t::uint8_max);
00531 IOS_FAIL(i);
00532 } else {
00533 u8 = negate ? (0 - value) : value;
00534 }
00535
00536 return i;
00537 }
00538
00539