BIscan.h

Go to the documentation of this file.
00001 #ifndef CXX_TOOLS_BIscan_header_included_p
00002 #define CXX_TOOLS_BIscan_header_included_p
00003 //
00004 // Copyright 2010, Lowell Boggs Jr.
00005 //
00006 // This file or directory, containing source code for a computer program,
00007 // is Copyrighted by Lowell Boggs, Jr.  987 Regency Drive, Lewisville
00008 // TX (USA), 75067.  You may use, copy, modify, and distribute this
00009 // source file without charge or obligation so long as you agree to
00010 // the following:
00011 //
00012 //  1.  You must indemnify Lowell Boggs against any and all financial
00013 //      obligations caused by its use, misuse, function, or malfunction.
00014 //      Further, you acknowledge that there is no warranty of any kind,
00015 //      whatsoever.
00016 //
00017 //  2.  You agree not to attempt to patent any portion of this original
00018 //      work -- though you may attempt to patent your own extensions to
00019 //      it if you so choose.
00020 //
00021 //  3.  You keep this copyright notice with the file and all copies
00022 //      of the file and do not change it anyway except language translation.
00023 //
00024 // You are responsible for enforcing your own compliance with these
00025 // conditions and may not use this source file if you cannot agree to the
00026 // above terms and conditions.
00027 //
00028 #include <string>
00029 #include <string.h> /* for strlen */
00030 #include <stdio.h>  /* for sscanf */
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;   // the reference to the start of  buffer does
00299                                     // not get modified unless parsing is 
00300                                     // successful.
00301     
00302        if(startRef != end)
00303        {
00304            char validator = *startRef; 
00305                                           // if this line fails to compile, your iterator 
00306                                           // does not point to a character.
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            // signed numbers are allowed
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            // speed optimization for the most common case
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; // return the new start of the character buffer.
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;  // p is a copy of s, we don't want to pass s to convertInteger
00394                            // because it modifies its parameter.
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                                          // convertInteger modifies its first parameter
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;  // p is a copy of s, we don't want to pass s to convertInteger
00494                            // because it modifies its parameter.
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;  // p is a copy of s, we don't want to pass s to convertInteger
00528                            // because it modifies its parameter.  (Only the pointer is copied,
00529                            // not the data)
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   // forward declare class Stream and various functions that are allowed to
00568   // construct Stream objects.  Stream objects are meant to be used only as
00569   // compiler temporaries.  It is not generally allowed to construct named variables
00570   // of type Stream.  There is little need for it and the Stream::operator!() makes
00571   // this a bit iffy in practice.  See below.
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        // Maintenance note:  the design of this class with respect to operator!() and
00652        // operator void const *(), substituting for operator bool, is very flakey.  
00653        // Duplicating it would be a bad idea because this class only works because you
00654        // cannot have variables to class Stream -- you can only have compiler temporaries
00655        // and that part of the design was necessitated by the goofy way operator! and
00656        // operator void const *() are required to work.
00657 
00658        char const *start_;
00659        char const *end_;
00660        bool        bad_;
00661        bool        invertedLogic_;  // see operator!() for details.
00662     
00663        // -----------------------------------------------------------------------------------
00664        // the Stream constructor is private and should remain so.
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        // Use a stream() function to construct streams.
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            //  This is a goofy implementation that works only because
00695            //  class Stream is not allowed to have named variables constructed for it.
00696            //
00697            //  See Stream::operator!(), below
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            //  This is a goofy implementation that works only because
00712            //  class Stream is not allowed to have named variables constructed for it.
00713            //
00714 
00715            invertedLogic_ ^= true; 
00716            return *this;  
00717 
00718            // for such a little function, this one needs a lot of comments.
00719            //
00720            //  This function would not exist if we only allowed the following
00721            //  syntaxes for use by Streams:
00722            //
00723            //     stream("string") >> v1 >> v2 >> v3;   // uses stream() below to
00724            //                                           // determine kind of Stream
00725            //
00726            //     if( stream("string") >> v4 >> v5 )    // uses stream() below
00727            //     {
00728            //        // parsing good!
00729            //     }
00730            //
00731            //
00732            //  However, if we want the following syntax to work: 
00733            //
00734            //    if( !stream("string") >> v1 >> v2 >> v3)
00735            //    {
00736            //       // parsing failed!
00737            //    }
00738            //
00739            //  Then we must have this method.
00740            //
00741            //  Why?  Good question!  Here's the answer:  Operator ! binds more
00742            //  strongly than does operator >>.  Thus, '!stream("s")' is evaluated
00743            //  before the operator>>.  The default operator not (!) returns a bool, and
00744            //  then operator>> is applied to the bool not to the stream.
00745            //  Doh!  However, this is the way C++ works.
00746            //
00747            //  Why does adding operator! to Stream class solve the problem?  Because
00748            //  we get to change the return type!  Instead of returning bool, as you
00749            //  would expect operator! to do, we return the stream itself with a flag set
00750            //  indicating that its operator! should now work backwards.  Sneaky huh?
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            // Parse an integer and return it.  Skips leading whitespace.
00786            // @return      this stream
00787            // @param[out]  object the data parsed
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            // Parse an double and return it.
00804            // @return      this stream
00805            // @param[out]  d the data parsed
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; // didn't match so try the next one
00859              }
00860 
00861              if(scan == last)
00862              {
00863                 // current character in the stream is not in the
00864                 // character set
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;  // leave room for null terminator
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; // null terminate
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     }; // class Stream
00999 
01000     // -----------------------------------------------------------------------------------
01001 
01002     template<class T>
01003     struct IsIntType
01010     {
01011          // none of the following functions and variables is
01012          // ever defined.  They exist so that sizeof( f(t) )
01013          // will evaluate to the size of the correct type (either char or int).
01014 
01015          static T* t;  
01016 
01017          static int f( void const * );   // handles all types of data
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     // specialization 2 MUST NOT EXIST.  See Hex(), below
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     // specialization 4 MUST NOT EXIST.  See Octal(), below
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     // specialization 6 MUST NOT EXIST.  See Octal(), below
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         // s must const & or you can't get his code compile
01116     
01117       Stream &mystream = const_cast<Stream&>(s);
01118     
01119       if(mystream.bad())
01120          return mystream;
01121     
01122       // mystream.parseInteger(variable);
01123 
01124       StreamReader<IntegerType, IsIntType<IntegerType>::value >() (mystream, variable);
01126          //   variable reference is not an integer.  See IsIntType<> above for a list
01127          //   of the allowed types.
01128     
01129       return mystream;
01130     }
01131     
01132     // -----------------------------------------------------------------------------------
01133 
01134     inline Stream &operator>> (Stream const & s, char &c)
01144     {
01145         // s must const & or you can't get his code to compile
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          //   variable reference is not an integer.  See IsIntType<> above for a list
01415          //   of the allowed types.
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          //   variable reference is not an integer.  See IsIntType<> above for a list
01525          //   of the allowed types.
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          //  If the above line of code fails to compile, it is because your
01626          //   variable reference is not an integer.  See IsIntType<> above for a list
01627          //   of the allowed types.
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 } // namespace BIscan
01761 
01762 #endif
Generated on Wed Feb 29 22:50:03 2012 for CXXUtilities by  doxygen 1.6.3