source: rtos_arduino/trunk/arduino_lib/libraries/ArduinoJson/src/Internals/JsonParser.cpp@ 209

Last change on this file since 209 was 209, checked in by ertl-honda, 8 years ago

BlueMix用のフィアルを追加

File size: 4.6 KB
Line 
1// Copyright Benoit Blanchon 2014-2016
2// MIT License
3//
4// Arduino JSON library
5// https://github.com/bblanchon/ArduinoJson
6// If you like this project, please add a star!
7
8#include "../../include/ArduinoJson/Internals/JsonParser.hpp"
9
10#include "../../include/ArduinoJson/Internals/Comments.hpp"
11#include "../../include/ArduinoJson/Internals/Encoding.hpp"
12#include "../../include/ArduinoJson/JsonArray.hpp"
13#include "../../include/ArduinoJson/JsonBuffer.hpp"
14#include "../../include/ArduinoJson/JsonObject.hpp"
15
16using namespace ArduinoJson;
17using namespace ArduinoJson::Internals;
18
19bool JsonParser::skip(char charToSkip) {
20 const char *ptr = skipSpacesAndComments(_readPtr);
21 if (*ptr != charToSkip) return false;
22 ptr++;
23 _readPtr = skipSpacesAndComments(ptr);
24 return true;
25}
26
27bool JsonParser::parseAnythingTo(JsonVariant *destination) {
28 if (_nestingLimit == 0) return false;
29 _nestingLimit--;
30 bool success = parseAnythingToUnsafe(destination);
31 _nestingLimit++;
32 return success;
33}
34
35inline bool JsonParser::parseAnythingToUnsafe(JsonVariant *destination) {
36 _readPtr = skipSpacesAndComments(_readPtr);
37
38 switch (*_readPtr) {
39 case '[':
40 return parseArrayTo(destination);
41
42 case '{':
43 return parseObjectTo(destination);
44
45 default:
46 return parseStringTo(destination);
47 }
48}
49
50JsonArray &JsonParser::parseArray() {
51 // Create an empty array
52 JsonArray &array = _buffer->createArray();
53
54 // Check opening braket
55 if (!skip('[')) goto ERROR_MISSING_BRACKET;
56 if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
57
58 // Read each value
59 for (;;) {
60 // 1 - Parse value
61 JsonVariant value;
62 if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
63 if (!array.add(value)) goto ERROR_NO_MEMORY;
64
65 // 2 - More values?
66 if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
67 if (!skip(',')) goto ERROR_MISSING_COMMA;
68 }
69
70SUCCESS_EMPTY_ARRAY:
71SUCCES_NON_EMPTY_ARRAY:
72 return array;
73
74ERROR_INVALID_VALUE:
75ERROR_MISSING_BRACKET:
76ERROR_MISSING_COMMA:
77ERROR_NO_MEMORY:
78 return JsonArray::invalid();
79}
80
81bool JsonParser::parseArrayTo(JsonVariant *destination) {
82 JsonArray &array = parseArray();
83 if (!array.success()) return false;
84
85 *destination = array;
86 return true;
87}
88
89JsonObject &JsonParser::parseObject() {
90 // Create an empty object
91 JsonObject &object = _buffer->createObject();
92
93 // Check opening brace
94 if (!skip('{')) goto ERROR_MISSING_BRACE;
95 if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
96
97 // Read each key value pair
98 for (;;) {
99 // 1 - Parse key
100 const char *key = parseString();
101 if (!key) goto ERROR_INVALID_KEY;
102 if (!skip(':')) goto ERROR_MISSING_COLON;
103
104 // 2 - Parse value
105 JsonVariant value;
106 if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
107 if (!object.set(key, value)) goto ERROR_NO_MEMORY;
108
109 // 3 - More keys/values?
110 if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
111 if (!skip(',')) goto ERROR_MISSING_COMMA;
112 }
113
114SUCCESS_EMPTY_OBJECT:
115SUCCESS_NON_EMPTY_OBJECT:
116 return object;
117
118ERROR_INVALID_KEY:
119ERROR_INVALID_VALUE:
120ERROR_MISSING_BRACE:
121ERROR_MISSING_COLON:
122ERROR_MISSING_COMMA:
123ERROR_NO_MEMORY:
124 return JsonObject::invalid();
125}
126
127bool JsonParser::parseObjectTo(JsonVariant *destination) {
128 JsonObject &object = parseObject();
129 if (!object.success()) return false;
130
131 *destination = object;
132 return true;
133}
134
135static inline bool isInRange(char c, char min, char max) {
136 return min <= c && c <= max;
137}
138
139static inline bool isLetterOrNumber(char c) {
140 return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
141 isInRange(c, 'A', 'Z') || c == '-' || c == '.';
142}
143
144static inline bool isQuote(char c) { return c == '\'' || c == '\"'; }
145
146const char *JsonParser::parseString() {
147 const char *readPtr = _readPtr;
148 char *writePtr = _writePtr;
149
150 char c = *readPtr;
151
152 if (isQuote(c)) { // quotes
153 char stopChar = c;
154 for (;;) {
155 c = *++readPtr;
156 if (c == '\0') break;
157
158 if (c == stopChar) {
159 readPtr++;
160 break;
161 }
162
163 if (c == '\\') {
164 // replace char
165 c = Encoding::unescapeChar(*++readPtr);
166 if (c == '\0') break;
167 }
168
169 *writePtr++ = c;
170 }
171 } else { // no quotes
172 for (;;) {
173 if (!isLetterOrNumber(c)) break;
174 *writePtr++ = c;
175 c = *++readPtr;
176 }
177 }
178 // end the string here
179 *writePtr++ = '\0';
180
181 const char *startPtr = _writePtr;
182
183 // update end ptr
184 _readPtr = readPtr;
185 _writePtr = writePtr;
186
187 // return pointer to unquoted string
188 return startPtr;
189}
190
191bool JsonParser::parseStringTo(JsonVariant *destination) {
192 bool hasQuotes = isQuote(_readPtr[0]);
193 const char *value = parseString();
194 if (value == NULL) return false;
195 if (hasQuotes) {
196 *destination = value;
197 } else {
198 *destination = Unparsed(value);
199 }
200 return true;
201}
Note: See TracBrowser for help on using the repository browser.