Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(812)

Side by Side Diff: runtime/vm/json.cc

Issue 10357003: Beginnings of a debugger wire protocol (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/json.h ('k') | runtime/vm/json_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/json.h"
6
7 #include "platform/assert.h"
8 #include "platform/utils.h"
9 #include "vm/os.h"
10
11 namespace dart {
12
13
14 JSONScanner::JSONScanner(const char* json_text) {
15 SetText(json_text);
16 }
17
18
19 void JSONScanner::SetText(const char* json_text) {
20 current_pos_ = json_text;
21 token_start_ = json_text;
22 token_length_ = 0;
23 token_ = TokenIllegal;
24 }
25
26
27 void JSONScanner::Recognize(Token t) {
28 ++current_pos_;
29 token_ = t;
30 }
31
32
33 bool JSONScanner::IsLetter(char ch) const {
34 return (('A' <= ch) && (ch <= 'Z')) || (('a' <= ch) && (ch <= 'z'));
35 }
36
37
38 bool JSONScanner::IsDigit(char ch) const {
39 return ('0' <= ch) && (ch <= '9');
40 }
41
42
43 bool JSONScanner::IsLiteral(const char* literal) {
44 int i = 0;
45 while ((literal[i] != '\0') && (current_pos_[i] == literal[i])) {
46 i++;
47 }
48 if ((literal[i] == '\0') && !IsLetter(current_pos_[i])) {
49 current_pos_ += i;
50 return true;
51 }
52 return false;
53 }
54
55
56 bool JSONScanner::IsStringLiteral(const char* literal) const {
57 if (token_ != TokenString) {
58 return false;
59 }
60 int i = 0;
61 while ((i < token_length_) && (token_start_[i] == literal[i])) {
62 i++;
63 }
64 return (i == token_length_) && (literal[i] == '\0');
65 }
66
67
68 void JSONScanner::Skip(Token matching_token) {
69 while (!EOM() && (token_ != TokenIllegal)) {
70 Scan();
71 if (token_ == TokenLBrace) {
72 Skip(TokenRBrace);
73 } else if (token_ == TokenLBrack) {
74 Skip(TokenRBrack);
75 } else if (token_ == matching_token) {
76 return;
77 } else if ((token_ == TokenRBrace) || (token_ == TokenRBrack)) {
78 // Mismatched brace or bracket.
79 token_ = TokenIllegal;
80 }
81 }
82 }
83
84
85 void JSONScanner::ScanString() {
86 ASSERT(*current_pos_ == '"');
87 ++current_pos_;
88 token_start_ = current_pos_;
89 while (*current_pos_ != '"') {
90 if (*current_pos_ == '\0') {
91 token_length_ = 0;
92 token_ = TokenIllegal;
93 return;
94 } else if (*current_pos_ == '\\') {
95 // TODO(hausner): Implement escape sequence.
96 UNIMPLEMENTED();
97 } else if (*current_pos_ < 0) {
98 // UTF-8 not supported.
99 token_length_ = 0;
100 token_ = TokenIllegal;
101 return;
102 } else {
103 ++current_pos_;
104 }
105 }
106 token_ = TokenString;
107 token_length_ = current_pos_ - token_start_;
108 ++current_pos_;
109 }
110
111
112 void JSONScanner::ScanNumber() {
113 if (*current_pos_ == '-') {
114 ++current_pos_;
115 }
116 if (!IsDigit(*current_pos_)) {
117 token_ = TokenIllegal;
118 token_length_ = 0;
119 return;
120 }
121 while (IsDigit(*current_pos_)) {
122 ++current_pos_;
123 }
124 if ((*current_pos_ == '.') ||
125 (*current_pos_ == 'e') ||
126 (*current_pos_ == 'E')) {
127 // Floating point numbers not supported.
128 token_ = TokenIllegal;
129 token_length_ = 0;
130 return;
131 }
132 token_ = TokenInteger;
133 token_length_ = current_pos_ - token_start_;
134 }
135
136
137 void JSONScanner::Scan() {
138 while ((*current_pos_ == ' ') ||
139 (*current_pos_ == '\t') ||
140 (*current_pos_ == '\n')) {
141 ++current_pos_;
142 }
143 token_start_ = current_pos_;
144 if (*current_pos_ == '\0') {
145 token_length_ = 0;
146 token_ = TokenEOM;
147 return;
148 }
149 switch (*current_pos_) {
150 case '{':
151 Recognize(TokenLBrace);
152 break;
153 case '}':
154 Recognize(TokenRBrace);
155 break;
156 case '[':
157 Recognize(TokenLBrack);
158 break;
159 case ']':
160 Recognize(TokenRBrack);
161 break;
162 case ':':
163 Recognize(TokenColon);
164 break;
165 case ',':
166 Recognize(TokenComma);
167 break;
168 case '"':
169 ScanString();
170 break;
171 case '0':
172 case '1':
173 case '2':
174 case '3':
175 case '4':
176 case '5':
177 case '6':
178 case '7':
179 case '8':
180 case '9':
181 case '-':
182 ScanNumber();
183 break;
184 default:
185 if (IsLiteral("true")) {
186 token_ = TokenTrue;
187 token_length_ = 4;
188 } else if (IsLiteral("false")) {
189 token_ = TokenFalse;
190 token_length_ = 5;
191 } else if (IsLiteral("null")) {
192 token_ = TokenNull;
193 token_length_ = 4;
194 } else {
195 token_length_ = 0;
196 token_ = TokenIllegal;
197 }
198 }
199 }
200
201
202 JSONReader::JSONReader(const char* json_object)
203 : scanner_(json_object) {
204 Set(json_object);
205 }
206
207 void JSONReader::Set(const char* json_object) {
208 scanner_.SetText(json_object);
209 json_object_ = json_object;
210 error_ = false;
211 }
212
213
214 bool JSONReader::Seek(const char* name) {
215 scanner_.SetText(json_object_);
216 scanner_.Scan();
217 if (scanner_.CurrentToken() != JSONScanner::TokenLBrace) {
218 error_ = true;
219 return false;
220 }
221 scanner_.Scan();
222 while (scanner_.CurrentToken() == JSONScanner::TokenString) {
223 bool found = scanner_.IsStringLiteral(name);
224 scanner_.Scan();
225 if (scanner_.CurrentToken() != JSONScanner::TokenColon) {
226 error_ = true;
227 return false;
228 }
229 scanner_.Scan();
230 switch (scanner_.CurrentToken()) {
231 case JSONScanner::TokenString:
232 case JSONScanner::TokenInteger:
233 case JSONScanner::TokenLBrace:
234 case JSONScanner::TokenLBrack:
235 case JSONScanner::TokenTrue:
236 case JSONScanner::TokenFalse:
237 case JSONScanner::TokenNull:
238 // Found a legal value.
239 if (found) {
240 return true;
241 }
242 break;
243 default:
244 error_ = true;
245 return false;
246 }
247 // Skip the value.
248 if (scanner_.CurrentToken() == JSONScanner::TokenLBrace) {
249 scanner_.Skip(JSONScanner::TokenRBrace);
250 if (scanner_.CurrentToken() != JSONScanner::TokenRBrace) {
251 error_ = true;
252 return false;
253 }
254 } else if (scanner_.CurrentToken() == JSONScanner::TokenLBrack) {
255 scanner_.Skip(JSONScanner::TokenRBrack);
256 if (scanner_.CurrentToken() != JSONScanner::TokenRBrack) {
257 error_ = true;
258 return false;
259 }
260 }
261 scanner_.Scan(); // Value or closing brace or bracket.
262 if (scanner_.CurrentToken() == JSONScanner::TokenComma) {
263 scanner_.Scan();
264 } else {
265 // End of json object or malformed object. Value not found.
266 error_ = true;
267 break;
268 }
269 }
270 return false;
271 }
272
273
274 JSONReader::JSONType JSONReader::Type() const {
275 if (error_) {
276 return kNone;
277 }
278 switch (scanner_.CurrentToken()) {
279 case JSONScanner::TokenString:
280 return kString;
281 case JSONScanner::TokenInteger:
282 return kInteger;
283 case JSONScanner::TokenLBrace:
284 return kObject;
285 case JSONScanner::TokenLBrack:
286 return kArray;
287 case JSONScanner::TokenTrue:
288 case JSONScanner::TokenFalse:
289 case JSONScanner::TokenNull:
290 return kLiteral;
291 default:
292 return kNone;
293 }
294 }
295
296
297 TextBuffer::TextBuffer(intptr_t buf_size) {
298 ASSERT(buf_size > 0);
299 buf_ = reinterpret_cast<char*>(malloc(buf_size));
300 buf_size_ = buf_size;
301 Clear();
302 }
303
304
305 TextBuffer::~TextBuffer() {
306 free(buf_);
307 buf_ = NULL;
308 }
309
310
311 void TextBuffer::Clear() {
312 msg_len_ = 0;
313 buf_[0] = '\0';
314 }
315
316
317 intptr_t TextBuffer::Printf(const char* format, ...) {
318 va_list args;
319 va_start(args, format);
320 intptr_t remaining = buf_size_ - msg_len_;
321 ASSERT(remaining >= 0);
322 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args);
323 va_end(args);
324 if (len >= remaining) {
325 const int kBufferSpareCapacity = 64; // Somewhat arbitrary.
326 GrowBuffer(len + kBufferSpareCapacity);
327 remaining = buf_size_ - msg_len_;
328 ASSERT(remaining > len);
329 va_list args2;
330 va_start(args2, format);
331 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2);
332 va_end(args2);
333 ASSERT(len == len2);
334 }
335 msg_len_ += len;
336 buf_[msg_len_] = '\0';
337 return len;
338 }
339
340
341 void TextBuffer::GrowBuffer(intptr_t len) {
342 intptr_t new_size = buf_size_ + len;
343 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
344 ASSERT(new_buf != NULL);
345 buf_ = new_buf;
346 buf_size_ = new_size;
347 }
348
349 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/json.h ('k') | runtime/vm/json_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698