Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
json_writer.cc
Go to the documentation of this file.
1// Copyright (c) 2017, 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/assert.h"
6
7#include "platform/unicode.h"
9#include "vm/json_writer.h"
10#include "vm/object.h"
11
12namespace dart {
13
15 public:
16 explicit MaybeOnStackBuffer(intptr_t size) {
17 if (size > kOnStackBufferCapacity) {
18 p_ = reinterpret_cast<char*>(malloc(size));
19 } else {
20 p_ = &buffer_[0];
21 }
22 }
24 if (p_ != &buffer_[0]) free(p_);
25 }
26
27 char* p() { return p_; }
28
29 private:
30 static constexpr intptr_t kOnStackBufferCapacity = 4096;
31 char* p_;
32 char buffer_[kOnStackBufferCapacity];
33};
34
35JSONWriter::JSONWriter(intptr_t buf_size)
36 : open_objects_(0), buffer_(buf_size) {}
37
38void JSONWriter::AppendBytes(const uint8_t* buffer, intptr_t buffer_length) {
39 buffer_.AddRaw(buffer, buffer_length);
40}
41
42static const char base64_digits[65] =
43 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
44static const char base64_pad = '=';
45
46void JSONWriter::AppendBytesInBase64(const uint8_t* bytes, intptr_t length) {
47 ASSERT(bytes != nullptr);
48 intptr_t odd_bits = length % 3;
49 intptr_t even_bits = length - odd_bits;
50 for (intptr_t i = 0; i < even_bits; i += 3) {
51 intptr_t triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
52 buffer_.AddChar(base64_digits[triplet >> 18]);
53 buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
54 buffer_.AddChar(base64_digits[(triplet >> 6) & 63]);
55 buffer_.AddChar(base64_digits[triplet & 63]);
56 }
57 if (odd_bits == 1) {
58 intptr_t triplet = bytes[even_bits] << 16;
59 buffer_.AddChar(base64_digits[triplet >> 18]);
60 buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
61 buffer_.AddChar(base64_pad);
62 buffer_.AddChar(base64_pad);
63 } else if (odd_bits == 2) {
64 intptr_t triplet = (bytes[even_bits] << 16) | (bytes[even_bits + 1] << 8);
65 buffer_.AddChar(base64_digits[triplet >> 18]);
66 buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
67 buffer_.AddChar(base64_digits[(triplet >> 6) & 63]);
68 buffer_.AddChar(base64_pad);
69 }
70}
71
72void JSONWriter::AppendSerializedObject(const char* serialized_object) {
74 buffer_.AddString(serialized_object);
75}
76
77void JSONWriter::AppendSerializedObject(const char* property_name,
78 const char* serialized_object) {
80 PrintPropertyName(property_name);
81 buffer_.AddString(serialized_object);
82}
83
85 buffer_.Clear();
86 open_objects_ = 0;
87}
88
89void JSONWriter::OpenObject(const char* property_name) {
91 open_objects_++;
92 if (property_name != nullptr) {
93 PrintPropertyName(property_name);
94 }
95 buffer_.AddChar('{');
96}
97
99 intptr_t len = buffer_.length();
100 ASSERT(len > 0);
101 ASSERT(buffer_.buffer()[len - 1] == '}');
102 open_objects_++;
103 buffer_.set_length(len - 1);
104}
105
107 ASSERT(open_objects_ > 0);
108 open_objects_--;
109 buffer_.AddChar('}');
110}
111
112void JSONWriter::OpenArray(const char* property_name) {
114 if (property_name != nullptr) {
115 PrintPropertyName(property_name);
116 }
117 open_objects_++;
118 buffer_.AddChar('[');
119}
120
122 ASSERT(open_objects_ > 0);
123 open_objects_--;
124 buffer_.AddChar(']');
125}
126
129 buffer_.Printf("null");
130}
131
134 buffer_.Printf("%s", b ? "true" : "false");
135}
136
137void JSONWriter::PrintValue(intptr_t i) {
138 EnsureIntegerIsRepresentableInJavaScript(static_cast<int64_t>(i));
140 buffer_.Printf("%" Pd "", i);
141}
142
144 EnsureIntegerIsRepresentableInJavaScript(i);
146 buffer_.Printf("%" Pd64 "", i);
147}
148
150 // Max length of a double in characters (including \0).
151 // See double_conversion.cc.
152 const size_t kBufferLen = 25;
153 char buffer[kBufferLen];
154 DoubleToCString(d, buffer, kBufferLen);
156 buffer_.Printf("%s", buffer);
157}
158
159void JSONWriter::PrintValueBase64(const uint8_t* bytes, intptr_t length) {
161 buffer_.AddChar('"');
163 buffer_.AddChar('"');
164}
165
166void JSONWriter::PrintValue(const char* s) {
168 buffer_.AddChar('"');
170 buffer_.AddChar('"');
171}
172
173void JSONWriter::PrintValue(const char* s, intptr_t i) {
175 buffer_.AddChar('"');
177 buffer_.AddChar('"');
178}
179
181 intptr_t offset,
182 intptr_t count) {
184 buffer_.AddChar('"');
185 bool did_truncate = AddDartString(s, offset, count);
186 buffer_.AddChar('"');
187 return did_truncate;
188}
189
192 buffer_.Printf("%s", s);
193}
194
195void JSONWriter::PrintfValue(const char* format, ...) {
196 va_list args;
197 va_start(args, format);
199 va_end(args);
200}
201
202void JSONWriter::VPrintfValue(const char* format, va_list args) {
204
205 va_list measure_args;
206 va_copy(measure_args, args);
207 intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
208 va_end(measure_args);
209
210 MaybeOnStackBuffer mosb(len + 1);
211 char* p = mosb.p();
212
213 va_list print_args;
214 va_copy(print_args, args);
215 intptr_t len2 = Utils::VSNPrint(p, len + 1, format, print_args);
216 va_end(print_args);
217 ASSERT(len == len2);
218
219 buffer_.AddChar('"');
220 AddEscapedUTF8String(p, len);
221 buffer_.AddChar('"');
222}
223
224void JSONWriter::PrintPropertyBool(const char* name, bool b) {
227}
228
229void JSONWriter::PrintProperty(const char* name, intptr_t i) {
231 PrintValue(i);
232}
233
234void JSONWriter::PrintProperty64(const char* name, int64_t i) {
236 PrintValue64(i);
237}
238
239void JSONWriter::PrintProperty(const char* name, double d) {
241 PrintValue(d);
242}
243
244void JSONWriter::PrintProperty(const char* name, const char* s) {
246 PrintValue(s);
247}
248
250 const uint8_t* b,
251 intptr_t len) {
253 PrintValueBase64(b, len);
254}
255
257 const String& s,
258 intptr_t offset,
259 intptr_t count) {
261 return PrintValueStr(s, offset, count);
262}
263
264void JSONWriter::PrintPropertyNoEscape(const char* name, const char* s) {
267}
268
269void JSONWriter::PrintfProperty(const char* name, const char* format, ...) {
270 va_list args;
271 va_start(args, format);
273 va_end(args);
274}
275
277 const char* format,
278 va_list args) {
280
281 va_list measure_args;
282 va_copy(measure_args, args);
283 intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
284 va_end(measure_args);
285
286 MaybeOnStackBuffer mosb(len + 1);
287 char* p = mosb.p();
288
289 va_list print_args;
290 va_copy(print_args, args);
291 intptr_t len2 = Utils::VSNPrint(p, len + 1, format, print_args);
292 va_end(print_args);
293 ASSERT(len == len2);
294
295 buffer_.AddChar('"');
296 AddEscapedUTF8String(p, len);
297 buffer_.AddChar('"');
298}
299
300void JSONWriter::Steal(char** buffer, intptr_t* buffer_length) {
301 ASSERT(buffer != nullptr);
302 ASSERT(buffer_length != nullptr);
303 *buffer_length = buffer_.length();
304 *buffer = buffer_.Steal();
305}
306
308 ASSERT(name != nullptr);
310 buffer_.AddChar('"');
312 buffer_.AddChar('"');
313 buffer_.AddChar(':');
314}
315
317 buffer_.AddChar('\n');
318}
319
321 if (NeedComma()) {
322 buffer_.AddChar(',');
323 }
324}
325
326bool JSONWriter::NeedComma() {
327 const char* buffer = buffer_.buffer();
328 intptr_t length = buffer_.length();
329 if (length == 0) {
330 return false;
331 }
332 char ch = buffer[length - 1];
333 return (ch != '[') && (ch != '{') && (ch != ':') && (ch != ',');
334}
335
336void JSONWriter::EnsureIntegerIsRepresentableInJavaScript(int64_t i) {
337#ifdef DEBUG
338 if (!Utils::IsJavaScriptInt(i)) {
340 "JSONWriter::EnsureIntegerIsRepresentableInJavaScript failed on "
341 "%" Pd64 "\n",
342 i);
343 UNREACHABLE();
344 }
345#endif
346}
347
349 if (s == nullptr) {
350 return;
351 }
352 intptr_t len = strlen(s);
354}
355
356void JSONWriter::AddEscapedUTF8String(const char* s, intptr_t len) {
357 if (s == nullptr) {
358 return;
359 }
360 buffer_.AddEscapedUTF8(s, len);
361}
362
363bool JSONWriter::AddDartString(const String& s,
364 intptr_t offset,
365 intptr_t count) {
366 intptr_t length = s.Length();
367 ASSERT(offset >= 0);
368 if (offset > length) {
369 offset = length;
370 }
372 count = length - offset;
373 }
374
375 if (count > 0) { // Avoid asserts about harmless out-of-bounds index.
376 NoSafepointScope no_safepoint;
377 if (s.IsOneByteString()) {
378 buffer_.AddEscapedLatin1(OneByteString::CharAddr(s, offset), count);
379 } else if (s.IsTwoByteString()) {
380 buffer_.AddEscapedUTF16(TwoByteString::CharAddr(s, offset), count);
381 } else {
382 UNREACHABLE();
383 }
384 }
385
386 // Return value indicates whether the string is truncated.
387 intptr_t limit = offset + count;
388 return (offset > 0) || (limit < length);
389}
390
391} // namespace dart
int count
#define UNREACHABLE()
Definition assert.h:248
void AddString(const char *s)
intptr_t Printf(const char *format,...) PRINTF_ATTRIBUTE(2
char * buffer() const
Definition text_buffer.h:35
void AddEscapedLatin1(const uint8_t *code_units, intptr_t len)
intptr_t length() const
Definition text_buffer.h:36
void AddChar(char ch)
void AddRaw(const uint8_t *buffer, intptr_t buffer_length)
void AddEscapedUTF8(const char *s, intptr_t len)
void AddEscapedUTF16(const uint16_t *code_units, intptr_t len)
void AppendBytesInBase64(const uint8_t *bytes, intptr_t length)
bool PrintPropertyStr(const char *name, const String &s, intptr_t offset=0, intptr_t count=-1)
JSONWriter(intptr_t buf_size=256)
void PrintPropertyBool(const char *name, bool b)
void PrintProperty64(const char *name, int64_t i)
void PrintPropertyBase64(const char *name, const uint8_t *bytes, intptr_t length)
void PrintCommaIfNeeded()
void Steal(char **buffer, intptr_t *buffer_length)
void PrintValue(intptr_t i)
void PrintValueBase64(const uint8_t *bytes, intptr_t length)
void PrintValueBool(bool b)
void PrintProperty(const char *name, intptr_t i)
void PrintPropertyName(const char *name)
void void VPrintfValue(const char *format, va_list args)
void PrintfValue(const char *format,...) PRINTF_ATTRIBUTE(2
void OpenArray(const char *property_name=nullptr)
void AppendBytes(const uint8_t *buffer, intptr_t buffer_length)
TextBuffer * buffer()
Definition json_writer.h:19
bool PrintValueStr(const String &s, intptr_t offset, intptr_t count)
void AppendSerializedObject(const char *serialized_object)
void void VPrintfProperty(const char *name, const char *format, va_list args)
void PrintfProperty(const char *name, const char *format,...) PRINTF_ATTRIBUTE(3
void AddEscapedUTF8String(const char *s)
void PrintValueNoEscape(const char *s)
void OpenObject(const char *property_name=nullptr)
void PrintValue64(int64_t i)
void PrintPropertyNoEscape(const char *name, const char *s)
MaybeOnStackBuffer(intptr_t size)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
void set_length(intptr_t len)
Definition text_buffer.h:67
static bool IsJavaScriptInt(int64_t value)
Definition utils.h:527
static int static int VSNPrint(char *str, size_t size, const char *format, va_list args)
static bool RangeCheck(intptr_t offset, intptr_t count, intptr_t length)
Definition utils.h:396
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
static bool b
struct MyStruct s
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
uint32_t uint32_t * format
size_t length
void DoubleToCString(double d, char *buffer, int buffer_size)
const char *const name
void * malloc(size_t size)
Definition allocation.cc:19
static const char base64_pad
static const char base64_digits[65]
#define Pd64
Definition globals.h:416
#define Pd
Definition globals.h:408
Point offset