LineParser.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2018 New Eagle
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of New Eagle nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034  
00035 #include <dbc/LineParser.h>
00036 
00037 namespace NewEagle
00038 {
00039   LineParser::LineParser(const std::string &line)
00040   {
00041     _line = line;
00042     _position = 0;
00043   }
00044 
00045   LineParser::~LineParser()
00046   {
00047   }
00048 
00049   int32_t LineParser::GetPosition()
00050   {
00051     return _position;
00052   }
00053 
00054   std::string LineParser::ReadCIdentifier()
00055   {
00056     SkipWhitespace();
00057 
00058     if (AtEOL())
00059     {
00060       throw LineParserAtEOLException();
00061     }
00062 
00063     if (!isalpha(_line[_position]) && _line[_position] != '_')
00064     {
00065       throw std::runtime_error("ReadCIdentifier: Unexpected character");
00066     }
00067 
00068     int32_t startIdx = _position;
00069 
00070     for(_position++; !AtEOL(); _position++)
00071     {
00072       if (!(isalpha(_line[_position]) || isdigit(_line[_position])) && _line[_position] != '_')
00073       {
00074         int32_t len = _position - startIdx;
00075         return _line.substr(startIdx, len);
00076       }
00077     }
00078 
00079     return _line.substr(startIdx, std::string::npos);
00080   }
00081 
00082   std::string LineParser::ReadCIdentifier(std::string fieldName)
00083   {
00084     std::string val = ReadCIdentifier();
00085 
00086     if (val == std::string())
00087     {
00088       throw std::runtime_error("Synxax Error: Expected : " + fieldName);
00089     }
00090 
00091     return val;
00092 
00093   }
00094 
00095   void LineParser::SkipWhitespace()
00096   {
00097     while(!AtEOL() && isspace(_line[_position]))
00098     {
00099       _position++;
00100     }
00101   }
00102 
00103   bool LineParser::AtEOL()
00104   {
00105     return _position >= _line.length();
00106   }
00107 
00108   char LineParser::ReadNextChar()
00109   {
00110     SkipWhitespace();
00111 
00112     if (AtEOL())
00113     {
00114       throw LineParserAtEOLException(); 
00115     }
00116 
00117     int32_t idx = _position;
00118     _position++;
00119 
00120     return _line[idx];
00121 
00122   }
00123 
00124   char LineParser::ReadNextChar(std::string fieldName)
00125   {
00126     try
00127     {
00128       char val = ReadNextChar();
00129       return val;
00130     }
00131     catch(LineParserExceptionBase& exlp)
00132     {
00133       throw;
00134     }
00135 
00136   }
00137 
00138   uint32_t LineParser::PeekUInt()
00139   {
00140     SkipWhitespace();
00141 
00142     if (AtEOL())
00143     {
00144       throw LineParserAtEOLException(); 
00145     }
00146 
00147     int32_t position = _position;
00148 
00149     int32_t startIdx = position;
00150     int32_t len = -1;
00151 
00152     for(; !AtEOL(); position++)
00153     {
00154       if (!isdigit(_line[position]))
00155       {
00156         len = position - startIdx;
00157         break;
00158       }
00159     }
00160 
00161     if (-1 == len)
00162     {
00163       len = position - startIdx;
00164     }
00165 
00166     if (0 == len)
00167     {
00168       throw LineParserLenZeroException(); 
00169     }
00170 
00171     std::istringstream reader(_line.substr(startIdx, len));
00172     uint32_t val;
00173     reader >> val;
00174 
00175     return val;
00176   }
00177 
00178   uint32_t LineParser::ReadUInt()
00179   {
00180     SkipWhitespace();
00181 
00182     if (AtEOL())
00183     {
00184       throw LineParserAtEOLException(); 
00185     }
00186 
00187     int32_t startIdx = _position;
00188     int32_t len = -1;
00189 
00190     for(; !AtEOL(); _position++)
00191     {
00192       if (!isdigit(_line[_position]))
00193       {
00194         len = _position - startIdx;
00195         break;
00196       }
00197     }
00198 
00199     if (-1 == len)
00200     {
00201       len = _position - startIdx;
00202     }
00203 
00204     if (0 == len)
00205     {
00206       throw LineParserLenZeroException(); 
00207     }
00208 
00209     std::istringstream reader(_line.substr(startIdx, len));
00210     uint32_t val;
00211     reader >> val;
00212 
00213     return val;
00214   }
00215 
00216   uint32_t LineParser::ReadUInt(std::string fieldName)
00217   {
00218     try
00219     {
00220       uint32_t val = ReadUInt();
00221       return val;
00222     }
00223     catch(LineParserExceptionBase& exlp)
00224     {
00225       throw;
00226     }
00227   }
00228 
00229   int32_t LineParser::ReadInt()
00230   {
00231     SkipWhitespace();
00232 
00233     if (AtEOL())
00234     {
00235       throw LineParserAtEOLException(); 
00236     }
00237 
00238     if (!isdigit(_line[_position]) && _line[_position] != '-' && _line[_position] != '+')
00239     {
00240       throw LineParserInvalidCharException(); 
00241     }
00242 
00243     int32_t startIdx = _position;
00244     int32_t len = -1;
00245 
00246     for(_position++; !AtEOL(); _position++)
00247     {
00248       if (!isdigit(_line[_position]))
00249       {
00250         len = _position - startIdx;
00251         break;
00252       }
00253     }
00254 
00255     if (-1 == len)
00256     {
00257       len = _position - startIdx;
00258     }
00259 
00260     if (0 == len)
00261     {
00262       throw LineParserLenZeroException(); 
00263     }
00264 
00265     std::istringstream reader(_line.substr(startIdx, len));
00266     int32_t val;
00267     reader >> val;
00268 
00269     return val;
00270 
00271   }
00272 
00273   double LineParser::ReadDouble()
00274   {
00275     SkipWhitespace();
00276 
00277     if (AtEOL())
00278     {
00279       throw LineParserAtEOLException(); 
00280     }
00281 
00282     if (!isdigit(_line[_position]) && _line[_position] != '-' && _line[_position] != '+')
00283     {
00284       throw LineParserInvalidCharException(); 
00285     }
00286 
00287     int32_t startIdx = _position;
00288     int32_t len = -1;
00289 
00290     NewEagle::ReadDoubleState state = NewEagle::READING_WHOLE_NUMBER;
00291 
00292     for(_position++; !AtEOL(); _position++)
00293     {
00294       char c = _line[_position];
00295 
00296       switch (state) {
00297         case NewEagle::READING_WHOLE_NUMBER:
00298           if ('E' == c || 'e' == c)
00299           {
00300             state = NewEagle::READ_E;
00301           }
00302           else if('.' == c)
00303           {
00304             state = NewEagle::READING_FRACTION;
00305           }
00306           else if (!isdigit(c))
00307           {
00308             goto DoneReading;
00309           }
00310           break;
00311         case NewEagle::READING_FRACTION:
00312           if ('E' == c || 'e' == c)
00313           {
00314             state = NewEagle::READ_E;
00315           }
00316           else if(!isdigit(c))
00317           {
00318             goto DoneReading;
00319           }
00320           break;
00321         case NewEagle::READ_E:
00322           if ('+' == c || '-' == c)
00323           {
00324             state = NewEagle::READ_SIGN;
00325           }
00326           else if (isdigit(c))
00327           {
00328             state = NewEagle::READING_EXP;
00329           }
00330           break;
00331         case NewEagle::READ_SIGN:
00332           if (!isdigit(c))
00333           {
00334             throw LineParserInvalidCharException();
00335           }
00336           else
00337           {
00338             state = NewEagle::READING_EXP;
00339           }
00340 
00341           break;
00342         case NewEagle::READING_EXP:
00343           if (!isdigit(c))
00344           {
00345             goto DoneReading;
00346           }
00347           break;
00348         default:
00349           break;
00350 
00351       }
00352 
00353     }
00354 
00355 DoneReading:
00356     len = _position - startIdx;
00357 
00358     if (0 == len)
00359     {
00360       throw LineParserLenZeroException(); 
00361     }
00362 
00363     std::istringstream reader(_line.substr(startIdx, len));
00364     double val;
00365     reader >> val;
00366 
00367     return val;
00368 
00369   }
00370 
00371   double LineParser::ReadDouble(std::string fieldName)
00372   {
00373     try
00374     {
00375       double val = ReadDouble();
00376      return val;
00377     }
00378     catch(LineParserExceptionBase& exlp)
00379     {
00380       throw;
00381     }
00382 
00383   }
00384 
00385   void LineParser::SeekSeparator(char separator)
00386   {
00387     char nextChar = ReadNextChar();
00388 
00389     if (nextChar == 0x00 || nextChar != separator)
00390     {
00391       throw std::runtime_error("Synxax Error: Expected : " + separator);
00392     }
00393   }
00394 
00395   std::string LineParser::ReadQuotedString()
00396   {
00397     SkipWhitespace();
00398 
00399     if (AtEOL())
00400     {
00401       throw LineParserAtEOLException(); 
00402     }
00403 
00404     if (_line[_position] != '"')
00405     {
00406       throw std::runtime_error("ReadQuotedString: Missing Quote");
00407     }
00408 
00409     int32_t startIdx = ++_position;
00410     int32_t len  = -1;
00411 
00412     for (; _position < _line.size(); _position++)
00413     {
00414       if (_line[_position] == '"')
00415       {
00416         len = _position - startIdx;
00417         _position++;
00418         break;
00419       }
00420     }
00421 
00422     if (-1 == len)
00423     {
00424       throw LineParserLenZeroException();
00425     }
00426 
00427     if (0 == len)
00428     {
00429       throw LineParserLenZeroException(); 
00430     }
00431 
00432     return _line.substr(startIdx, len);
00433   }
00434 }


dbc
Author(s): Ryan Borchert
autogenerated on Mon Jun 24 2019 19:18:30