00001 #ifndef CXX_TOOLS_BIscan_header_included_p
00002 #define CXX_TOOLS_BIscan_header_included_p
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 #include <string>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032
00033
00043
00044
00045
00106
00107
00108
00109 namespace BIscan
00170 {
00171
00172
00173
00174 inline bool isValidDigit(char c, int base)
00186 {
00187 if(base == 16)
00188 return isxdigit(c);
00189
00190 if(base <= 10 && base > 1)
00191 {
00192 return (c >= '0') && ((c - '0') < base);
00193 }
00194
00195 return false;
00196 }
00197
00198
00199
00200 inline int digitValue(char c, int base=10)
00214 {
00215 if(base == 16 && isxdigit(c))
00216 {
00217 c = toupper(c);
00218
00219 if(c < 'A')
00220 return c - '0';
00221
00222 return c - 'A' + 10;
00223
00224 }
00225 else
00226 return c - '0';
00227
00228 return 0;
00229 }
00230
00231
00232
00233 template<class Iterator>
00234 inline bool parseUnsignedDecimal(Iterator &start,
00235 Iterator const &end,
00236 unsigned long long &tmp
00237 )
00248 {
00249 tmp = 0;
00250
00251 char c;
00252
00253 bool found=false;
00254
00255 while( start != end
00256 && ( (c=*start) >= '0')
00257 && ( c <= '9' )
00258 )
00259 {
00260 ++found;
00261 ++start;
00262 tmp *= 10;
00263 tmp += c - '0';
00264 }
00265
00266 return found;
00267
00268 }
00269
00270
00271
00272
00273 template<class T, class Iterator>
00274 inline bool parseInteger(Iterator &startRef,
00275 Iterator const &end,
00276 T &integer,
00277 int base=10,
00278 bool signable=true
00279 )
00297 {
00298 Iterator start = startRef;
00299
00300
00301
00302 if(startRef != end)
00303 {
00304 char validator = *startRef;
00305
00306
00307 validator=validator;
00308 }
00309
00310 unsigned long long tmp=0;
00311
00312 while(start != end && isspace(*start))
00313 ++start;
00314
00315 if(start == end)
00316 return false;
00317
00318 bool negative=false;
00319
00320 if(signable)
00321 {
00322
00323
00324 if(*start == '-')
00325 {
00326 negative = true;
00327 ++start;
00328 }
00329
00330 if(start == end)
00331 return false;
00332 }
00333
00334 char c;
00335
00336 if( ! isValidDigit(c = *start, base) )
00337 return false;
00338
00339 if(base == 10)
00340 {
00341
00342
00343 if(! parseUnsignedDecimal(start, end, tmp) )
00344 return false;
00345
00346 }
00347 else
00348 {
00349 while( start != end
00350 && isValidDigit( c = *start, base )
00351 )
00352 {
00353 ++start;
00354 tmp *= base;
00355 tmp += digitValue(c,base);
00356 }
00357 }
00358
00359 if(negative)
00360 {
00361 long long negValue = tmp;
00362 negValue = -negValue;
00363 integer = negValue;
00364 }
00365 else
00366 integer = tmp;
00367
00368 startRef = start;
00369 return true;
00370 }
00371
00372
00373
00374 template<class T>
00375 bool convertInteger(char const * const &s,
00376 T &integer,
00377 int base=10,
00378 int signable=true
00379 )
00392 {
00393 char const *p = s;
00394
00395
00396 return parseInteger(p, p + strlen(s), integer, base, signable);
00397 }
00398
00399
00400
00401 template<class T, class StringType>
00402 bool convertInteger(StringType const &s,
00403 T &integer,
00404 int base=10,
00405 int signable=true
00406 )
00420 {
00421 typename StringType::const_iterator tmp(s.begin());
00422
00423
00424 return parseInteger(tmp, s.end(), integer, base, signable);
00425 }
00426
00427
00428
00429 template<class Iterator>
00430 inline bool parseDouble(Iterator & firstRef,
00431 Iterator const & last,
00432 double & d
00433 )
00443 {
00444 Iterator first = firstRef;
00445
00446 while( first != last && isspace(*first) )
00447 ++first;
00448
00449 static std::string floatDigits(".0123456789e+-");
00450
00451 char buffer[300];
00452
00453 char *scan = buffer;
00454
00455 char c;
00456
00457 while( first != last
00458 && floatDigits.find_first_of(c = *first) < floatDigits.size()
00459 )
00460 {
00461 *scan++ = c;
00462
00463 ++first;
00464
00465 if(scan > (buffer+ sizeof(buffer)-1))
00466 return false;
00467
00468 }
00469
00470 if(scan == buffer)
00471 return false;
00472
00473 *scan = 0;
00474
00475 if( 1 != sscanf(buffer, "%lf", &d) )
00476 return false;
00477
00478 firstRef = first;
00479 return true;
00480 }
00481
00482
00483
00484 inline bool convertDouble(char const * const &s, double &d)
00492 {
00493 char const *p = s;
00494
00495
00496 return parseDouble(p, p + strlen(s), d);
00497 }
00498
00499
00500
00501 template<class StringType>
00502 inline bool convertDouble(StringType const &s, double &d)
00510 {
00511 char const *p = s.data();
00512
00513 return parseDouble(p, s.data() + s.size(), d);
00514 }
00515
00516
00517
00518 inline bool convertFloat(char const * const &s, float &f)
00526 {
00527 char const *p = s;
00528
00529
00530
00531 double d;
00532
00533 bool rv = parseDouble(p, p + strlen(s), d);
00534
00535 f = d;
00536
00537 return rv;
00538 }
00539
00540
00541
00542 template<class StringType>
00543 inline bool convertFloat(StringType const &s, float &f)
00551 {
00552 double d;
00553
00554 char const *p = s.data();
00555
00556 bool rv = parseDouble(p, s.data() + s.size(), d);
00557
00558 f = d;
00559
00560 return rv;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 class Stream;
00574
00575 Stream stream(char const * const &p);
00576 Stream stream(char const * begin, char const *end);
00577
00578 template<class StringType>
00579 Stream stream(StringType const &p);
00580
00581 Stream stream(char const * begin, size_t length);
00582
00583
00584 class Stream
00649 {
00650
00651
00652
00653
00654
00655
00656
00657
00658 char const *start_;
00659 char const *end_;
00660 bool bad_;
00661 bool invertedLogic_;
00662
00663
00664
00665
00666 Stream(char const *start, char const *end)
00667 : start_(start)
00668 , end_ (end)
00669 , bad_ (0)
00670 , invertedLogic_(0)
00671 {
00672 }
00673
00674
00675
00676 friend Stream stream(char const * const &p);
00677 friend Stream stream(char const * begin, char const *end);
00678
00679 template<class StringType>
00680 friend Stream stream(StringType const &p);
00681
00682
00683 friend Stream stream(char const * begin, size_t length);
00684
00685
00686 public:
00687
00688
00689
00690 operator void const *() const
00692 {
00693
00694
00695
00696
00697
00698
00699
00700 if(invertedLogic_)
00701 return bad_ ? this : 0;
00702
00703 return bad_ ? 0 : this;
00704 }
00705
00706
00707
00708 inline Stream &operator !()
00709 {
00710
00711
00712
00713
00714
00715 invertedLogic_ ^= true;
00716 return *this;
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 }
00753
00754
00755
00756 bool empty() const { return start_ == end_; }
00757
00758 char first() const { return *start_; }
00759
00760
00761
00762 bool bad() const { return bad_; }
00763
00764
00765 void setBad(bool b) { bad_ = b; }
00766
00767
00768
00769 void pop_front() { ++start_; }
00770
00771
00772 unsigned long size() const { return end_ - start_; }
00773
00774
00775 char const *begin() const { return start_; }
00776
00777
00778 char const *end() const { return end_; }
00779
00780
00781
00782
00783 template<class IntType>
00784 Stream &parseInteger(IntType &object, int base=10, bool signable=true)
00785
00786
00787
00788 {
00789 if(bad())
00790 return *this;
00791
00792 if( !BIscan::parseInteger(start_, end_, object, base, signable) )
00793 {
00794 setBad(true);
00795 }
00796
00797 return *this;
00798 }
00799
00800
00801
00802 Stream &parseDouble(double &d)
00803
00804
00805
00806 {
00807 if(bad())
00808 return *this;
00809
00810 if( !BIscan::parseDouble(start_, end_, d) )
00811 {
00812 setBad(true);
00813 }
00814
00815 return *this;
00816 }
00817
00818
00819
00820 void skipWS()
00822 {
00823 while(start_ != end_ && isspace(*start_))
00824 ++start_;
00825 }
00826
00827
00828
00829 bool skipCharset(char const *first, char const *last)
00844 {
00845 bool found=false;
00846
00847 while(start_ != end_)
00848 {
00849 char const *scan = first;
00850
00851 char c = *start_;
00852
00853 while(scan != last)
00854 {
00855 if(c == *scan)
00856 break;
00857
00858 ++scan;
00859 }
00860
00861 if(scan == last)
00862 {
00863
00864
00865 break;
00866 }
00867
00868 found=true;
00869 ++start_;
00870 }
00871
00872 return found;
00873 }
00874
00875
00876
00877 bool skipString(char const *s)
00889 {
00890 skipWS();
00891
00892 char const *start = start_;
00893
00894 while(start != end_)
00895 {
00896 if(*start == *s)
00897 {
00898 ++start;
00899 ++s;
00900 }
00901 else
00902 break;
00903 }
00904
00905 if(*s == 0)
00906 {
00907 start_ = start;
00908 return true;
00909 }
00910
00911 return false;
00912
00913 }
00914
00915
00916
00917
00918 template<size_t N>
00919 size_t parseString( char (&array)[N] )
00931
00932 {
00933 if(bad_)
00934 {
00935 array[0] = 0;
00936 return 0;
00937 }
00938
00939 skipWS();
00940
00941 char *output = &array[0];
00942
00943 size_t avail = N-1;
00944
00945 size_t rv=0;
00946
00947 while(avail-- && start_ != end_ && !isspace(*start_) )
00948 {
00949 *output++ = *start_++;
00950 ++rv;
00951 }
00952
00953 *output = 0;
00954
00955 return rv;
00956 }
00957
00958
00959
00960 template<class StringType>
00961 size_t parseString(StringType &s )
00972
00973 {
00974 s.resize(0);
00975
00976 skipWS();
00977
00978 char buffer[257];
00979
00980 for(;;)
00981 {
00982 size_t bytesRead = parseString(buffer);
00983
00984 if(bytesRead == 0)
00985 break;
00986
00987 s.append(buffer, bytesRead);
00988
00989 if(empty() || isspace(*start_))
00990 break;
00991
00992 }
00993
00994
00995 return s.size();
00996 }
00997
00998 };
00999
01000
01001
01002 template<class T>
01003 struct IsIntType
01010 {
01011
01012
01013
01014
01015 static T* t;
01016
01017 static int f( void const * );
01018
01019 static char f(int);
01020 static char f(short);
01021 static char f(long);
01022 static char f(long long);
01023 static char f(unsigned int);
01024 static char f(unsigned short);
01025 static char f(unsigned long);
01026 static char f(unsigned long long);
01027 static char f(unsigned char);
01028
01029 enum { value = (1 == sizeof( f(*t) )) };
01030 };
01031
01032
01033
01034 template<class T, int TypeCategory=0>
01035 struct StreamReader
01042 {
01043 };
01044
01045
01046
01047 template<class T>
01048 struct StreamReader<T, 1>
01050 {
01051 void operator() (Stream &s, T &outputVariable)
01052 {
01053 s.parseInteger(outputVariable);
01054 }
01055 };
01056
01057
01058
01059
01060
01061
01062
01063 template<class T>
01064 struct StreamReader<T, 3>
01066 {
01067 void operator() (Stream &s, T &outputVariable)
01068 {
01069 s.parseInteger(outputVariable,16);
01070 }
01071 };
01072
01073
01074
01075
01076
01077
01078 template<class T>
01079 struct StreamReader<T, 5>
01081 {
01082 void operator() (Stream &s, T &outputVariable)
01083 {
01084 s.parseInteger(outputVariable,8);
01085 }
01086 };
01087
01088
01089
01090
01091
01092
01093
01094 template<class T>
01095 struct StreamReader<T, 7>
01097 {
01098 void operator() (Stream &s, T &outputVariable)
01099 {
01100 s.parseInteger(outputVariable,2);
01101 }
01102 };
01103
01104
01105
01106
01107 template<class IntegerType>
01108 inline Stream &operator>> (Stream const & s, IntegerType &variable)
01114 {
01115
01116
01117 Stream &mystream = const_cast<Stream&>(s);
01118
01119 if(mystream.bad())
01120 return mystream;
01121
01122
01123
01124 StreamReader<IntegerType, IsIntType<IntegerType>::value >() (mystream, variable);
01126
01127
01128
01129 return mystream;
01130 }
01131
01132
01133
01134 inline Stream &operator>> (Stream const & s, char &c)
01144 {
01145
01146
01147 Stream &mystream = const_cast<Stream&>(s);
01148
01149 if(mystream.bad())
01150 return mystream;
01151
01152 if(mystream.empty())
01153 {
01154 mystream.setBad(true);
01155 }
01156 else
01157 {
01158 c = mystream.first();
01159
01160 mystream.pop_front();
01161
01162 }
01163
01164 return mystream;
01165 }
01166
01167
01168
01169 template<size_t N>
01170 inline Stream &operator>> (Stream const &s, char (&array)[N] )
01180 {
01181 Stream &mystream = const_cast<Stream&>(s);
01182
01183 if(mystream.bad())
01184 return mystream;
01185
01186 mystream.parseString(array);
01187
01188 return mystream;
01189 }
01190
01191
01192
01193 inline Stream &operator>> (Stream const &s, char const *skipString)
01213 {
01214 Stream &mystream = const_cast<Stream&>(s);
01215
01216 if(mystream.bad())
01217 return mystream;
01218
01219 mystream.skipString(skipString);
01220
01221 return mystream;
01222 }
01223
01224
01225
01226 inline Stream &operator>> (Stream const &s, std::string &str )
01237 {
01238 Stream &mystream = const_cast<Stream&>(s);
01239
01240 if(mystream.bad())
01241 return mystream;
01242
01243 mystream.parseString(str);
01244
01245 return mystream;
01246 }
01247
01248
01249
01250 inline Stream &operator>> (Stream const & s, double &d)
01263 {
01264
01265 Stream &mystream = const_cast<Stream&>(s);
01266
01267 if(mystream.bad())
01268 return mystream;
01269
01270 mystream.parseDouble(d);
01271
01272 return mystream;
01273
01274 }
01275
01276
01277
01278 inline Stream &operator>> (Stream const & s, float &f)
01291 {
01292
01293 Stream &mystream = const_cast<Stream&>(s);
01294
01295 if(mystream.bad())
01296 return mystream;
01297
01298 double d;
01299
01300 mystream.parseDouble(d);
01301
01302 if(!mystream.bad())
01303 f = d;
01304
01305 return mystream;
01306
01307 }
01308
01309
01310
01311
01312 template<class IntegerType>
01313 struct HexParsed
01339 {
01340 IntegerType &output_;
01341
01342 HexParsed(IntegerType &data)
01343 : output_(data)
01344 {
01345 }
01346 };
01347
01348
01349
01350 template<class IntegerType>
01351 inline HexParsed<IntegerType> Hex(IntegerType &t)
01362 {
01363 return HexParsed<IntegerType>(t);
01364 }
01365
01366
01367
01368 template<class IntegerType>
01369 inline Stream &operator>> (Stream const &s, HexParsed<IntegerType> h )
01398 {
01399 Stream &myStream = const_cast<Stream&>(s);
01400
01401 if(myStream.bad())
01402 return myStream;
01403
01404 myStream.skipWS();
01405
01406 if(myStream.empty())
01407 {
01408 myStream.setBad(true);
01409 return myStream;
01410 }
01411
01412 StreamReader<IntegerType, (2 + IsIntType<IntegerType>::value) >() (myStream, h.output_);
01414
01415
01416
01417 return myStream;
01418 }
01419
01420
01421
01422 template<class IntegerType>
01423 struct OctalParsed
01448 {
01449 IntegerType &output_;
01450
01451 OctalParsed(IntegerType &data)
01452 : output_(data)
01453 {
01454 }
01455 };
01456
01457
01458
01459 template<class IntegerType>
01460 inline OctalParsed<IntegerType> Octal(IntegerType &t)
01471 {
01472 return OctalParsed<IntegerType>(t);
01473 }
01474
01475
01476
01477 template<class IntegerType>
01478 inline Stream &operator>> (Stream const &s, OctalParsed<IntegerType> o )
01507
01508 {
01509 Stream &myStream = const_cast<Stream&>(s);
01510
01511 if(myStream.bad())
01512 return myStream;
01513
01514 myStream.skipWS();
01515
01516 if(myStream.empty())
01517 {
01518 myStream.setBad(true);
01519 return myStream;
01520 }
01521
01522 StreamReader<IntegerType, (4 + IsIntType<IntegerType>::value) >() (myStream, o.output_);
01524
01525
01526
01527 return myStream;
01528 }
01529
01530
01531
01532 template<class IntegerType>
01533 struct BinaryParsed
01558
01559 {
01560 IntegerType &output_;
01561
01562 BinaryParsed(IntegerType &data)
01563 : output_(data)
01564 {
01565 }
01566 };
01567
01568
01569
01570 template<class IntegerType>
01571 inline BinaryParsed<IntegerType> Binary(IntegerType &t)
01582 {
01583 return BinaryParsed<IntegerType>(t);
01584 }
01585
01586
01587
01588 template<class IntegerType>
01589 inline Stream &operator>> (Stream const &s, BinaryParsed<IntegerType> o )
01609 {
01610 Stream &myStream = const_cast<Stream&>(s);
01611
01612 if(myStream.bad())
01613 return myStream;
01614
01615 myStream.skipWS();
01616
01617 if(myStream.empty())
01618 {
01619 myStream.setBad(true);
01620 return myStream;
01621 }
01622
01623 StreamReader<IntegerType, (6 + IsIntType<IntegerType>::value) >() (myStream, o.output_);
01624
01625
01626
01627
01628
01629 return myStream;
01630 }
01631
01632
01633
01634 struct SKIPSET
01650 {
01651 char const *first_;
01652 char const *last_;
01653
01654 SKIPSET(char const *f, char const *l)
01655 : first_(f)
01656 , last_(l)
01657 {
01658 }
01659
01660 explicit SKIPSET(char const *s)
01661 : first_(s)
01662 , last_( s + strlen(s))
01663 {
01664 }
01665
01666 };
01667
01668
01669
01670 inline Stream &operator>>( Stream &s, SKIPSET const &cs)
01687 {
01688 if(! s.skipCharset(cs.first_, cs.last_) )
01689 {
01690 s.setBad(true);
01691 }
01692
01693 return s;
01694 }
01695
01696
01697
01698 inline Stream stream(char const * const &p)
01707 {
01708 return Stream(p,p + strlen(p));
01709 }
01710
01711
01712
01713 inline Stream stream(char const * begin, char const *end)
01722
01723 {
01724 return Stream(begin,end);
01725 }
01726
01727
01728
01729 inline Stream stream(char const * begin, size_t length)
01738
01739 {
01740 return Stream(begin,begin + length);
01741 }
01742
01743
01744
01745 template<class StringType>
01746 inline Stream stream(StringType const &s)
01755 {
01756 return Stream( s.data(), s.data() + s.size() );
01757 }
01758
01759
01760 }
01761
01762 #endif