Flutter Engine
The Flutter Engine
SkString.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
15#include "src/base/SkSafeMath.h"
16#include "src/base/SkUTF.h"
17#include "src/base/SkUtils.h"
18
19#include <algorithm>
20#include <cstdio>
21#include <cstring>
22#include <new>
23#include <string_view>
24#include <utility>
25
26// number of bytes (on the stack) to receive the printf result
27static const size_t kBufferSize = 1024;
28
30 char* fText;
32};
33
34template <int SIZE>
35static StringBuffer apply_format_string(const char* format, va_list args, char (&stackBuffer)[SIZE],
36 SkString* heapBuffer) SK_PRINTF_LIKE(1, 0);
37
38template <int SIZE>
39static StringBuffer apply_format_string(const char* format, va_list args, char (&stackBuffer)[SIZE],
40 SkString* heapBuffer) {
41 // First, attempt to print directly to the stack buffer.
42 va_list argsCopy;
43 va_copy(argsCopy, args);
44 int outLength = std::vsnprintf(stackBuffer, SIZE, format, args);
45 if (outLength < 0) {
46 SkDebugf("SkString: vsnprintf reported error.");
47 va_end(argsCopy);
48 return {stackBuffer, 0};
49 }
50 if (outLength < SIZE) {
51 va_end(argsCopy);
52 return {stackBuffer, outLength};
53 }
54
55 // Our text was too long to fit on the stack! However, we now know how much space we need to
56 // format it. Format the string into our heap buffer. `set` automatically reserves an extra
57 // byte at the end of the buffer for a null terminator, so we don't need to add one here.
58 heapBuffer->set(nullptr, outLength);
59 char* heapBufferDest = heapBuffer->data();
60 SkDEBUGCODE(int checkLength =) std::vsnprintf(heapBufferDest, outLength + 1, format, argsCopy);
61 SkASSERT(checkLength == outLength);
62 va_end(argsCopy);
63 return {heapBufferDest, outLength};
64}
65
66///////////////////////////////////////////////////////////////////////////////
67
68bool SkStrEndsWith(const char string[], const char suffixStr[]) {
69 SkASSERT(string);
70 SkASSERT(suffixStr);
71 size_t strLen = strlen(string);
72 size_t suffixLen = strlen(suffixStr);
73 return strLen >= suffixLen &&
74 !strncmp(string + strLen - suffixLen, suffixStr, suffixLen);
75}
76
77bool SkStrEndsWith(const char string[], const char suffixChar) {
78 SkASSERT(string);
79 size_t strLen = strlen(string);
80 if (0 == strLen) {
81 return false;
82 } else {
83 return (suffixChar == string[strLen-1]);
84 }
85}
86
87int SkStrStartsWithOneOf(const char string[], const char prefixes[]) {
88 int index = 0;
89 do {
90 const char* limit = strchr(prefixes, '\0');
91 if (!strncmp(string, prefixes, limit - prefixes)) {
92 return index;
93 }
94 prefixes = limit + 1;
95 index++;
96 } while (prefixes[0]);
97 return -1;
98}
99
100char* SkStrAppendU32(char string[], uint32_t dec) {
101 SkDEBUGCODE(char* start = string;)
102
104 char* p = buffer + sizeof(buffer);
105
106 do {
107 *--p = SkToU8('0' + dec % 10);
108 dec /= 10;
109 } while (dec != 0);
110
111 SkASSERT(p >= buffer);
112 size_t cp_len = buffer + sizeof(buffer) - p;
113 memcpy(string, p, cp_len);
114 string += cp_len;
115
117 return string;
118}
119
120char* SkStrAppendS32(char string[], int32_t dec) {
121 uint32_t udec = dec;
122 if (dec < 0) {
123 *string++ = '-';
124 udec = ~udec + 1; // udec = -udec, but silences some warnings that are trying to be helpful
125 }
126 return SkStrAppendU32(string, udec);
127}
128
129char* SkStrAppendU64(char string[], uint64_t dec, int minDigits) {
130 SkDEBUGCODE(char* start = string;)
131
133 char* p = buffer + sizeof(buffer);
134
135 do {
136 *--p = SkToU8('0' + (int32_t) (dec % 10));
137 dec /= 10;
138 minDigits--;
139 } while (dec != 0);
140
141 while (minDigits > 0) {
142 *--p = '0';
143 minDigits--;
144 }
145
146 SkASSERT(p >= buffer);
147 size_t cp_len = buffer + sizeof(buffer) - p;
148 memcpy(string, p, cp_len);
149 string += cp_len;
150
152 return string;
153}
154
155char* SkStrAppendS64(char string[], int64_t dec, int minDigits) {
156 uint64_t udec = dec;
157 if (dec < 0) {
158 *string++ = '-';
159 udec = ~udec + 1; // udec = -udec, but silences some warnings that are trying to be helpful
160 }
161 return SkStrAppendU64(string, udec, minDigits);
162}
163
164char* SkStrAppendScalar(char string[], SkScalar value) {
165 // Handle infinity and NaN ourselves to ensure consistent cross-platform results.
166 // (e.g.: `inf` versus `1.#INF00`, `nan` versus `-nan` for high-bit-set NaNs)
167 if (SkIsNaN(value)) {
168 strcpy(string, "nan");
169 return string + 3;
170 }
171 if (!SkIsFinite(value)) {
172 if (value > 0) {
173 strcpy(string, "inf");
174 return string + 3;
175 } else {
176 strcpy(string, "-inf");
177 return string + 4;
178 }
179 }
180
181 // since floats have at most 8 significant digits, we limit our %g to that.
182 static const char gFormat[] = "%.8g";
183 // make it 1 larger for the terminating 0
185 int len = snprintf(buffer, sizeof(buffer), gFormat, value);
186 memcpy(string, buffer, len);
188 return string + len;
189}
190
191///////////////////////////////////////////////////////////////////////////////
192
193const SkString::Rec SkString::gEmptyRec(0, 0);
194
195#define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec)
196
197static uint32_t trim_size_t_to_u32(size_t value) {
198 if (sizeof(size_t) > sizeof(uint32_t)) {
199 if (value > UINT32_MAX) {
200 value = UINT32_MAX;
201 }
202 }
203 return (uint32_t)value;
204}
205
206static size_t check_add32(size_t base, size_t extra) {
207 SkASSERT(base <= UINT32_MAX);
208 if (sizeof(size_t) > sizeof(uint32_t)) {
209 if (base + extra > UINT32_MAX) {
210 extra = UINT32_MAX - base;
211 }
212 }
213 return extra;
214}
215
216sk_sp<SkString::Rec> SkString::Rec::Make(const char text[], size_t len) {
217 if (0 == len) {
218 return sk_sp<SkString::Rec>(const_cast<Rec*>(&gEmptyRec));
219 }
220
221 SkSafeMath safe;
222 // We store a 32bit version of the length
223 uint32_t stringLen = safe.castTo<uint32_t>(len);
224 // Add SizeOfRec() for our overhead and 1 for null-termination
225 size_t allocationSize = safe.add(len, SizeOfRec() + sizeof(char));
226 // Align up to a multiple of 4
227 allocationSize = safe.alignUp(allocationSize, 4);
228
229 SkASSERT_RELEASE(safe.ok());
230
231 void* storage = ::operator new (allocationSize);
232 sk_sp<Rec> rec(new (storage) Rec(stringLen, 1));
233 if (text) {
234 memcpy(rec->data(), text, len);
235 }
236 rec->data()[len] = 0;
237 return rec;
238}
239
240void SkString::Rec::ref() const {
241 if (this == &SkString::gEmptyRec) {
242 return;
243 }
244 SkAssertResult(this->fRefCnt.fetch_add(+1, std::memory_order_relaxed));
245}
246
247void SkString::Rec::unref() const {
248 if (this == &SkString::gEmptyRec) {
249 return;
250 }
251 int32_t oldRefCnt = this->fRefCnt.fetch_add(-1, std::memory_order_acq_rel);
252 SkASSERT(oldRefCnt);
253 if (1 == oldRefCnt) {
254 delete this;
255 }
256}
257
258bool SkString::Rec::unique() const {
259 return fRefCnt.load(std::memory_order_acquire) == 1;
260}
261
262#ifdef SK_DEBUG
263int32_t SkString::Rec::getRefCnt() const {
264 return fRefCnt.load(std::memory_order_relaxed);
265}
266
267const SkString& SkString::validate() const {
268 // make sure no one has written over our global
269 SkASSERT(0 == gEmptyRec.fLength);
270 SkASSERT(0 == gEmptyRec.getRefCnt());
271 SkASSERT(0 == gEmptyRec.data()[0]);
272
273 if (fRec.get() != &gEmptyRec) {
274 SkASSERT(fRec->fLength > 0);
275 SkASSERT(fRec->getRefCnt() > 0);
276 SkASSERT(0 == fRec->data()[fRec->fLength]);
277 }
278 return *this;
279}
280
281SkString& SkString::validate() {
282 const_cast<const SkString*>(this)->validate();
283 return *this;
284}
285#endif
286
287///////////////////////////////////////////////////////////////////////////////
288
289SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) {
290}
291
293 fRec = Rec::Make(nullptr, len);
294}
295
297 size_t len = text ? strlen(text) : 0;
298
299 fRec = Rec::Make(text, len);
300}
301
302SkString::SkString(const char text[], size_t len) {
303 fRec = Rec::Make(text, len);
304}
305
306SkString::SkString(const SkString& src) : fRec(src.validate().fRec) {}
307
308SkString::SkString(SkString&& src) : fRec(std::move(src.validate().fRec)) {
309 src.fRec.reset(const_cast<Rec*>(&gEmptyRec));
310}
311
312SkString::SkString(const std::string& src) {
313 fRec = Rec::Make(src.c_str(), src.size());
314}
315
316SkString::SkString(std::string_view src) {
317 fRec = Rec::Make(src.data(), src.length());
318}
319
321 this->validate();
322}
323
324bool SkString::equals(const SkString& src) const {
325 return fRec == src.fRec || this->equals(src.c_str(), src.size());
326}
327
328bool SkString::equals(const char text[]) const {
329 return this->equals(text, text ? strlen(text) : 0);
330}
331
332bool SkString::equals(const char text[], size_t len) const {
333 SkASSERT(len == 0 || text != nullptr);
334
335 return fRec->fLength == len && !sk_careful_memcmp(fRec->data(), text, len);
336}
337
339 this->validate();
340 fRec = src.fRec; // sk_sp<Rec>::operator=(const sk_sp<Ref>&) checks for self-assignment.
341 return *this;
342}
343
345 this->validate();
346
347 if (fRec != src.fRec) {
348 this->swap(src);
349 }
350 return *this;
351}
352
354 this->validate();
355 return *this = SkString(text);
356}
357
359 this->validate();
360 fRec.reset(const_cast<Rec*>(&gEmptyRec));
361}
362
364 this->validate();
365
366 if (fRec->fLength) {
367 if (!fRec->unique()) {
368 fRec = Rec::Make(fRec->data(), fRec->fLength);
369 }
370 }
371 return fRec->data();
372}
373
374void SkString::resize(size_t len) {
376 if (0 == len) {
377 this->reset();
378 } else if (fRec->unique() && ((len >> 2) <= (fRec->fLength >> 2))) {
379 // Use less of the buffer we have without allocating a smaller one.
380 char* p = this->data();
381 p[len] = '\0';
382 fRec->fLength = SkToU32(len);
383 } else {
384 SkString newString(len);
385 char* dest = newString.data();
386 int copyLen = std::min<uint32_t>(len, this->size());
387 memcpy(dest, this->c_str(), copyLen);
388 dest[copyLen] = '\0';
389 this->swap(newString);
390 }
391}
392
393void SkString::set(const char text[]) {
394 this->set(text, text ? strlen(text) : 0);
395}
396
397void SkString::set(const char text[], size_t len) {
399 if (0 == len) {
400 this->reset();
401 } else if (fRec->unique() && ((len >> 2) <= (fRec->fLength >> 2))) {
402 // Use less of the buffer we have without allocating a smaller one.
403 char* p = this->data();
404 if (text) {
405 memcpy(p, text, len);
406 }
407 p[len] = '\0';
408 fRec->fLength = SkToU32(len);
409 } else {
410 SkString tmp(text, len);
411 this->swap(tmp);
412 }
413}
414
415void SkString::insert(size_t offset, const char text[]) {
416 this->insert(offset, text, text ? strlen(text) : 0);
417}
418
419void SkString::insert(size_t offset, const char text[], size_t len) {
420 if (len) {
421 size_t length = fRec->fLength;
422 if (offset > length) {
423 offset = length;
424 }
425
426 // Check if length + len exceeds 32bits, we trim len
428 if (0 == len) {
429 return;
430 }
431
432 /* If we're the only owner, and we have room in our allocation for the insert,
433 do it in place, rather than allocating a new buffer.
434
435 To know we have room, compare the allocated sizes
436 beforeAlloc = SkAlign4(length + 1)
437 afterAlloc = SkAligh4(length + 1 + len)
438 but SkAlign4(x) is (x + 3) >> 2 << 2
439 which is equivalent for testing to (length + 1 + 3) >> 2 == (length + 1 + 3 + len) >> 2
440 and we can then eliminate the +1+3 since that doesn't affec the answer
441 */
442 if (fRec->unique() && (length >> 2) == ((length + len) >> 2)) {
443 char* dst = this->data();
444
445 if (offset < length) {
446 memmove(dst + offset + len, dst + offset, length - offset);
447 }
448 memcpy(dst + offset, text, len);
449
450 dst[length + len] = 0;
451 fRec->fLength = SkToU32(length + len);
452 } else {
453 /* Seems we should use realloc here, since that is safe if it fails
454 (we have the original data), and might be faster than alloc/copy/free.
455 */
456 SkString tmp(fRec->fLength + len);
457 char* dst = tmp.data();
458
459 if (offset > 0) {
460 memcpy(dst, fRec->data(), offset);
461 }
462 memcpy(dst + offset, text, len);
463 if (offset < fRec->fLength) {
464 memcpy(dst + offset + len, fRec->data() + offset,
465 fRec->fLength - offset);
466 }
467
468 this->swap(tmp);
469 }
470 }
471}
472
475 size_t len = SkUTF::ToUTF8(uni, buffer);
476
477 if (len) {
478 this->insert(offset, buffer, len);
479 }
480}
481
482void SkString::insertS32(size_t offset, int32_t dec) {
484 char* stop = SkStrAppendS32(buffer, dec);
485 this->insert(offset, buffer, stop - buffer);
486}
487
488void SkString::insertS64(size_t offset, int64_t dec, int minDigits) {
490 char* stop = SkStrAppendS64(buffer, dec, minDigits);
491 this->insert(offset, buffer, stop - buffer);
492}
493
494void SkString::insertU32(size_t offset, uint32_t dec) {
496 char* stop = SkStrAppendU32(buffer, dec);
497 this->insert(offset, buffer, stop - buffer);
498}
499
500void SkString::insertU64(size_t offset, uint64_t dec, int minDigits) {
502 char* stop = SkStrAppendU64(buffer, dec, minDigits);
503 this->insert(offset, buffer, stop - buffer);
504}
505
506void SkString::insertHex(size_t offset, uint32_t hex, int minDigits) {
507 minDigits = SkTPin(minDigits, 0, 8);
508
509 char buffer[8];
510 char* p = buffer + sizeof(buffer);
511
512 do {
513 *--p = SkHexadecimalDigits::gUpper[hex & 0xF];
514 hex >>= 4;
515 minDigits -= 1;
516 } while (hex != 0);
517
518 while (--minDigits >= 0) {
519 *--p = '0';
520 }
521
522 SkASSERT(p >= buffer);
523 this->insert(offset, p, buffer + sizeof(buffer) - p);
524}
525
528 char* stop = SkStrAppendScalar(buffer, value);
529 this->insert(offset, buffer, stop - buffer);
530}
531
532///////////////////////////////////////////////////////////////////////////////
533
534void SkString::printf(const char format[], ...) {
535 va_list args;
537 this->printVAList(format, args);
538 va_end(args);
539}
540
541void SkString::printVAList(const char format[], va_list args) {
542 char stackBuffer[kBufferSize];
543 StringBuffer result = apply_format_string(format, args, stackBuffer, this);
544
545 if (result.fText == stackBuffer) {
546 this->set(result.fText, result.fLength);
547 }
548}
549
550void SkString::appendf(const char format[], ...) {
551 va_list args;
553 this->appendVAList(format, args);
554 va_end(args);
555}
556
557void SkString::appendVAList(const char format[], va_list args) {
558 if (this->isEmpty()) {
559 this->printVAList(format, args);
560 return;
561 }
562
563 SkString overflow;
564 char stackBuffer[kBufferSize];
565 StringBuffer result = apply_format_string(format, args, stackBuffer, &overflow);
566
567 this->append(result.fText, result.fLength);
568}
569
570void SkString::prependf(const char format[], ...) {
571 va_list args;
573 this->prependVAList(format, args);
574 va_end(args);
575}
576
577void SkString::prependVAList(const char format[], va_list args) {
578 if (this->isEmpty()) {
579 this->printVAList(format, args);
580 return;
581 }
582
583 SkString overflow;
584 char stackBuffer[kBufferSize];
585 StringBuffer result = apply_format_string(format, args, stackBuffer, &overflow);
586
587 this->prepend(result.fText, result.fLength);
588}
589
590///////////////////////////////////////////////////////////////////////////////
591
592void SkString::remove(size_t offset, size_t length) {
593 size_t size = this->size();
594
595 if (offset < size) {
596 if (length > size - offset) {
597 length = size - offset;
598 }
599 SkASSERT(length <= size);
601 if (length > 0) {
602 SkString tmp(size - length);
603 char* dst = tmp.data();
604 const char* src = this->c_str();
605
606 if (offset) {
607 memcpy(dst, src, offset);
608 }
609 size_t tail = size - (offset + length);
610 if (tail) {
611 memcpy(dst + offset, src + (offset + length), tail);
612 }
613 SkASSERT(dst[tmp.size()] == 0);
614 this->swap(tmp);
615 }
616 }
617}
618
620 this->validate();
621 other.validate();
622
623 using std::swap;
624 swap(fRec, other.fRec);
625}
626
627///////////////////////////////////////////////////////////////////////////////
628
629SkString SkStringPrintf(const char* format, ...) {
630 SkString formattedOutput;
631 va_list args;
633 formattedOutput.printVAList(format, args);
634 va_end(args);
635 return formattedOutput;
636}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_PRINTF_LIKE(A, B)
Definition: SkAttributes.h:52
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static constexpr bool SkIsNaN(T x)
static bool SkIsFinite(T x, Pack... values)
static int sk_careful_memcmp(const void *a, const void *b, size_t len)
Definition: SkMalloc.h:143
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
static size_t check_add32(size_t base, size_t extra)
Definition: SkString.cpp:206
char * SkStrAppendScalar(char string[], SkScalar value)
Definition: SkString.cpp:164
char * SkStrAppendU32(char string[], uint32_t dec)
Definition: SkString.cpp:100
SkString SkStringPrintf(const char *format,...)
Definition: SkString.cpp:629
char * SkStrAppendS64(char string[], int64_t dec, int minDigits)
Definition: SkString.cpp:155
static const size_t kBufferSize
Definition: SkString.cpp:27
char * SkStrAppendS32(char string[], int32_t dec)
Definition: SkString.cpp:120
bool SkStrEndsWith(const char string[], const char suffixStr[])
Definition: SkString.cpp:68
char * SkStrAppendU64(char string[], uint64_t dec, int minDigits)
Definition: SkString.cpp:129
#define SizeOfRec()
Definition: SkString.cpp:195
static uint32_t trim_size_t_to_u32(size_t value)
Definition: SkString.cpp:197
static StringBuffer apply_format_string(const char *format, va_list args, char(&stackBuffer)[SIZE], SkString *heapBuffer) SK_PRINTF_LIKE(1
int SkStrStartsWithOneOf(const char string[], const char prefixes[])
Definition: SkString.cpp:87
static constexpr int kSkStrAppendS32_MaxSize
Definition: SkString.h:89
static constexpr int kSkStrAppendS64_MaxSize
Definition: SkString.h:91
static constexpr int kSkStrAppendU32_MaxSize
Definition: SkString.h:84
static constexpr int kSkStrAppendScalar_MaxSize
Definition: SkString.h:101
static constexpr int kSkStrAppendU64_MaxSize
Definition: SkString.h:86
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
constexpr uint32_t SkToU32(S x)
Definition: SkTo.h:26
int32_t SkUnichar
Definition: SkTypes.h:175
size_t add(size_t x, size_t y)
Definition: SkSafeMath.h:33
size_t alignUp(size_t x, size_t alignment)
Definition: SkSafeMath.h:54
T castTo(size_t value)
Definition: SkSafeMath.h:59
bool ok() const
Definition: SkSafeMath.h:26
void insertScalar(size_t offset, SkScalar)
Definition: SkString.cpp:526
void insertUnichar(size_t offset, SkUnichar)
Definition: SkString.cpp:473
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:534
void void void void void void void remove(size_t offset, size_t length)
Definition: SkString.cpp:592
void insertU64(size_t offset, uint64_t value, int minDigits=0)
Definition: SkString.cpp:500
void void void void appendVAList(const char format[], va_list) SK_PRINTF_LIKE(2
Definition: SkString.cpp:557
size_t size() const
Definition: SkString.h:131
void void printVAList(const char format[], va_list) SK_PRINTF_LIKE(2
Definition: SkString.cpp:541
void void void void void void prependVAList(const char format[], va_list) SK_PRINTF_LIKE(2
Definition: SkString.cpp:577
void insertU32(size_t offset, uint32_t value)
Definition: SkString.cpp:494
const char * data() const
Definition: SkString.h:132
void insertS32(size_t offset, int32_t value)
Definition: SkString.cpp:482
void set(const SkString &src)
Definition: SkString.h:186
bool equals(const SkString &) const
Definition: SkString.cpp:324
bool isEmpty() const
Definition: SkString.h:130
void append(const char text[])
Definition: SkString.h:203
void swap(SkString &other)
Definition: SkString.cpp:619
void resize(size_t len)
Definition: SkString.cpp:374
void insert(size_t offset, const char text[])
Definition: SkString.cpp:415
SkString & operator=(const SkString &)
Definition: SkString.cpp:338
void reset()
Definition: SkString.cpp:358
void prepend(const char text[])
Definition: SkString.h:215
const char * c_str() const
Definition: SkString.h:133
void insertS64(size_t offset, int64_t value, int minDigits=0)
Definition: SkString.cpp:488
void void void void void prependf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:570
void insertHex(size_t offset, uint32_t value, int minDigits=0)
Definition: SkString.cpp:506
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:550
T * get() const
Definition: SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
float SkScalar
Definition: extension.cpp:12
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
GAsyncResult * result
uint32_t uint32_t * format
size_t length
std::u16string text
const char gUpper[16]
Definition: SkUtils.cpp:10
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
SK_SPI size_t ToUTF8(SkUnichar uni, char utf8[kMaxBytesInUTF8Sequence]=nullptr)
constexpr unsigned kMaxBytesInUTF8Sequence
Definition: SkUTF.h:59
va_start(args, format)
va_end(args)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
dst
Definition: cp.py:12
Definition: ref_ptr.h:256
dest
Definition: zip.py:79
#define SIZE
SeparatedVector2 offset
char * fText
Definition: SkString.cpp:30