"Fossies" - the Fresh Open Source Software Archive

Member "gama-2.05/lib/gnu_gama/local/itstream.h" (10 May 2019, 9188 Bytes) of package /linux/privat/gama-2.05.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "itstream.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2     GNU Gama -- adjustment of geodetic networks
    3     Copyright (C) 1999  Ales Cepek <cepek@fsv.cvut.cz>
    4 
    5     This file is part of the GNU Gama C++ library.
    6 
    7     This library is free software; you can redistribute it and/or modify
    8     it under the terms of the GNU General Public License as published by
    9     the Free Software Foundation; either version 3 of the License, or
   10     (at your option) any later version.
   11 
   12     This library is distributed in the hope that it will be useful,
   13     but WITHOUT ANY WARRANTY; without even the implied warranty of
   14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15     GNU General Public License for more details.
   16 
   17     You should have received a copy of the GNU General Public License
   18     along with this library; if not, write to the Free Software
   19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   20 */
   21 
   22 #ifndef gama_local_Input_Text_Stream_h
   23 #define gama_local_Input_Text_Stream_h
   24 
   25 #include <string>
   26 #include <stack>
   27 #include <utility>
   28 #include <cctype>
   29 #include <cstdlib>
   30 #include <cerrno>
   31 
   32 namespace GNU_gama { namespace local {
   33 
   34 template <typename InputStream> class InputTextStream {
   35 
   36   // template parameter InputStream must implement `bool get(char&)'
   37   // with the same meaning as std::istream::get(char&)
   38 
   39 public:
   40 
   41   InputTextStream(InputStream& inp, bool sc=false, size_t alloc=256) :
   42     input_stream_(inp), skip_comments_(sc), eot_(false), stop_(false),
   43     byte_(0), line_(0), index_(0), end_(0)
   44     {
   45       buffer_.resize(alloc);
   46       read_buffer_();
   47     }
   48 
   49   void push_back(char c) { stack_.push(c); }
   50   void push_back(const std::string&);
   51 
   52   bool get(char&);                        // get char (' ' on eot() or eol())
   53   bool get(std::string&);                 //     word
   54   bool get(int&);                         //     int
   55   bool get(double&);                      //     double
   56 
   57   bool get_int(std::string&);             //     word representing integer
   58   bool get_float(std::string&);           //                       float
   59 
   60   bool eot() const { return eot_; }       // end of text
   61   bool eol() const { return eol_; }       // end of line
   62 
   63   bool skip_comments() const { return skip_comments_; }
   64   bool skip_comments(bool b) { return skip_comments_ = b; }
   65 
   66   bool skip_ws();                         // skip white spaces
   67 
   68   size_t byte()  const { return byte_;  } // current byte
   69   size_t line()  const { return line_;  } //         line
   70 
   71   std::pair<const char*, size_t> get_buffer() const {
   72       return std::pair<const char*, size_t>(buffer_.c_str(), end_);
   73   }
   74   size_t get_buffer_index() const { return index_; }
   75 
   76 private:
   77 
   78   InputStream&     input_stream_;
   79   bool             skip_comments_;
   80   bool             eot_, eol_, stop_;
   81   std::string      buffer_;
   82   size_t           byte_, line_, index_, end_;
   83   std::stack<char> stack_;
   84 
   85   void read_buffer_();
   86 
   87 };
   88 
   89 template <typename InputStream>
   90 inline bool InputTextStream<InputStream>::get(char& c)
   91   {
   92     if (!stack_.empty())
   93       {
   94         c = stack_.top();
   95         stack_.pop();
   96         eol_ = false;    // pushed back 'eols' are ignored
   97         return true;
   98       }
   99 
  100     for (;;)
  101       if (eot_)
  102         {
  103           c = ' ';
  104           eol_ = true;
  105           return false;
  106         }
  107       else if (index_ < end_)
  108         {
  109           c = buffer_[index_];
  110           ++index_;
  111           ++byte_;
  112           if (skip_comments_ && (c == '#') )
  113             {
  114               c = ' ';
  115               byte_ += end_ - index_ + 1;
  116               index_ = end_ + 1;
  117               eol_   = true;
  118               return true;
  119             }
  120           eol_ = false;
  121           return true;
  122         }
  123       else if (index_ == end_)
  124         {
  125           c = ' ';
  126           ++index_;
  127           ++byte_;
  128           eol_ = true;
  129           return true;
  130         }
  131       else
  132         {
  133           read_buffer_();
  134         }
  135   }
  136 
  137 template <typename InputStream>
  138 bool InputTextStream<InputStream>::get(int& n)
  139   {
  140     using namespace std;
  141     string word;
  142 
  143     if (!get_int(word)) return false;
  144     errno = 0;
  145     n = atoi(word.c_str());
  146 
  147     if (errno)
  148       {
  149         push_back(word);
  150         n = 0;
  151         return false;
  152       }
  153 
  154     return true;
  155   }
  156 
  157 template <typename InputStream>
  158 bool InputTextStream<InputStream>::get(double& n)
  159   {
  160     using namespace std;
  161     string word;
  162 
  163     if (!get_float(word)) return false;
  164     errno = 0;
  165     n = atof(word.c_str());
  166 
  167     if (errno)
  168       {
  169         push_back(word);
  170         n = 0;
  171         return false;
  172       }
  173 
  174     return true;
  175   }
  176 
  177 template <typename InputStream>
  178 bool InputTextStream<InputStream>::get_int(std::string& word)
  179   {
  180     word = "";
  181     skip_ws();
  182 
  183     char sign;
  184     get(sign);
  185     switch (sign) {
  186     case '+':
  187     case '-':
  188       word += sign;
  189       break;
  190     default:
  191       push_back(sign);
  192       break;
  193     }
  194 
  195     char digit;
  196     while(get(digit))
  197       {
  198         bool eod = false;
  199         switch (digit) {
  200         case '0': case '1': case '2': case '3': case '4':
  201         case '5': case '6': case '7': case '8': case '9':
  202           word += digit;
  203           break;
  204         default:
  205           push_back(digit);
  206           eod = true;
  207           break;
  208         }
  209         if (eod) break;
  210       }
  211 
  212     if (word == "+" || word == "-")
  213       {
  214         push_back(word[0]);
  215         return false;
  216       }
  217 
  218     return word!="";
  219   }
  220 
  221 template <typename InputStream>
  222 bool InputTextStream<InputStream>::get_float(std::string& word)
  223   {
  224     word = "";
  225     skip_ws();
  226 
  227     char sign;
  228     get(sign);
  229     switch (sign) {
  230     case '+':
  231     case '-':
  232       word += sign;
  233       break;
  234     default:
  235       push_back(sign);
  236       break;
  237     }
  238 
  239     bool has_digit = false;
  240     char digit;
  241     while(get(digit))
  242       {
  243         bool eod = false;
  244         switch(digit) {
  245         case '0': case '1': case '2': case '3': case '4':
  246         case '5': case '6': case '7': case '8': case '9':
  247           word += digit;
  248           has_digit = true;
  249           break;
  250         default:
  251           push_back(digit);
  252           eod = true;
  253           break;
  254         }
  255         if (eod) break;
  256       }
  257 
  258     char dot;
  259     get(dot);
  260     switch(dot) {
  261     case '.':
  262       word += dot;
  263       break;
  264     default:
  265       push_back(dot);
  266     }
  267 
  268     while(get(digit))
  269       {
  270         bool eod = false;
  271         switch(digit) {
  272         case '0': case '1': case '2': case '3': case '4':
  273         case '5': case '6': case '7': case '8': case '9':
  274           word += digit;
  275           has_digit = true;
  276           break;
  277         default:
  278           push_back(digit);
  279           eod = true;
  280           break;
  281         }
  282         if (eod) break;
  283       }
  284 
  285     if (!has_digit) {
  286       push_back(word);
  287       word = "";
  288       return false;
  289     }
  290 
  291     char e;
  292     get(e);
  293     if (e != 'e' && e !='E')
  294       push_back(e);
  295     else
  296       {
  297         std::string exp;
  298         exp += e;
  299 
  300         get(sign);
  301         switch(sign) {
  302         case '+':
  303         case '-':
  304           exp += sign;
  305           break;
  306         default:
  307           push_back(sign);
  308           break;
  309         }
  310 
  311         has_digit = false;
  312         while(get(digit))
  313           {
  314             bool eod = false;
  315             switch(digit) {
  316             case '0': case '1': case '2': case '3': case '4':
  317             case '5': case '6': case '7': case '8': case '9':
  318               exp += digit;
  319               has_digit = true;
  320               break;
  321             default:
  322               push_back(digit);
  323               eod = true;
  324               break;
  325             }
  326             if (eod) break;
  327           }
  328 
  329         word += exp;
  330         if (!has_digit)
  331           {
  332             push_back(word);
  333             word = "";
  334             return false;
  335           }
  336       }
  337 
  338     return true;
  339   }
  340 
  341 template <typename InputStream>
  342 bool InputTextStream<InputStream>::get(std::string& word)
  343   {
  344     word = "";
  345 
  346     if (!skip_ws()) return false;
  347 
  348     char  c;
  349     while (get(c))
  350       {
  351         if (isspace(c))
  352           {
  353             push_back(c);
  354             return true;
  355           }
  356         word += c;
  357       }
  358 
  359     return true;
  360   }
  361 
  362 template <typename InputStream>
  363 void InputTextStream<InputStream>::push_back(const std::string& word )
  364   {
  365     using namespace std;
  366     stack_.push(' ');
  367     for (string::const_reverse_iterator r=word.rbegin(); r!=word.rend(); ++r)
  368       stack_.push(*r);
  369   }
  370 
  371 template <typename InputStream>
  372 bool InputTextStream<InputStream>::skip_ws()
  373   {
  374     char c;
  375     while (get(c))
  376       if (!isspace(c))
  377         {
  378           push_back(c);
  379           break;
  380         }
  381     return !eot();
  382   }
  383 
  384 template <typename InputStream>
  385 void InputTextStream<InputStream>::read_buffer_()
  386   {
  387     if (eot_) return;
  388     if (stop_)
  389       {
  390         eot_ = true;
  391         return;
  392       }
  393 
  394     ++line_;
  395     eol_ = false;
  396     index_ = end_ = 0;
  397     char c;
  398     while (input_stream_.get(c))
  399       {
  400         if (c == '\n')
  401           {
  402             if (end_ < buffer_.length())
  403               buffer_[end_] = ' ';
  404             else
  405               buffer_ += ' ';
  406             return;
  407           }
  408 
  409         if (end_ < buffer_.length())
  410           buffer_[end_] = c;
  411         else
  412           buffer_ += c;
  413         end_++;
  414       }
  415 
  416     stop_ = true;
  417     eot_  = (index_ == end_);
  418     if (eot_) --line_;
  419   }
  420 
  421 }}   // namespace GNU_gama::local
  422 
  423 #endif