1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXMLWriter.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLWriter::SkXMLWriter(bool doEscapeMarkup) : fDoEscapeMarkup(doEscapeMarkup) 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLWriter::~SkXMLWriter() 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fElems.count() == 0); 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::flush() 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fElems.count()) 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->endElement(); 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::addAttribute(const char name[], const char value[]) 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addAttributeLen(name, value, strlen(value)); 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::addS32Attribute(const char name[], int32_t value) 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString tmp; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.appendS32(value); 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addAttribute(name, tmp.c_str()); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::addHexAttribute(const char name[], uint32_t value, int minDigits) 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString tmp("0x"); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.appendHex(value, minDigits); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addAttribute(name, tmp.c_str()); 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::addScalarAttribute(const char name[], SkScalar value) 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString tmp; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.appendScalar(value); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addAttribute(name, tmp.c_str()); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::doEnd(Elem* elem) 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete elem; 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkXMLWriter::doStart(const char name[], size_t length) 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int level = fElems.count(); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool firstChild = level > 0 && !fElems[level-1]->fHasChildren; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (firstChild) 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fElems[level-1]->fHasChildren = true; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Elem** elem = fElems.push(); 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *elem = new Elem; 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (*elem)->fName.set(name, length); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (*elem)->fHasChildren = 0; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return firstChild; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comSkXMLWriter::Elem* SkXMLWriter::getEnd() 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Elem* elem; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fElems.pop(&elem); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return elem; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkXMLWriter::getHeader() 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const char gHeader[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gHeader; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::startElement(const char name[]) 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->startElementLen(name, strlen(name)); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* escape_char(char c, char storage[2]) 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const char* gEscapeChars[] = { 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<<", 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ">>", 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //"\""", 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //"''", 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "&&" 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char** array = gEscapeChars; 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (unsigned i = 0; i < SK_ARRAY_COUNT(gEscapeChars); i++) 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (array[i][0] == c) 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return &array[i][1]; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage[0] = c; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com storage[1] = 0; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return storage; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic size_t escape_markup(char dst[], const char src[], size_t length) 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t extra = 0; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = src + length; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (src < stop) 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char orig[2]; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* seq = escape_char(*src, orig); 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t seqSize = strlen(seq); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (dst) 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(dst, seq, seqSize); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst += seqSize; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now record the extra size needed 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com extra += seqSize - 1; // minus one to subtract the original char 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // bump to the next src char 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src += 1; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return extra; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::addAttributeLen(const char name[], const char value[], size_t length) 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString valueStr; 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDoEscapeMarkup) 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t extra = escape_markup(NULL, value, length); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (extra) 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com valueStr.resize(length + extra); 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)escape_markup(valueStr.writable_str(), value, length); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value = valueStr.c_str(); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com length += extra; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->onAddAttributeLen(name, value, length); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::startElementLen(const char elem[], size_t length) 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->onStartElementLen(elem, length); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////// 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void write_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLWriter* w, bool skipRoot) 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!skipRoot) 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w->startElement(dom.getName(node)); 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::AttrIter iter(dom, node); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* value; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((name = iter.next(&value)) != NULL) 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w->addAttribute(name, value); 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node = dom.getFirstChild(node, NULL); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (node) 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com write_dom(dom, node, w, false); 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node = dom.getNextSibling(node, NULL); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!skipRoot) 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w->endElement(); 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::writeDOM(const SkDOM& dom, const SkDOM::Node* node, bool skipRoot) 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (node) 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com write_dom(dom, node, this, skipRoot); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLWriter::writeHeader() 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// SkXMLStreamWriter 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void tab(SkWStream& stream, int level) 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < level; i++) 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream.writeText("\t"); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLStreamWriter::SkXMLStreamWriter(SkWStream* stream) : fStream(*stream) 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLStreamWriter::~SkXMLStreamWriter() 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->flush(); 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLStreamWriter::onAddAttributeLen(const char name[], const char value[], size_t length) 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!fElems.top()->fHasChildren); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText(" "); 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText(name); 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText("=\""); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.write(value, length); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText("\""); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLStreamWriter::onEndElement() 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Elem* elem = getEnd(); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (elem->fHasChildren) 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tab(fStream, fElems.count()); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText("</"); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText(elem->fName.c_str()); 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText(">"); 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText("/>"); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.newline(); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com doEnd(elem); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLStreamWriter::onStartElementLen(const char name[], size_t length) 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int level = fElems.count(); 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->doStart(name, length)) 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the first child, need to close with > 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText(">"); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.newline(); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tab(fStream, level); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.writeText("<"); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.write(name, length); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLStreamWriter::writeHeader() 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* header = getHeader(); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.write(header, strlen(header)); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream.newline(); 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////////////// 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXMLParser.h" 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLParserWriter::SkXMLParserWriter(SkXMLParser* parser) 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkXMLWriter(false), fParser(*parser) 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkXMLParserWriter::~SkXMLParserWriter() 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->flush(); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLParserWriter::onAddAttributeLen(const char name[], const char value[], size_t length) 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fElems.count() == 0 || !fElems.top()->fHasChildren); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString str(value, length); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParser.addAttribute(name, str.c_str()); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLParserWriter::onEndElement() 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Elem* elem = this->getEnd(); 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParser.endElement(elem->fName.c_str()); 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->doEnd(elem); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLParserWriter::onStartElementLen(const char name[], size_t length) 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)this->doStart(name, length); 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString str(name, length); 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParser.startElement(str.c_str()); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////// 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////// 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkXMLStreamWriter::UnitTest() 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_SUPPORT_UNITTEST 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugWStream s; 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXMLStreamWriter w(&s); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem0"); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addAttribute("hello", "world"); 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addS32Attribute("dec", 42); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addHexAttribute("hex", 0x42, 3); 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addScalarAttribute("scalar", -4.2f); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem1"); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem1"); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addAttribute("name", "value"); 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem1"); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem2"); 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem3"); 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.addAttribute("name", "value"); 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.startElement("elem2"); 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com w.endElement(); 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 332