A client for the SmartREST protocol from Cumulocity.
Dependencies: HTTPClient SmartRest
Diff: SmartRest/Parser.cpp
- Revision:
- 11:844856ab160d
- Parent:
- 10:478414cc15a4
- Child:
- 12:788dd934f283
--- a/SmartRest/Parser.cpp Wed Feb 05 16:21:46 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Parser.cpp - * - * Created on: Nov 1, 2013 - * * Authors: Vincent Wochnik <v.wochnik@gmail.com> - * - * Copyright (c) 2013 Cumulocity GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "Parser.h" - -#define STATE_BLANK 0 -#define STATE_STRUCTURE 1 -#define STATE_VALUE 2 -#define STATE_INQUOTES 3 -#define STATE_AFTERQUOTE 4 -#define STATE_COMPLETE 5 -#define STATE_ERROR 6 - -Parser::Parser() -{ - reset(); -} - -uint8_t Parser::readFrom(AbstractDataSource& source, ParsedRecord& record) -{ - uint8_t status; char read; - - reset(); - record.set(NULL, 0); - - while ((_state < STATE_COMPLETE) && - (((read = source.read()) > 0 ) || - ((status = source.status()) == DS_STATUS_OK))) - parse(read); - - if (_state == STATE_COMPLETE) - record.set(_buffer, _count); - - if (_state == STATE_COMPLETE) - return PARSER_SUCCESS; - else if (_state == STATE_BLANK) - if (status == DS_STATUS_CLOSED) - return PARSER_END_OF_RESPONSE; - else - return PARSER_TIMEOUT_ERROR; - else - if (status == DS_STATUS_TIMEOUT) - return PARSER_TIMEOUT_ERROR; - else - return PARSER_PARSE_ERROR; -} - -void Parser::parse(char c) -{ - if (_ptr-_buffer >= PARSER_BUFFER_SIZE) { - _state = STATE_ERROR; - return; - } - - switch (_state) { - case STATE_BLANK: - _state = STATE_STRUCTURE; - case STATE_STRUCTURE: - switch (c) { - case ' ': - case '\t': - case '\r': - break; - case '"': - _state = STATE_INQUOTES; - break; - case ',': - close(); - break; - case '\0': - case '\n': - if ((_count == 0) && (_length == 0)) { - _state = STATE_BLANK; - } else { - close(); - _state = STATE_COMPLETE; - } - break; - default: - if (_length > 0) { - _state = STATE_ERROR; - } else { - _state = STATE_VALUE; - parse(c); - } - break; - } - break; - case STATE_VALUE: - switch (c) { - case ',': - case '\n': - _state = STATE_STRUCTURE; - parse(c); - break; - case '"': - _state = STATE_ERROR; - break; - default: - if ((c == ' ') || (c == '\t') || (c == '\r')) - _trailing++; - else - _trailing = 0; - append(c); - break; - } - break; - case STATE_INQUOTES: - switch (c) { - case '"': - _state = STATE_AFTERQUOTE; - break; - default: - append(c); - break; - } - break; - case STATE_AFTERQUOTE: - switch (c) { - case '"': - append(c); - _state = STATE_INQUOTES; - break; - default: - _state = STATE_STRUCTURE; - parse(c); - break; - } - break; - } -} - -void Parser::append(char c) -{ - *_ptr++ = c; - _length++; -} - -void Parser::close() -{ - _ptr -= _trailing; - *_ptr++ = 0; - _trailing = 0; - _length = 0; - _count++; -} - -void Parser::reset() -{ - _state = STATE_BLANK; - _ptr = _buffer; - _count = 0; - _trailing = 0; - _length = 0; -}