Own fork of MbedSmartRest
Dependents: MbedSmartRestMain MbedSmartRestMain
Fork of MbedSmartRest by
Parser.cpp
00001 /* 00002 * Parser.cpp 00003 * 00004 * Created on: Nov 1, 2013 00005 * * Authors: Vincent Wochnik <v.wochnik@gmail.com> 00006 * 00007 * Copyright (c) 2013 Cumulocity GmbH 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining 00010 * a copy of this software and associated documentation files (the 00011 * "Software"), to deal in the Software without restriction, including 00012 * without limitation the rights to use, copy, modify, merge, publish, 00013 * distribute, sublicense, and/or sell copies of the Software, and to 00014 * permit persons to whom the Software is furnished to do so, subject to 00015 * the following conditions: 00016 * 00017 * The above copyright notice and this permission notice shall be 00018 * included in all copies or substantial portions of the Software. 00019 * 00020 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00021 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00022 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00023 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00024 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00025 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00026 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00027 */ 00028 00029 #include <assert.h> 00030 #include <stdio.h> 00031 #include <ctype.h> 00032 #include "Parser.h" 00033 00034 #define STATE_BLANK 0 00035 #define STATE_STRUCTURE 1 00036 #define STATE_VALUE 2 00037 #define STATE_INQUOTES 3 00038 #define STATE_AFTERQUOTE 4 00039 #define STATE_COMPLETE 5 00040 #define STATE_ERROR 6 00041 00042 00043 /*-------------------------------------------------------------------------*/ 00044 Parser::Parser() 00045 { 00046 reset(); 00047 } 00048 /*-------------------------------------------------------------------------*/ 00049 uint8_t Parser::readFrom(AbstractDataSource& source, ParsedRecord& record) 00050 { 00051 reset(); 00052 record.clear(); 00053 00054 int status = -1; 00055 char read; 00056 while (_state < STATE_COMPLETE) { 00057 read = source.read(); 00058 status = source.status(); 00059 // if (isprint(read)) { 00060 // printf("%4c: %u\n", read, status); 00061 // } else { 00062 // printf("#%04x: %u\n", read, status); 00063 // } 00064 if (read > 0 || status == DS_STATUS_OK) 00065 parse(read); 00066 else 00067 break; 00068 } 00069 // printf("Parser: [E]while! %u, %d\r\n", _state, status); 00070 if (_state == STATE_COMPLETE) { // successfully read record 00071 if (!record.set(_buffer, _count)) 00072 return PARSER_INTERNAL_ERROR; 00073 else 00074 return PARSER_SUCCESS; 00075 } else if (_state == STATE_BLANK) { 00076 if (status == DS_STATUS_CLOSED) 00077 return PARSER_END_OF_RESPONSE; 00078 else if (status == DS_STATUS_TIMEOUT) 00079 return PARSER_TIMEOUT_ERROR; 00080 else 00081 return PARSER_INTERNAL_ERROR; 00082 } else { 00083 if (status == DS_STATUS_TIMEOUT) 00084 return PARSER_TIMEOUT_ERROR; 00085 else if (status == DS_STATUS_ERROR) 00086 return PARSER_INTERNAL_ERROR; 00087 else 00088 return PARSER_PARSE_ERROR; 00089 } 00090 } 00091 /*-------------------------------------------------------------------------*/ 00092 void Parser::parse(char c) 00093 { 00094 if (_ptr-_buffer >= SMARTREST_PARSER_BUFFER_SIZE) { 00095 _state = STATE_ERROR; 00096 return; 00097 } 00098 00099 switch (_state) 00100 { 00101 case STATE_BLANK: _state = STATE_STRUCTURE; 00102 case STATE_STRUCTURE: 00103 switch (c) 00104 { 00105 case ' ': 00106 case '\t': 00107 case '\r': break; 00108 case '"': _state = STATE_INQUOTES; break; 00109 case ',': close(); break; 00110 case '\0': 00111 case '\n': 00112 if (_count==0 && _length==0) { 00113 _state = STATE_BLANK; 00114 } else { 00115 close(); 00116 _state = STATE_COMPLETE; 00117 } 00118 break; 00119 default: 00120 if (_length > 0) { 00121 _state = STATE_ERROR; 00122 } else { 00123 _state = STATE_VALUE; 00124 parse(c); 00125 } 00126 break; 00127 } 00128 break; 00129 case STATE_VALUE: 00130 switch (c) 00131 { 00132 case ',': 00133 case '\n': _state = STATE_STRUCTURE; parse(c); break; 00134 case '"': _state = STATE_ERROR; break; 00135 default: 00136 if ((c == ' ') || (c == '\t') || (c == '\r')) 00137 _trailing++; 00138 else 00139 _trailing = 0; 00140 append(c); 00141 break; 00142 } 00143 break; 00144 case STATE_INQUOTES: 00145 switch (c) 00146 { 00147 case '"': _state = STATE_AFTERQUOTE; break; 00148 default: append(c); break; 00149 } 00150 break; 00151 case STATE_AFTERQUOTE: 00152 switch (c) 00153 { 00154 case '"': append(c); _state = STATE_INQUOTES; break; 00155 default: _state = STATE_STRUCTURE; parse(c); break; 00156 } 00157 break; 00158 } 00159 } 00160 /*-------------------------------------------------------------------------*/ 00161 void Parser::append(char c) 00162 { 00163 *_ptr++ = c; 00164 _length++; 00165 } 00166 /*-------------------------------------------------------------------------*/ 00167 void Parser::close() 00168 { 00169 _ptr -= _trailing; 00170 *_ptr++ = 0; 00171 _trailing = 0; 00172 _length = 0; 00173 _count++; 00174 } 00175 /*-------------------------------------------------------------------------*/ 00176 void Parser::reset() 00177 { 00178 _state = STATE_BLANK; 00179 _ptr = _buffer; 00180 _count = 0; 00181 _trailing = 0; 00182 _length = 0; 00183 } 00184 /*-------------------------------------------------------------------------*/
Generated on Tue Jul 12 2022 17:00:00 by 1.7.2