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