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

Side by Side Diff: runtime/platform/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/platform/json.h ('k') | runtime/platform/platform_headers.gypi » ('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 "platform/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 error_ = false;
216 scanner_.SetText(json_object_);
217 scanner_.Scan();
218 if (scanner_.CurrentToken() != JSONScanner::TokenLBrace) {
219 error_ = true;
220 return false;
221 }
222 scanner_.Scan();
223 if (scanner_.CurrentToken() == JSONScanner::TokenRBrace) {
224 return false;
225 }
226 while (scanner_.CurrentToken() == JSONScanner::TokenString) {
227 bool found = scanner_.IsStringLiteral(name);
228 scanner_.Scan();
229 if (scanner_.CurrentToken() != JSONScanner::TokenColon) {
230 error_ = true;
231 return false;
232 }
233 scanner_.Scan();
234 switch (scanner_.CurrentToken()) {
235 case JSONScanner::TokenString:
236 case JSONScanner::TokenInteger:
237 case JSONScanner::TokenLBrace:
238 case JSONScanner::TokenLBrack:
239 case JSONScanner::TokenTrue:
240 case JSONScanner::TokenFalse:
241 case JSONScanner::TokenNull:
242 // Found a legal value.
243 if (found) {
244 return true;
245 }
246 break;
247 default:
248 error_ = true;
249 return false;
250 }
251 // Skip the value.
252 if (scanner_.CurrentToken() == JSONScanner::TokenLBrace) {
253 scanner_.Skip(JSONScanner::TokenRBrace);
254 if (scanner_.CurrentToken() != JSONScanner::TokenRBrace) {
255 error_ = true;
256 return false;
257 }
258 } else if (scanner_.CurrentToken() == JSONScanner::TokenLBrack) {
259 scanner_.Skip(JSONScanner::TokenRBrack);
260 if (scanner_.CurrentToken() != JSONScanner::TokenRBrack) {
261 error_ = true;
262 return false;
263 }
264 }
265 scanner_.Scan(); // Value or closing brace or bracket.
266 if (scanner_.CurrentToken() == JSONScanner::TokenComma) {
267 scanner_.Scan();
268 } else if (scanner_.CurrentToken() == JSONScanner::TokenRBrace) {
269 return false;
270 } else {
271 error_ = true;
272 return false;
273 }
274 }
275 error_ = true;
276 return false;
277 }
278
279
280 const char* JSONReader::EndOfObject() {
281 bool found = Seek("***"); // Look for illegally named value.
282 ASSERT(!found);
283 if (!found && !error_) {
284 const char* s = scanner_.TokenChars();
285 ASSERT(*s == '}');
286 return s;
287 }
288 return NULL;
289 }
290
291
292 JSONReader::JSONType JSONReader::Type() const {
293 if (error_) {
294 return kNone;
295 }
296 switch (scanner_.CurrentToken()) {
297 case JSONScanner::TokenString:
298 return kString;
299 case JSONScanner::TokenInteger:
300 return kInteger;
301 case JSONScanner::TokenLBrace:
302 return kObject;
303 case JSONScanner::TokenLBrack:
304 return kArray;
305 case JSONScanner::TokenTrue:
306 case JSONScanner::TokenFalse:
307 case JSONScanner::TokenNull:
308 return kLiteral;
309 default:
310 return kNone;
311 }
312 }
313
314
315 TextBuffer::TextBuffer(intptr_t buf_size) {
316 ASSERT(buf_size > 0);
317 buf_ = reinterpret_cast<char*>(malloc(buf_size));
318 buf_size_ = buf_size;
319 Clear();
320 }
321
322
323 TextBuffer::~TextBuffer() {
324 free(buf_);
325 buf_ = NULL;
326 }
327
328
329 void TextBuffer::Clear() {
330 msg_len_ = 0;
331 buf_[0] = '\0';
332 }
333
334
335 intptr_t TextBuffer::Printf(const char* format, ...) {
336 va_list args;
337 va_start(args, format);
338 intptr_t remaining = buf_size_ - msg_len_;
339 ASSERT(remaining >= 0);
340 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args);
341 va_end(args);
342 if (len >= remaining) {
343 const int kBufferSpareCapacity = 64; // Somewhat arbitrary.
344 GrowBuffer(len + kBufferSpareCapacity);
345 remaining = buf_size_ - msg_len_;
346 ASSERT(remaining > len);
347 va_list args2;
348 va_start(args2, format);
349 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2);
350 va_end(args2);
351 ASSERT(len == len2);
352 }
353 msg_len_ += len;
354 buf_[msg_len_] = '\0';
355 return len;
356 }
357
358
359 void TextBuffer::GrowBuffer(intptr_t len) {
360 intptr_t new_size = buf_size_ + len;
361 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
362 ASSERT(new_buf != NULL);
363 buf_ = new_buf;
364 buf_size_ = new_size;
365 }
366
367 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/platform/json.h ('k') | runtime/platform/platform_headers.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698