1 | // Copyright (c) 2013, 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 | #ifndef RUNTIME_VM_JSON_STREAM_H_ |
6 | #define RUNTIME_VM_JSON_STREAM_H_ |
7 | |
8 | #include "include/dart_api.h" // for Dart_Port |
9 | #include "platform/allocation.h" |
10 | #include "platform/text_buffer.h" |
11 | #include "vm/json_writer.h" |
12 | #include "vm/os.h" |
13 | #include "vm/service.h" |
14 | #include "vm/token_position.h" |
15 | |
16 | namespace dart { |
17 | |
18 | class Array; |
19 | class Breakpoint; |
20 | class BreakpointLocation; |
21 | class Field; |
22 | class GrowableObjectArray; |
23 | class Instance; |
24 | class JSONArray; |
25 | class JSONObject; |
26 | class MessageQueue; |
27 | class Metric; |
28 | class Object; |
29 | class Script; |
30 | class ServiceEvent; |
31 | class String; |
32 | class TimelineEvent; |
33 | class TimelineEventBlock; |
34 | class Thread; |
35 | class ThreadRegistry; |
36 | class Zone; |
37 | |
38 | // Keep this enum in sync with: |
39 | // |
40 | // - runtime/vm/service/vmservice.dart |
41 | // - runtime/observatory/lib/src/service/object.dart |
42 | // - pkg/dds/lib/src/rpc_error_codes.dart |
43 | // |
44 | enum JSONRpcErrorCode { |
45 | kParseError = -32700, |
46 | kInvalidRequest = -32600, |
47 | kMethodNotFound = -32601, |
48 | kInvalidParams = -32602, |
49 | kInternalError = -32603, |
50 | |
51 | kExtensionError = -32000, |
52 | |
53 | kFeatureDisabled = 100, |
54 | kCannotAddBreakpoint = 102, |
55 | kStreamAlreadySubscribed = 103, |
56 | kStreamNotSubscribed = 104, |
57 | kIsolateMustBeRunnable = 105, |
58 | kIsolateMustBePaused = 106, |
59 | kCannotResume = 107, |
60 | kIsolateIsReloading = 108, |
61 | kIsolateReloadBarred = 109, |
62 | kIsolateMustHaveReloaded = 110, |
63 | kServiceAlreadyRegistered = 111, |
64 | kServiceDisappeared = 112, |
65 | kExpressionCompilationError = 113, |
66 | kInvalidTimelineRequest = 114, |
67 | |
68 | // Experimental (used in private rpcs). |
69 | kFileSystemAlreadyExists = 1001, |
70 | kFileSystemDoesNotExist = 1002, |
71 | kFileDoesNotExist = 1003, |
72 | }; |
73 | |
74 | // Builds on JSONWriter to provide support for serializing various objects |
75 | // used in the VM service protocol. |
76 | class JSONStream : ValueObject { |
77 | public: |
78 | explicit JSONStream(intptr_t buf_size = 256); |
79 | |
80 | void Setup(Zone* zone, |
81 | Dart_Port reply_port, |
82 | const Instance& seq, |
83 | const String& method, |
84 | const Array& param_keys, |
85 | const Array& param_values, |
86 | bool parameters_are_dart_objects = false); |
87 | void SetupError(); |
88 | |
89 | void PrintError(intptr_t code, const char* details_format, ...) |
90 | PRINTF_ATTRIBUTE(3, 4); |
91 | |
92 | void PostReply(); |
93 | |
94 | void set_id_zone(ServiceIdZone* id_zone) { id_zone_ = id_zone; } |
95 | ServiceIdZone* id_zone() { return id_zone_; } |
96 | |
97 | TextBuffer* buffer() { return writer_.buffer(); } |
98 | const char* ToCString() { return writer_.ToCString(); } |
99 | |
100 | void Steal(char** buffer, intptr_t* buffer_length) { |
101 | writer_.Steal(buffer, buffer_length); |
102 | } |
103 | |
104 | void set_reply_port(Dart_Port port); |
105 | |
106 | bool include_private_members() const { return include_private_members_; } |
107 | void set_include_private_members(bool include_private_members) { |
108 | include_private_members_ = include_private_members; |
109 | } |
110 | |
111 | bool IsAllowableKey(const char* key) { |
112 | if (include_private_members_) { |
113 | return true; |
114 | } |
115 | return *key != '_'; |
116 | } |
117 | |
118 | void SetParams(const char** param_keys, |
119 | const char** param_values, |
120 | intptr_t num_params); |
121 | |
122 | Dart_Port reply_port() const { return reply_port_; } |
123 | |
124 | intptr_t NumObjectParameters() const; |
125 | ObjectPtr GetObjectParameterKey(intptr_t i) const; |
126 | ObjectPtr GetObjectParameterValue(intptr_t i) const; |
127 | ObjectPtr LookupObjectParam(const char* key) const; |
128 | |
129 | intptr_t num_params() const { return num_params_; } |
130 | const char* GetParamKey(intptr_t i) const { return param_keys_[i]; } |
131 | const char* GetParamValue(intptr_t i) const { return param_values_[i]; } |
132 | |
133 | const char* LookupParam(const char* key) const; |
134 | |
135 | bool HasParam(const char* key) const; |
136 | |
137 | // Returns true if there is an param with key and value, false |
138 | // otherwise. |
139 | bool ParamIs(const char* key, const char* value) const; |
140 | |
141 | const char* method() const { return method_; } |
142 | const char** param_keys() const { return param_keys_; } |
143 | const char** param_values() const { return param_values_; } |
144 | |
145 | void set_offset(intptr_t value) { |
146 | ASSERT(value > 0); |
147 | offset_ = value; |
148 | } |
149 | |
150 | void set_count(intptr_t value) { |
151 | ASSERT(value > 0); |
152 | count_ = value; |
153 | } |
154 | |
155 | void ComputeOffsetAndCount(intptr_t length, |
156 | intptr_t* offset, |
157 | intptr_t* count); |
158 | |
159 | // Append |buffer| to the stream. |
160 | void AppendBytes(const uint8_t* buffer, intptr_t buffer_length) { |
161 | writer_.AppendBytes(buffer, buffer_length); |
162 | } |
163 | |
164 | // Append |serialized_object| to the stream. |
165 | void AppendSerializedObject(const char* serialized_object) { |
166 | writer_.AppendSerializedObject(serialized_object); |
167 | } |
168 | |
169 | // Append |serialized_object| to the stream with |property_name|. |
170 | void AppendSerializedObject(const char* property_name, |
171 | const char* serialized_object) { |
172 | writer_.AppendSerializedObject(property_name, serialized_object); |
173 | } |
174 | |
175 | void PrintCommaIfNeeded() { writer_.PrintCommaIfNeeded(); } |
176 | JSONWriter* writer() { return &writer_; } |
177 | |
178 | private: |
179 | void Clear() { writer_.Clear(); } |
180 | |
181 | void PostNullReply(Dart_Port port); |
182 | |
183 | void OpenObject(const char* property_name = nullptr) { |
184 | if (ignore_object_depth_ > 0 || |
185 | (property_name != nullptr && !IsAllowableKey(key: property_name))) { |
186 | ignore_object_depth_++; |
187 | return; |
188 | } |
189 | writer_.OpenObject(property_name); |
190 | } |
191 | void CloseObject() { |
192 | if (ignore_object_depth_ > 0) { |
193 | ignore_object_depth_--; |
194 | return; |
195 | } |
196 | writer_.CloseObject(); |
197 | } |
198 | void UncloseObject() { |
199 | // This should be updated to handle unclosing a private object if we need |
200 | // to handle that case, which we don't currently. |
201 | writer_.UncloseObject(); |
202 | } |
203 | |
204 | void OpenArray(const char* property_name = nullptr) { |
205 | if (ignore_object_depth_ > 0 || |
206 | (property_name != nullptr && !IsAllowableKey(key: property_name))) { |
207 | ignore_object_depth_++; |
208 | return; |
209 | } |
210 | writer_.OpenArray(property_name); |
211 | } |
212 | void CloseArray() { |
213 | if (ignore_object_depth_ > 0) { |
214 | ignore_object_depth_--; |
215 | return; |
216 | } |
217 | writer_.CloseArray(); |
218 | } |
219 | |
220 | // Append the Base64 encoding of |bytes| to the stream. |
221 | // |
222 | // Beware that padding characters are added when |length| is not a multiple of |
223 | // three. Padding is only valid at the end of Base64 strings, so you must be |
224 | // careful when trying to populate a single Base64 string with multiple calls |
225 | // to this method. |JSONBase64String| should be used for that use-case, |
226 | // because it handles padding management. |
227 | void AppendBytesInBase64(const uint8_t* bytes, intptr_t length) { |
228 | writer_.AppendBytesInBase64(bytes, length); |
229 | } |
230 | void PrintValueNull() { writer_.PrintValueNull(); } |
231 | void PrintValueBool(bool b) { writer_.PrintValueBool(b); } |
232 | void PrintValue(intptr_t i) { writer_.PrintValue(i); } |
233 | void PrintValue64(int64_t i) { writer_.PrintValue64(i); } |
234 | void PrintValueTimeMillis(int64_t millis) { writer_.PrintValue64(i: millis); } |
235 | void PrintValueTimeMicros(int64_t micros) { writer_.PrintValue64(i: micros); } |
236 | void PrintValue(double d) { writer_.PrintValue(d); } |
237 | void PrintValueBase64(const uint8_t* bytes, intptr_t length) { |
238 | writer_.PrintValueBase64(bytes, length); |
239 | } |
240 | void PrintValue(const char* s) { writer_.PrintValue(s); } |
241 | void PrintValueNoEscape(const char* s) { writer_.PrintValueNoEscape(s); } |
242 | bool PrintValueStr(const String& s, intptr_t offset, intptr_t count) { |
243 | return writer_.PrintValueStr(s, offset, count); |
244 | } |
245 | void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
246 | void VPrintfValue(const char* format, va_list args) { |
247 | writer_.VPrintfValue(format, args); |
248 | } |
249 | |
250 | void PrintValue(const Object& o, bool ref = true); |
251 | void PrintValue(Breakpoint* bpt); |
252 | void PrintValue(TokenPosition tp); |
253 | void PrintValue(const ServiceEvent* event); |
254 | void PrintValue(Metric* metric); |
255 | void PrintValue(MessageQueue* queue); |
256 | void PrintValue(Isolate* isolate, bool ref = true); |
257 | void PrintValue(IsolateGroup* isolate, bool ref = true); |
258 | void PrintValue(const TimelineEvent* timeline_event); |
259 | void PrintValue(const TimelineEventBlock* timeline_event_block); |
260 | void PrintValueVM(bool ref = true); |
261 | |
262 | void PrintServiceId(const Object& o); |
263 | |
264 | #define PRIVATE_NAME_CHECK() \ |
265 | if (!IsAllowableKey(name) || ignore_object_depth_ > 0) { \ |
266 | return; \ |
267 | } |
268 | |
269 | void PrintPropertyBool(const char* name, bool b) { |
270 | PRIVATE_NAME_CHECK(); |
271 | writer_.PrintPropertyBool(name, b); |
272 | } |
273 | void PrintProperty(const char* name, intptr_t i) { |
274 | PRIVATE_NAME_CHECK(); |
275 | writer_.PrintProperty(name, i); |
276 | } |
277 | void PrintProperty64(const char* name, int64_t i) { |
278 | PRIVATE_NAME_CHECK(); |
279 | writer_.PrintProperty64(name, i); |
280 | } |
281 | void PrintPropertyTimeMillis(const char* name, int64_t millis) { |
282 | PRIVATE_NAME_CHECK(); |
283 | writer_.PrintProperty64(name, i: millis); |
284 | } |
285 | void PrintPropertyTimeMicros(const char* name, int64_t micros) { |
286 | PRIVATE_NAME_CHECK(); |
287 | writer_.PrintProperty64(name, i: micros); |
288 | } |
289 | void PrintProperty(const char* name, double d) { |
290 | PRIVATE_NAME_CHECK(); |
291 | writer_.PrintProperty(name, d); |
292 | } |
293 | void PrintPropertyBase64(const char* name, |
294 | const uint8_t* bytes, |
295 | intptr_t length) { |
296 | PRIVATE_NAME_CHECK(); |
297 | writer_.PrintPropertyBase64(name, bytes, length); |
298 | } |
299 | void PrintProperty(const char* name, const char* s) { |
300 | PRIVATE_NAME_CHECK(); |
301 | writer_.PrintProperty(name, s); |
302 | } |
303 | bool PrintPropertyStr(const char* name, |
304 | const String& s, |
305 | intptr_t offset, |
306 | intptr_t count) { |
307 | if (!IsAllowableKey(key: name)) { |
308 | return false; |
309 | } |
310 | return writer_.PrintPropertyStr(name, s, offset, count); |
311 | } |
312 | void PrintPropertyNoEscape(const char* name, const char* s) { |
313 | PRIVATE_NAME_CHECK(); |
314 | writer_.PrintPropertyNoEscape(name, s); |
315 | } |
316 | void PrintfProperty(const char* name, const char* format, ...) |
317 | PRINTF_ATTRIBUTE(3, 4); |
318 | void VPrintfProperty(const char* name, const char* format, va_list args) { |
319 | PRIVATE_NAME_CHECK(); |
320 | writer_.VPrintfProperty(name, format, args); |
321 | } |
322 | |
323 | #undef PRIVATE_NAME_CHECK |
324 | |
325 | void PrintProperty(const char* name, const Object& o, bool ref = true); |
326 | |
327 | void PrintProperty(const char* name, const ServiceEvent* event); |
328 | void PrintProperty(const char* name, Breakpoint* bpt); |
329 | void PrintProperty(const char* name, TokenPosition tp); |
330 | void PrintProperty(const char* name, Metric* metric); |
331 | void PrintProperty(const char* name, MessageQueue* queue); |
332 | void PrintProperty(const char* name, Isolate* isolate); |
333 | void PrintProperty(const char* name, IsolateGroup* isolate_group); |
334 | void PrintProperty(const char* name, Zone* zone); |
335 | void PrintProperty(const char* name, const TimelineEvent* timeline_event); |
336 | void PrintProperty(const char* name, |
337 | const TimelineEventBlock* timeline_event_block); |
338 | void PrintPropertyVM(const char* name, bool ref = true); |
339 | void PrintPropertyName(const char* name) { writer_.PrintPropertyName(name); } |
340 | |
341 | void AddEscapedUTF8String(const char* s, intptr_t len) { |
342 | writer_.AddEscapedUTF8String(s, len); |
343 | } |
344 | |
345 | JSONWriter writer_; |
346 | // Default service id zone. |
347 | RingServiceIdZone default_id_zone_; |
348 | ServiceIdZone* id_zone_; |
349 | Dart_Port reply_port_; |
350 | Instance* seq_; |
351 | Array* parameter_keys_; |
352 | Array* parameter_values_; |
353 | const char* method_; |
354 | const char** param_keys_; |
355 | const char** param_values_; |
356 | intptr_t num_params_; |
357 | intptr_t offset_; |
358 | intptr_t count_; |
359 | int64_t setup_time_micros_; |
360 | bool include_private_members_; |
361 | intptr_t ignore_object_depth_; |
362 | friend class JSONObject; |
363 | friend class JSONArray; |
364 | friend class JSONBase64String; |
365 | friend class TimelineEvent; |
366 | }; |
367 | |
368 | class JSONObject : public ValueObject { |
369 | public: |
370 | explicit JSONObject(JSONStream* stream) : stream_(stream) { |
371 | stream_->OpenObject(); |
372 | } |
373 | JSONObject(const JSONObject* obj, const char* name) : stream_(obj->stream_) { |
374 | stream_->OpenObject(property_name: name); |
375 | } |
376 | explicit JSONObject(const JSONArray* arr); |
377 | |
378 | ~JSONObject() { stream_->CloseObject(); } |
379 | |
380 | void AddServiceId(const Object& o) const { stream_->PrintServiceId(o); } |
381 | |
382 | void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3); |
383 | void AddServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3); |
384 | |
385 | void AddLocation( |
386 | const Script& script, |
387 | TokenPosition token_pos, |
388 | TokenPosition end_token_pos = TokenPosition::kNoSource) const; |
389 | |
390 | void AddLocation(const BreakpointLocation* bpt_loc) const; |
391 | void AddLocationLine(const Script& script, intptr_t line) const; |
392 | |
393 | void AddUnresolvedLocation(const BreakpointLocation* bpt_loc) const; |
394 | |
395 | void AddProperty(const char* name, bool b) const { |
396 | stream_->PrintPropertyBool(name, b); |
397 | } |
398 | void AddProperty(const char* name, intptr_t i) const { |
399 | stream_->PrintProperty(name, i); |
400 | } |
401 | void AddProperty64(const char* name, int64_t i) const { |
402 | stream_->PrintProperty64(name, i); |
403 | } |
404 | void AddPropertyTimeMillis(const char* name, int64_t millis) const { |
405 | stream_->PrintPropertyTimeMillis(name, millis); |
406 | } |
407 | void AddPropertyTimeMicros(const char* name, int64_t micros) const { |
408 | stream_->PrintPropertyTimeMicros(name, micros); |
409 | } |
410 | void AddProperty(const char* name, double d) const { |
411 | stream_->PrintProperty(name, d); |
412 | } |
413 | void AddPropertyBase64(const char* name, |
414 | const uint8_t* bytes, |
415 | intptr_t length) const { |
416 | stream_->PrintPropertyBase64(name, bytes, length); |
417 | } |
418 | void AddProperty(const char* name, const char* s) const { |
419 | stream_->PrintProperty(name, s); |
420 | } |
421 | bool AddPropertyStr(const char* name, |
422 | const String& s, |
423 | intptr_t offset = 0, |
424 | intptr_t count = -1) const { |
425 | return stream_->PrintPropertyStr(name, s, offset, count); |
426 | } |
427 | void AddPropertyNoEscape(const char* name, const char* s) const { |
428 | stream_->PrintPropertyNoEscape(name, s); |
429 | } |
430 | void AddProperty(const char* name, const Object& obj, bool ref = true) const { |
431 | stream_->PrintProperty(name, o: obj, ref); |
432 | } |
433 | void AddProperty(const char* name, const ServiceEvent* event) const { |
434 | stream_->PrintProperty(name, event); |
435 | } |
436 | void AddProperty(const char* name, Breakpoint* bpt) const { |
437 | stream_->PrintProperty(name, bpt); |
438 | } |
439 | void AddProperty(const char* name, TokenPosition tp) const { |
440 | stream_->PrintProperty(name, tp); |
441 | } |
442 | void AddProperty(const char* name, Metric* metric) const { |
443 | stream_->PrintProperty(name, metric); |
444 | } |
445 | void AddProperty(const char* name, MessageQueue* queue) const { |
446 | stream_->PrintProperty(name, queue); |
447 | } |
448 | void AddProperty(const char* name, Isolate* isolate) const { |
449 | stream_->PrintProperty(name, isolate); |
450 | } |
451 | void AddProperty(const char* name, IsolateGroup* isolate_group) const { |
452 | stream_->PrintProperty(name, isolate_group); |
453 | } |
454 | void AddProperty(const char* name, Zone* zone) const { |
455 | stream_->PrintProperty(name, zone); |
456 | } |
457 | void AddProperty(const char* name, |
458 | const TimelineEvent* timeline_event) const { |
459 | stream_->PrintProperty(name, timeline_event); |
460 | } |
461 | void AddProperty(const char* name, |
462 | const TimelineEventBlock* timeline_event_block) const { |
463 | stream_->PrintProperty(name, timeline_event_block); |
464 | } |
465 | void AddPropertyVM(const char* name, bool ref = true) const { |
466 | stream_->PrintPropertyVM(name, ref); |
467 | } |
468 | void AddPropertyF(const char* name, const char* format, ...) const |
469 | PRINTF_ATTRIBUTE(3, 4); |
470 | |
471 | private: |
472 | JSONStream* stream_; |
473 | |
474 | friend class JSONArray; |
475 | |
476 | DISALLOW_ALLOCATION(); |
477 | DISALLOW_COPY_AND_ASSIGN(JSONObject); |
478 | }; |
479 | |
480 | class JSONArray : public ValueObject { |
481 | public: |
482 | explicit JSONArray(JSONStream* stream) : stream_(stream) { |
483 | stream_->OpenArray(); |
484 | } |
485 | JSONArray(const JSONObject* obj, const char* name) : stream_(obj->stream_) { |
486 | stream_->OpenArray(property_name: name); |
487 | } |
488 | explicit JSONArray(const JSONArray* arr) : stream_(arr->stream_) { |
489 | stream_->OpenArray(); |
490 | } |
491 | ~JSONArray() { stream_->CloseArray(); } |
492 | |
493 | void AddValueNull() const { stream_->PrintValueNull(); } |
494 | void AddValue(bool b) const { stream_->PrintValueBool(b); } |
495 | void AddValue(intptr_t i) const { stream_->PrintValue(i); } |
496 | void AddValue64(int64_t i) const { stream_->PrintValue64(i); } |
497 | void AddValueTimeMillis(int64_t millis) const { |
498 | stream_->PrintValueTimeMillis(millis); |
499 | } |
500 | void AddValueTimeMicros(int64_t micros) const { |
501 | stream_->PrintValueTimeMicros(micros); |
502 | } |
503 | void AddValue(double d) const { stream_->PrintValue(d); } |
504 | void AddValue(const char* s) const { stream_->PrintValue(s); } |
505 | void AddValue(const Object& obj, bool ref = true) const { |
506 | stream_->PrintValue(o: obj, ref); |
507 | } |
508 | void AddValue(Isolate* isolate, bool ref = true) const { |
509 | stream_->PrintValue(isolate, ref); |
510 | } |
511 | void AddValue(IsolateGroup* isolate_group, bool ref = true) const { |
512 | stream_->PrintValue(isolate: isolate_group, ref); |
513 | } |
514 | void AddValue(Breakpoint* bpt) const { stream_->PrintValue(bpt); } |
515 | void AddValue(TokenPosition tp) const { stream_->PrintValue(tp); } |
516 | void AddValue(const ServiceEvent* event) const { stream_->PrintValue(event); } |
517 | void AddValue(Metric* metric) const { stream_->PrintValue(metric); } |
518 | void AddValue(MessageQueue* queue) const { stream_->PrintValue(queue); } |
519 | void AddValue(const TimelineEvent* timeline_event) const { |
520 | stream_->PrintValue(timeline_event); |
521 | } |
522 | void AddValue(const TimelineEventBlock* timeline_event_block) const { |
523 | stream_->PrintValue(timeline_event_block); |
524 | } |
525 | void AddValueVM(bool ref = true) const { stream_->PrintValueVM(ref); } |
526 | void AddValueF(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3); |
527 | |
528 | private: |
529 | JSONStream* stream_; |
530 | |
531 | friend class JSONObject; |
532 | |
533 | DISALLOW_ALLOCATION(); |
534 | DISALLOW_COPY_AND_ASSIGN(JSONArray); |
535 | }; |
536 | |
537 | class JSONBase64String : public ValueObject { |
538 | public: |
539 | explicit JSONBase64String(JSONStream* stream) |
540 | : stream_(stream), queued_bytes_(), num_queued_bytes_(0) { |
541 | stream_->AppendBytes(buffer: reinterpret_cast<const uint8_t*>("\""), buffer_length: 1); |
542 | } |
543 | ~JSONBase64String() { |
544 | stream_->AppendBytesInBase64(bytes: queued_bytes_, length: num_queued_bytes_); |
545 | stream_->AppendBytes(buffer: reinterpret_cast<const uint8_t*>("\""), buffer_length: 1); |
546 | } |
547 | |
548 | void AppendBytes(const uint8_t* bytes, intptr_t length); |
549 | |
550 | private: |
551 | JSONStream* stream_; |
552 | uint8_t queued_bytes_[3]; |
553 | intptr_t num_queued_bytes_; |
554 | |
555 | DISALLOW_ALLOCATION(); |
556 | DISALLOW_COPY_AND_ASSIGN(JSONBase64String); |
557 | }; |
558 | |
559 | } // namespace dart |
560 | |
561 | #endif // RUNTIME_VM_JSON_STREAM_H_ |
562 |
Definitions
- JSONRpcErrorCode
- JSONStream
- set_id_zone
- id_zone
- buffer
- ToCString
- Steal
- include_private_members
- set_include_private_members
- IsAllowableKey
- reply_port
- num_params
- GetParamKey
- GetParamValue
- method
- param_keys
- param_values
- set_offset
- set_count
- AppendBytes
- AppendSerializedObject
- AppendSerializedObject
- PrintCommaIfNeeded
- writer
- Clear
- OpenObject
- CloseObject
- UncloseObject
- OpenArray
- CloseArray
- AppendBytesInBase64
- PrintValueNull
- PrintValueBool
- PrintValue
- PrintValue64
- PrintValueTimeMillis
- PrintValueTimeMicros
- PrintValue
- PrintValueBase64
- PrintValue
- PrintValueNoEscape
- PrintValueStr
- VPrintfValue
- PrintPropertyBool
- PrintProperty
- PrintProperty64
- PrintPropertyTimeMillis
- PrintPropertyTimeMicros
- PrintProperty
- PrintPropertyBase64
- PrintProperty
- PrintPropertyStr
- PrintPropertyNoEscape
- VPrintfProperty
- PrintPropertyName
- AddEscapedUTF8String
- JSONObject
- JSONObject
- JSONObject
- ~JSONObject
- AddServiceId
- AddProperty
- AddProperty
- AddProperty64
- AddPropertyTimeMillis
- AddPropertyTimeMicros
- AddProperty
- AddPropertyBase64
- AddProperty
- AddPropertyStr
- AddPropertyNoEscape
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddProperty
- AddPropertyVM
- JSONObject
- JSONArray
- JSONArray
- JSONArray
- JSONArray
- ~JSONArray
- AddValueNull
- AddValue
- AddValue
- AddValue64
- AddValueTimeMillis
- AddValueTimeMicros
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValue
- AddValueVM
- JSONArray
- JSONBase64String
- JSONBase64String
- ~JSONBase64String
Learn more about Flutter for embedded and desktop on industrialflutter.com