1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/* 3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2006 The Android Open Source Project 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */ 8685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkXMLWriter.h" 11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkStream.h" 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLWriter::SkXMLWriter(bool doEscapeMarkup) : fDoEscapeMarkup(doEscapeMarkup) 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 15bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLWriter::~SkXMLWriter() 18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 19bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fElems.count() == 0); 20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::flush() 23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while (fElems.count()) 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->endElement(); 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::addAttribute(const char name[], const char value[]) 29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->addAttributeLen(name, value, strlen(value)); 31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::addS32Attribute(const char name[], int32_t value) 34bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString tmp; 36bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com tmp.appendS32(value); 37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->addAttribute(name, tmp.c_str()); 38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 39bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::addHexAttribute(const char name[], uint32_t value, int minDigits) 41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString tmp("0x"); 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com tmp.appendHex(value, minDigits); 44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->addAttribute(name, tmp.c_str()); 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::addScalarAttribute(const char name[], SkScalar value) 48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString tmp; 50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com tmp.appendScalar(value); 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->addAttribute(name, tmp.c_str()); 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::doEnd(Elem* elem) 55bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 56bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com delete elem; 57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkXMLWriter::doStart(const char name[], size_t length) 60bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 61bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int level = fElems.count(); 62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool firstChild = level > 0 && !fElems[level-1]->fHasChildren; 63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (firstChild) 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fElems[level-1]->fHasChildren = true; 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com Elem** elem = fElems.push(); 66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *elem = new Elem; 67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (*elem)->fName.set(name, length); 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (*elem)->fHasChildren = 0; 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return firstChild; 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 72dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.comSkXMLWriter::Elem* SkXMLWriter::getEnd() 73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 74bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com Elem* elem; 75bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fElems.pop(&elem); 76bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return elem; 77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comconst char* SkXMLWriter::getHeader() 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static const char gHeader[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"; 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return gHeader; 83bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 84bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::startElement(const char name[]) 86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->startElementLen(name, strlen(name)); 88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic const char* escape_char(char c, char storage[2]) 91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 92bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static const char* gEscapeChars[] = { 93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com "<<", 94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com ">>", 95bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com //"\""", 96bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com //"''", 97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com "&&" 98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com }; 99bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 100bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char** array = gEscapeChars; 101bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (unsigned i = 0; i < SK_ARRAY_COUNT(gEscapeChars); i++) 102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (array[i][0] == c) 104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return &array[i][1]; 105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[0] = c; 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com storage[1] = 0; 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return storage; 109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic size_t escape_markup(char dst[], const char src[], size_t length) 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t extra = 0; 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* stop = src + length; 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while (src < stop) 117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com char orig[2]; 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* seq = escape_char(*src, orig); 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t seqSize = strlen(seq); 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (dst) 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com memcpy(dst, seq, seqSize); 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com dst += seqSize; 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // now record the extra size needed 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com extra += seqSize - 1; // minus one to subtract the original char 130bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 131bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // bump to the next src char 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com src += 1; 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return extra; 135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::addAttributeLen(const char name[], const char value[], size_t length) 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString valueStr; 140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fDoEscapeMarkup) 142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 143bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com size_t extra = escape_markup(NULL, value, length); 144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (extra) 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com valueStr.resize(length + extra); 147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (void)escape_markup(valueStr.writable_str(), value, length); 148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com value = valueStr.c_str(); 149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com length += extra; 150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->onAddAttributeLen(name, value, length); 153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::startElementLen(const char elem[], size_t length) 156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->onStartElementLen(elem, length); 158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 160bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////////////////////// 161bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic void write_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLWriter* w, bool skipRoot) 163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 164bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (!skipRoot) 165bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w->startElement(dom.getName(node)); 167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDOM::AttrIter iter(dom, node); 169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* name; 170bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* value; 171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while ((name = iter.next(&value)) != NULL) 172bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w->addAttribute(name, value); 173bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 174bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 175bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com node = dom.getFirstChild(node, NULL); 176bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while (node) 177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com write_dom(dom, node, w, false); 179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com node = dom.getNextSibling(node, NULL); 180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 181bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (!skipRoot) 183bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w->endElement(); 184bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 185bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::writeDOM(const SkDOM& dom, const SkDOM::Node* node, bool skipRoot) 187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (node) 189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com write_dom(dom, node, this, skipRoot); 190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLWriter::writeHeader() 193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com// SkXMLStreamWriter 197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic void tab(SkWStream& stream, int level) 199bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 200bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (int i = 0; i < level; i++) 201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com stream.writeText("\t"); 202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLStreamWriter::SkXMLStreamWriter(SkWStream* stream) : fStream(*stream) 205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLStreamWriter::~SkXMLStreamWriter() 209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 210bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->flush(); 211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLStreamWriter::onAddAttributeLen(const char name[], const char value[], size_t length) 214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(!fElems.top()->fHasChildren); 216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText(" "); 217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText(name); 218bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText("=\""); 219bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.write(value, length); 220bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText("\""); 221bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 223bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLStreamWriter::onEndElement() 224bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com Elem* elem = getEnd(); 226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (elem->fHasChildren) 227bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com tab(fStream, fElems.count()); 229bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText("</"); 230bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText(elem->fName.c_str()); 231bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText(">"); 232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com else 234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText("/>"); 235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.newline(); 236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com doEnd(elem); 237bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 238bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLStreamWriter::onStartElementLen(const char name[], size_t length) 240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int level = fElems.count(); 242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (this->doStart(name, length)) 243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // the first child, need to close with > 245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText(">"); 246bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.newline(); 247bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com tab(fStream, level); 250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.writeText("<"); 251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.write(name, length); 252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLStreamWriter::writeHeader() 255bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 256bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com const char* header = getHeader(); 257bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.write(header, strlen(header)); 258bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fStream.newline(); 259bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 260bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 261bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////////////////////////////// 262bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 263bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkXMLParser.h" 264bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 265bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLParserWriter::SkXMLParserWriter(SkXMLParser* parser) 266bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com : SkXMLWriter(false), fParser(*parser) 267bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 268bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 269bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 270bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkXMLParserWriter::~SkXMLParserWriter() 271bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 272bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->flush(); 273bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 274bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 275bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLParserWriter::onAddAttributeLen(const char name[], const char value[], size_t length) 276bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fElems.count() == 0 || !fElems.top()->fHasChildren); 278bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString str(value, length); 279bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fParser.addAttribute(name, str.c_str()); 280bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 281bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 282bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLParserWriter::onEndElement() 283bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 284bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com Elem* elem = this->getEnd(); 285bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fParser.endElement(elem->fName.c_str()); 286bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->doEnd(elem); 287bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 288bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 289bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLParserWriter::onStartElementLen(const char name[], size_t length) 290bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 291bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (void)this->doStart(name, length); 292bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkString str(name, length); 293bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fParser.startElement(str.c_str()); 294bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 295bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 296bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 297bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////////////////////// 298bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////////////////////// 299bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 300bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG 301bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 302bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkXMLStreamWriter::UnitTest() 303bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 304bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_SUPPORT_UNITTEST 305bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkDebugWStream s; 306bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkXMLStreamWriter w(&s); 307bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 308bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem0"); 309bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addAttribute("hello", "world"); 310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addS32Attribute("dec", 42); 311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addHexAttribute("hex", 0x42, 3); 312bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_SCALAR_IS_FLOAT 313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addScalarAttribute("scalar", -4.2f); 314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 315bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem1"); 316bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 317bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem1"); 318bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addAttribute("name", "value"); 319bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 320bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem1"); 321bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem2"); 322bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem3"); 323bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.addAttribute("name", "value"); 324bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.startElement("elem2"); 327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 329bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com w.endElement(); 330bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 331bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 332bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 333bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif 334