Generic SmartRest library

Dependents:   SmartRestUnitTest MbedSmartRest MbedSmartRestStreaming

Committer:
vwochnik
Date:
Wed Apr 16 08:30:49 2014 +0000
Revision:
1:3e7b4c9e0821
Parent:
0:744801d5734d
fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vwochnik 0:744801d5734d 1 /*
vwochnik 0:744801d5734d 2 * Parser.cpp
vwochnik 0:744801d5734d 3 *
vwochnik 0:744801d5734d 4 * Created on: Nov 1, 2013
vwochnik 0:744801d5734d 5 * * Authors: Vincent Wochnik <v.wochnik@gmail.com>
vwochnik 0:744801d5734d 6 *
vwochnik 0:744801d5734d 7 * Copyright (c) 2013 Cumulocity GmbH
vwochnik 0:744801d5734d 8 *
vwochnik 0:744801d5734d 9 * Permission is hereby granted, free of charge, to any person obtaining
vwochnik 0:744801d5734d 10 * a copy of this software and associated documentation files (the
vwochnik 0:744801d5734d 11 * "Software"), to deal in the Software without restriction, including
vwochnik 0:744801d5734d 12 * without limitation the rights to use, copy, modify, merge, publish,
vwochnik 0:744801d5734d 13 * distribute, sublicense, and/or sell copies of the Software, and to
vwochnik 0:744801d5734d 14 * permit persons to whom the Software is furnished to do so, subject to
vwochnik 0:744801d5734d 15 * the following conditions:
vwochnik 0:744801d5734d 16 *
vwochnik 0:744801d5734d 17 * The above copyright notice and this permission notice shall be
vwochnik 0:744801d5734d 18 * included in all copies or substantial portions of the Software.
vwochnik 0:744801d5734d 19 *
vwochnik 0:744801d5734d 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
vwochnik 0:744801d5734d 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
vwochnik 0:744801d5734d 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
vwochnik 0:744801d5734d 23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
vwochnik 0:744801d5734d 24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
vwochnik 0:744801d5734d 25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
vwochnik 0:744801d5734d 26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vwochnik 0:744801d5734d 27 */
vwochnik 0:744801d5734d 28
vwochnik 0:744801d5734d 29 #include "Parser.h"
vwochnik 0:744801d5734d 30
vwochnik 0:744801d5734d 31 #define STATE_BLANK 0
vwochnik 0:744801d5734d 32 #define STATE_STRUCTURE 1
vwochnik 0:744801d5734d 33 #define STATE_VALUE 2
vwochnik 0:744801d5734d 34 #define STATE_INQUOTES 3
vwochnik 0:744801d5734d 35 #define STATE_AFTERQUOTE 4
vwochnik 0:744801d5734d 36 #define STATE_COMPLETE 5
vwochnik 0:744801d5734d 37 #define STATE_ERROR 6
vwochnik 0:744801d5734d 38
vwochnik 0:744801d5734d 39 Parser::Parser()
vwochnik 0:744801d5734d 40 {
vwochnik 0:744801d5734d 41 reset();
vwochnik 0:744801d5734d 42 }
vwochnik 0:744801d5734d 43
vwochnik 0:744801d5734d 44 uint8_t Parser::readFrom(AbstractDataSource& source, ParsedRecord& record)
vwochnik 0:744801d5734d 45 {
vwochnik 0:744801d5734d 46 uint8_t status; char read;
vwochnik 0:744801d5734d 47
vwochnik 0:744801d5734d 48 reset();
vwochnik 0:744801d5734d 49 record.set(NULL, 0);
vwochnik 0:744801d5734d 50
vwochnik 0:744801d5734d 51 while ((_state < STATE_COMPLETE) &&
vwochnik 0:744801d5734d 52 (((read = source.read()) > 0 ) ||
vwochnik 0:744801d5734d 53 ((status = source.status()) == DS_STATUS_OK)))
vwochnik 0:744801d5734d 54 parse(read);
vwochnik 0:744801d5734d 55
vwochnik 0:744801d5734d 56 if (_state == STATE_COMPLETE)
vwochnik 0:744801d5734d 57 record.set(_buffer, _count);
vwochnik 0:744801d5734d 58
vwochnik 0:744801d5734d 59 if (_state == STATE_COMPLETE)
vwochnik 0:744801d5734d 60 return PARSER_SUCCESS;
vwochnik 0:744801d5734d 61 else if (_state == STATE_BLANK)
vwochnik 0:744801d5734d 62 if (status == DS_STATUS_CLOSED)
vwochnik 0:744801d5734d 63 return PARSER_END_OF_RESPONSE;
vwochnik 0:744801d5734d 64 else
vwochnik 0:744801d5734d 65 return PARSER_TIMEOUT_ERROR;
vwochnik 0:744801d5734d 66 else
vwochnik 0:744801d5734d 67 if (status == DS_STATUS_TIMEOUT)
vwochnik 0:744801d5734d 68 return PARSER_TIMEOUT_ERROR;
vwochnik 0:744801d5734d 69 else
vwochnik 0:744801d5734d 70 return PARSER_PARSE_ERROR;
vwochnik 0:744801d5734d 71 }
vwochnik 0:744801d5734d 72
vwochnik 0:744801d5734d 73 void Parser::parse(char c)
vwochnik 0:744801d5734d 74 {
vwochnik 0:744801d5734d 75 if (_ptr-_buffer >= PARSER_BUFFER_SIZE) {
vwochnik 0:744801d5734d 76 _state = STATE_ERROR;
vwochnik 0:744801d5734d 77 return;
vwochnik 0:744801d5734d 78 }
vwochnik 0:744801d5734d 79
vwochnik 0:744801d5734d 80 switch (_state) {
vwochnik 0:744801d5734d 81 case STATE_BLANK:
vwochnik 0:744801d5734d 82 _state = STATE_STRUCTURE;
vwochnik 0:744801d5734d 83 case STATE_STRUCTURE:
vwochnik 0:744801d5734d 84 switch (c) {
vwochnik 0:744801d5734d 85 case ' ':
vwochnik 0:744801d5734d 86 case '\t':
vwochnik 0:744801d5734d 87 case '\r':
vwochnik 0:744801d5734d 88 break;
vwochnik 0:744801d5734d 89 case '"':
vwochnik 0:744801d5734d 90 _state = STATE_INQUOTES;
vwochnik 0:744801d5734d 91 break;
vwochnik 0:744801d5734d 92 case ',':
vwochnik 0:744801d5734d 93 close();
vwochnik 0:744801d5734d 94 break;
vwochnik 0:744801d5734d 95 case '\0':
vwochnik 0:744801d5734d 96 case '\n':
vwochnik 0:744801d5734d 97 if ((_count == 0) && (_length == 0)) {
vwochnik 0:744801d5734d 98 _state = STATE_BLANK;
vwochnik 0:744801d5734d 99 } else {
vwochnik 0:744801d5734d 100 close();
vwochnik 0:744801d5734d 101 _state = STATE_COMPLETE;
vwochnik 0:744801d5734d 102 }
vwochnik 0:744801d5734d 103 break;
vwochnik 0:744801d5734d 104 default:
vwochnik 0:744801d5734d 105 if (_length > 0) {
vwochnik 0:744801d5734d 106 _state = STATE_ERROR;
vwochnik 0:744801d5734d 107 } else {
vwochnik 0:744801d5734d 108 _state = STATE_VALUE;
vwochnik 0:744801d5734d 109 parse(c);
vwochnik 0:744801d5734d 110 }
vwochnik 0:744801d5734d 111 break;
vwochnik 0:744801d5734d 112 }
vwochnik 0:744801d5734d 113 break;
vwochnik 0:744801d5734d 114 case STATE_VALUE:
vwochnik 0:744801d5734d 115 switch (c) {
vwochnik 0:744801d5734d 116 case ',':
vwochnik 0:744801d5734d 117 case '\n':
vwochnik 0:744801d5734d 118 _state = STATE_STRUCTURE;
vwochnik 0:744801d5734d 119 parse(c);
vwochnik 0:744801d5734d 120 break;
vwochnik 0:744801d5734d 121 case '"':
vwochnik 0:744801d5734d 122 _state = STATE_ERROR;
vwochnik 0:744801d5734d 123 break;
vwochnik 0:744801d5734d 124 default:
vwochnik 0:744801d5734d 125 if ((c == ' ') || (c == '\t') || (c == '\r'))
vwochnik 0:744801d5734d 126 _trailing++;
vwochnik 0:744801d5734d 127 else
vwochnik 0:744801d5734d 128 _trailing = 0;
vwochnik 0:744801d5734d 129 append(c);
vwochnik 0:744801d5734d 130 break;
vwochnik 0:744801d5734d 131 }
vwochnik 0:744801d5734d 132 break;
vwochnik 0:744801d5734d 133 case STATE_INQUOTES:
vwochnik 0:744801d5734d 134 switch (c) {
vwochnik 0:744801d5734d 135 case '"':
vwochnik 0:744801d5734d 136 _state = STATE_AFTERQUOTE;
vwochnik 0:744801d5734d 137 break;
vwochnik 0:744801d5734d 138 default:
vwochnik 0:744801d5734d 139 append(c);
vwochnik 0:744801d5734d 140 break;
vwochnik 0:744801d5734d 141 }
vwochnik 0:744801d5734d 142 break;
vwochnik 0:744801d5734d 143 case STATE_AFTERQUOTE:
vwochnik 0:744801d5734d 144 switch (c) {
vwochnik 0:744801d5734d 145 case '"':
vwochnik 0:744801d5734d 146 append(c);
vwochnik 0:744801d5734d 147 _state = STATE_INQUOTES;
vwochnik 0:744801d5734d 148 break;
vwochnik 0:744801d5734d 149 default:
vwochnik 0:744801d5734d 150 _state = STATE_STRUCTURE;
vwochnik 0:744801d5734d 151 parse(c);
vwochnik 0:744801d5734d 152 break;
vwochnik 0:744801d5734d 153 }
vwochnik 0:744801d5734d 154 break;
vwochnik 0:744801d5734d 155 }
vwochnik 0:744801d5734d 156 }
vwochnik 0:744801d5734d 157
vwochnik 0:744801d5734d 158 void Parser::append(char c)
vwochnik 0:744801d5734d 159 {
vwochnik 0:744801d5734d 160 *_ptr++ = c;
vwochnik 0:744801d5734d 161 _length++;
vwochnik 0:744801d5734d 162 }
vwochnik 0:744801d5734d 163
vwochnik 0:744801d5734d 164 void Parser::close()
vwochnik 0:744801d5734d 165 {
vwochnik 0:744801d5734d 166 _ptr -= _trailing;
vwochnik 0:744801d5734d 167 *_ptr++ = 0;
vwochnik 0:744801d5734d 168 _trailing = 0;
vwochnik 0:744801d5734d 169 _length = 0;
vwochnik 0:744801d5734d 170 _count++;
vwochnik 0:744801d5734d 171 }
vwochnik 0:744801d5734d 172
vwochnik 0:744801d5734d 173 void Parser::reset()
vwochnik 0:744801d5734d 174 {
vwochnik 0:744801d5734d 175 _state = STATE_BLANK;
vwochnik 0:744801d5734d 176 _ptr = _buffer;
vwochnik 0:744801d5734d 177 _count = 0;
vwochnik 0:744801d5734d 178 _trailing = 0;
vwochnik 0:744801d5734d 179 _length = 0;
vwochnik 0:744801d5734d 180 }