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 }