8#ifndef SkJSONWriter_DEFINED
9#define SkJSONWriter_DEFINED
58 : fBlock(new char[kBlockSize])
60 , fBlockEnd(fBlock + kBlockSize)
63 , fState(
State::kStart) {
79 if (fWrite != fBlock) {
80 fStream->
write(fBlock, fWrite - fBlock);
94 SkASSERT(Scope::kObject == this->scope());
95 SkASSERT(State::kObjectBegin == fState || State::kObjectValue == fState);
96 if (State::kObjectValue == fState) {
99 this->separator(this->multiline());
100 this->write(
"\"", 1);
102 this->write(
"\":", 2);
103 fState = State::kObjectName;
116 this->beginValue(
true);
120 fState = State::kObjectBegin;
127 SkASSERT(Scope::kObject == this->scope());
128 SkASSERT(State::kObjectBegin == fState || State::kObjectValue == fState);
129 bool emptyObject = State::kObjectBegin == fState;
130 bool wasMultiline = this->multiline();
133 this->separator(wasMultiline);
148 this->beginValue(
true);
152 fState = State::kArrayBegin;
159 SkASSERT(Scope::kArray == this->scope());
160 SkASSERT(State::kArrayBegin == fState || State::kArrayValue == fState);
161 bool emptyArray = State::kArrayBegin == fState;
162 bool wasMultiline = this->multiline();
165 this->separator(wasMultiline);
178 this->write(
"\"", 1);
185 case '"': this->write(
"\\\"", 2);
break;
186 case '\\': this->write(
"\\\\", 2);
break;
187 case '\b': this->write(
"\\b", 2);
break;
188 case '\f': this->write(
"\\f", 2);
break;
189 case '\n': this->write(
"\\n", 2);
break;
190 case '\r': this->write(
"\\r", 2);
break;
191 case '\t': this->write(
"\\t", 2);
break;
196 s.appendHex((
unsigned char)*
value, 4);
197 this->write(
s.c_str(),
s.size());
198 }
else if (u < 0x20) {
201 this->write(
s.c_str(),
s.size());
210 this->write(
"\"", 1);
216 template <
class T, std::enable_if_t<std::is_same_v<T,std::
string>,
bool> = false>
221 static_assert(
N > 0);
232 this->write(
"true", 4);
234 this->write(
"false", 5);
245 this->appendf(
"%.*g", digits,
value);
249 this->appendf(
"%.*g", digits,
value);
263 template <
class T, std::enable_if_t<std::is_same_v<T,std::
string>,
bool> = false>
269 static_assert(
N > 0);
277#define DEFINE_NAMED_APPEND(function, type) \
278 void function(const char* name, type value) { this->appendName(name); this->function(value); }
295#undef DEFINE_NAMED_APPEND
311 kBlockSize = 32 * 1024,
332 void beginValue(
bool structure =
false) {
333 SkASSERT(State::kObjectName == fState ||
334 State::kArrayBegin == fState ||
335 State::kArrayValue == fState ||
336 (structure && State::kStart == fState));
337 if (State::kArrayValue == fState) {
340 if (Scope::kArray == this->scope()) {
341 this->separator(this->multiline());
342 }
else if (Scope::kObject == this->scope() &&
Mode::kPretty == fMode) {
348 fState = Scope::kArray == this->scope() ? State::kArrayValue : State::kObjectValue;
352 void separator(
bool multiline) {
355 this->write(
"\n", 1);
356 for (
int i = 0;
i < fScopeStack.
size() - 1; ++
i) {
365 void write(
const char* buf,
size_t length) {
366 if (
static_cast<size_t>(fBlockEnd - fWrite) <
length) {
370 if (length > kBlockSize) {
374 memcpy(fWrite, buf,
length);
379 Scope scope()
const {
381 return fScopeStack.
back();
384 bool multiline()
const {
386 return fNewlineStack.
back();
392 switch (this->scope()) {
394 fState = State::kEnd;
397 fState = State::kObjectValue;
400 fState = State::kArrayValue;
static float next(float f)
#define SkDEBUGFAIL(message)
#define SK_PRINTF_LIKE(A, B)
#define DEFINE_NAMED_APPEND(function, type)
void appendS32(int32_t value)
void appendNString(char const (&value)[N])
SkJSONWriter(SkWStream *stream, Mode mode=Mode::kFast)
void appendFloatDigits(float value, int digits)
void appendString(const T &value)
void beginArray(const char *name=nullptr, bool multiline=true)
void appendDouble(double value)
void appendNString(const char *name, char const (&value)[N])
void appendString(const char *name, const SkString &value)
void appendU32(uint32_t value)
void appendDoubleDigits(const char *name, double value, int digits)
void beginObject(const char *name=nullptr, bool multiline=true)
void appendU64(uint64_t value)
void appendFloat(float value)
void appendPointer(const void *value)
void appendS64(int64_t value)
void appendCString(const char *name, const char *value)
void appendBool(bool value)
void appendName(const char *name)
void appendCString(const char *value)
void appendString(const SkString &value)
void appendString(const char *name, const T &value)
void appendHexU64(uint64_t value)
void appendString(const char *value, size_t size)
void appendDoubleDigits(double value, int digits)
void appendHexU32(uint32_t value)
void appendFloatDigits(const char *name, float value, int digits)
void appendString(const char *name, const char *value, size_t size)
const char * c_str() const
virtual bool write(const void *buffer, size_t size)=0
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static SkString fmt(SkColor4f c)