Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SkXMLWriter.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
12
13SkXMLWriter::SkXMLWriter(bool doEscapeMarkup) : fDoEscapeMarkup(doEscapeMarkup)
14{}
15
17 SkASSERT(fElems.empty());
18}
19
21 while (!fElems.empty()) {
22 this->endElement();
23 }
24}
25
26void SkXMLWriter::addAttribute(const char name[], const char value[]) {
27 this->addAttributeLen(name, value, strlen(value));
28}
29
30void SkXMLWriter::addS32Attribute(const char name[], int32_t value) {
31 SkString tmp;
32 tmp.appendS32(value);
33 this->addAttribute(name, tmp.c_str());
34}
35
36void SkXMLWriter::addHexAttribute(const char name[], uint32_t value, int minDigits) {
37 SkString tmp("0x");
38 tmp.appendHex(value, minDigits);
39 this->addAttribute(name, tmp.c_str());
40}
41
43 SkString tmp;
45 this->addAttribute(name, tmp.c_str());
46}
47
48void SkXMLWriter::addText(const char text[], size_t length) {
49 if (fElems.empty()) {
50 return;
51 }
52
53 this->onAddText(text, length);
54
55 fElems.back()->fHasText = true;
56}
57
59 delete elem;
60}
61
62bool SkXMLWriter::doStart(const char name[], size_t length) {
63 int level = fElems.size();
64 bool firstChild = level > 0 && !fElems[level-1]->fHasChildren;
65 if (firstChild) {
66 fElems[level-1]->fHasChildren = true;
67 }
68 Elem** elem = fElems.append();
69 *elem = new Elem(name, length);
70 return firstChild;
71}
72
74 Elem* elem = fElems.back();
75 fElems.pop_back();
76 return elem;
77}
78
80 static const char gHeader[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
81 return gHeader;
82}
83
84void SkXMLWriter::startElement(const char name[]) {
85 this->startElementLen(name, strlen(name));
86}
87
88static const char* escape_char(char c, char storage[2]) {
89 static const char* gEscapeChars[] = {
90 "<&lt;",
91 ">&gt;",
92 //"\"&quot;",
93 //"'&apos;",
94 "&&amp;"
95 };
96
97 const char** array = gEscapeChars;
98 for (unsigned i = 0; i < std::size(gEscapeChars); i++) {
99 if (array[i][0] == c) {
100 return &array[i][1];
101 }
102 }
103 storage[0] = c;
104 storage[1] = 0;
105 return storage;
106}
107
108static size_t escape_markup(char dst[], const char src[], size_t length) {
109 size_t extra = 0;
110 const char* stop = src + length;
111
112 while (src < stop) {
113 char orig[2];
114 const char* seq = escape_char(*src, orig);
115 size_t seqSize = strlen(seq);
116
117 if (dst) {
118 memcpy(dst, seq, seqSize);
119 dst += seqSize;
120 }
121
122 // now record the extra size needed
123 extra += seqSize - 1; // minus one to subtract the original char
124
125 // bump to the next src char
126 src += 1;
127 }
128 return extra;
129}
130
131void SkXMLWriter::addAttributeLen(const char name[], const char value[], size_t length) {
132 SkString valueStr;
133
134 if (fDoEscapeMarkup) {
135 size_t extra = escape_markup(nullptr, value, length);
136 if (extra) {
137 valueStr.resize(length + extra);
138 (void)escape_markup(valueStr.data(), value, length);
139 value = valueStr.c_str();
140 length += extra;
141 }
142 }
143 this->onAddAttributeLen(name, value, length);
144}
145
146void SkXMLWriter::startElementLen(const char elem[], size_t length) {
147 this->onStartElementLen(elem, length);
148}
149
150////////////////////////////////////////////////////////////////////////////////////////
151
152static void write_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLWriter* w, bool skipRoot) {
153 if (!skipRoot) {
154 const char* elem = dom.getName(node);
155 if (dom.getType(node) == SkDOM::kText_Type) {
156 SkASSERT(dom.countChildren(node) == 0);
157 w->addText(elem, strlen(elem));
158 return;
159 }
160
161 w->startElement(elem);
162
163 SkDOM::AttrIter iter(dom, node);
164 const char* name;
165 const char* value;
166 while ((name = iter.next(&value)) != nullptr) {
167 w->addAttribute(name, value);
168 }
169 }
170
171 node = dom.getFirstChild(node, nullptr);
172 while (node) {
173 write_dom(dom, node, w, false);
174 node = dom.getNextSibling(node, nullptr);
175 }
176
177 if (!skipRoot) {
178 w->endElement();
179 }
180}
181
182void SkXMLWriter::writeDOM(const SkDOM& dom, const SkDOM::Node* node, bool skipRoot) {
183 if (node) {
184 write_dom(dom, node, this, skipRoot);
185 }
186}
187
189{}
190
191// SkXMLStreamWriter
192
194 : fStream(*stream)
195 , fFlags(flags) {}
196
198 this->flush();
199}
200
201void SkXMLStreamWriter::onAddAttributeLen(const char name[], const char value[], size_t length) {
202 SkASSERT(!fElems.back()->fHasChildren && !fElems.back()->fHasText);
203 fStream.writeText(" ");
204 fStream.writeText(name);
205 fStream.writeText("=\"");
206 fStream.write(value, length);
207 fStream.writeText("\"");
208}
209
210void SkXMLStreamWriter::onAddText(const char text[], size_t length) {
211 Elem* elem = fElems.back();
212
213 if (!elem->fHasChildren && !elem->fHasText) {
214 fStream.writeText(">");
215 this->newline();
216 }
217
218 this->tab(fElems.size() + 1);
219 fStream.write(text, length);
220 this->newline();
221}
222
224 Elem* elem = getEnd();
225 if (elem->fHasChildren || elem->fHasText) {
226 this->tab(fElems.size());
227 fStream.writeText("</");
228 fStream.writeText(elem->fName.c_str());
229 fStream.writeText(">");
230 } else {
231 fStream.writeText("/>");
232 }
233 this->newline();
234 doEnd(elem);
235}
236
238 int level = fElems.size();
239 if (this->doStart(name, length)) {
240 // the first child, need to close with >
241 fStream.writeText(">");
242 this->newline();
243 }
244
245 this->tab(level);
246 fStream.writeText("<");
247 fStream.write(name, length);
248}
249
251 const char* header = getHeader();
252 fStream.write(header, strlen(header));
253 this->newline();
254}
255
256void SkXMLStreamWriter::newline() {
257 if (!(fFlags & kNoPretty_Flag)) {
258 fStream.newline();
259 }
260}
261
262void SkXMLStreamWriter::tab(int level) {
263 if (!(fFlags & kNoPretty_Flag)) {
264 for (int i = 0; i < level; i++) {
265 fStream.writeText("\t");
266 }
267 }
268}
269
270////////////////////////////////////////////////////////////////////////////////////////////////
271
272#include "src/xml/SkXMLParser.h"
273
275 : SkXMLWriter(false), fParser(*parser)
276{
277}
278
280 this->flush();
281}
282
283void SkXMLParserWriter::onAddAttributeLen(const char name[], const char value[], size_t length) {
284 SkASSERT(fElems.empty() || (!fElems.back()->fHasChildren && !fElems.back()->fHasText));
285 SkString str(value, length);
286 fParser.addAttribute(name, str.c_str());
287}
288
289void SkXMLParserWriter::onAddText(const char text[], size_t length) {
290 fParser.text(text, SkToInt(length));
291}
292
294 Elem* elem = this->getEnd();
295 fParser.endElement(elem->fName.c_str());
296 this->doEnd(elem);
297}
298
300 (void)this->doStart(name, length);
301 SkString str(name, length);
302 fParser.startElement(str.c_str());
303}
uint16_t fFlags
Definition: ShapeLayer.cpp:106
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr int SkToInt(S x)
Definition: SkTo.h:29
static size_t escape_markup(char dst[], const char src[], size_t length)
static const char * escape_char(char c, char storage[2])
Definition: SkXMLWriter.cpp:88
static void write_dom(const SkDOM &dom, const SkDOM::Node *node, SkXMLWriter *w, bool skipRoot)
const char * next(const char **value)
Definition: SkDOM.cpp:165
Definition: SkDOM.h:24
@ kText_Type
Definition: SkDOM.h:44
const char * data() const
Definition: SkString.h:132
void appendHex(uint32_t value, int minDigits=0)
Definition: SkString.h:212
void appendS32(int32_t value)
Definition: SkString.h:208
void resize(size_t len)
Definition: SkString.cpp:374
void appendScalar(SkScalar value)
Definition: SkString.h:213
const char * c_str() const
Definition: SkString.h:133
virtual bool write(const void *buffer, size_t size)=0
bool writeText(const char text[])
Definition: SkStream.h:247
bool newline()
Definition: SkStream.h:252
void onEndElement() override
SkXMLParserWriter(SkXMLParser *)
void onAddText(const char text[], size_t length) override
void onAddAttributeLen(const char name[], const char value[], size_t length) override
~SkXMLParserWriter() override
void onStartElementLen(const char elem[], size_t length) override
bool startElement(const char elem[])
bool endElement(const char elem[])
bool addAttribute(const char name[], const char value[])
bool text(const char text[], int len)
~SkXMLStreamWriter() override
void onStartElementLen(const char elem[], size_t length) override
void onEndElement() override
SkXMLStreamWriter(SkWStream *, uint32_t flags=0)
void onAddText(const char text[], size_t length) override
void writeHeader() override
void onAddAttributeLen(const char name[], const char value[], size_t length) override
virtual ~SkXMLWriter()
Definition: SkXMLWriter.cpp:16
virtual void onStartElementLen(const char elem[], size_t length)=0
void addText(const char text[], size_t length)
Definition: SkXMLWriter.cpp:48
void writeDOM(const SkDOM &, const SkDOM::Node *, bool skipRoot)
void addAttributeLen(const char name[], const char value[], size_t length)
void addHexAttribute(const char name[], uint32_t value, int minDigits=0)
Definition: SkXMLWriter.cpp:36
const char * getHeader()
Definition: SkXMLWriter.cpp:79
void doEnd(Elem *elem)
Definition: SkXMLWriter.cpp:58
void flush()
Definition: SkXMLWriter.cpp:20
virtual void onAddText(const char text[], size_t length)=0
void addScalarAttribute(const char name[], SkScalar value)
Definition: SkXMLWriter.cpp:42
SkXMLWriter(bool doEscapeMarkup=true)
Definition: SkXMLWriter.cpp:13
Elem * getEnd()
Definition: SkXMLWriter.cpp:73
void addS32Attribute(const char name[], int32_t value)
Definition: SkXMLWriter.cpp:30
SkTDArray< Elem * > fElems
Definition: SkXMLWriter.h:56
void addAttribute(const char name[], const char value[])
Definition: SkXMLWriter.cpp:26
virtual void onAddAttributeLen(const char name[], const char value[], size_t length)=0
virtual void writeHeader()
bool doStart(const char name[], size_t length)
Definition: SkXMLWriter.cpp:62
void endElement()
Definition: SkXMLWriter.h:29
void startElement(const char elem[])
Definition: SkXMLWriter.cpp:84
void startElementLen(const char elem[], size_t length)
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
uint8_t value
size_t length
std::u16string text
Definition: dom.py:1
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
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
Definition: switches.h:259
dst
Definition: cp.py:12
parser
Definition: zip.py:78
SkScalar w
static const char header[]
Definition: skpbench.cpp:88