SkDOM.cpp revision 852f15da7ceb53cfb49b9f728baa6dbc53b27694
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 "SkDOM.h" 117a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita#include "SkStream.h" 127a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita#include "SkXMLWriter.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////// 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXMLParser.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkXMLParser::parse(const SkDOM& dom, const SkDOMNode* node) 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* elemName = dom.getName(node); 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->startElement(elemName)) 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 23d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::AttrIter iter(dom, node); 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name, *value; 26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 2796fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((name = iter.next(&value)) != nullptr) 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->addAttribute(name, value)) 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if ((node = dom.getFirstChild(node)) != nullptr) 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->parse(dom, node)) 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3596fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((node = dom.getNextSibling(node)) != nullptr); 36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !this->endElement(elemName); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////// 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkDOMAttr { 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fValue; 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkDOMNode { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMNode* fFirstChild; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMNode* fNextSibling; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t fAttrCount; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint8_t fType; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint8_t fPad; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkDOMAttr* attrs() const 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (const SkDOMAttr*)(this + 1); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMAttr* attrs() 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkDOMAttr*)(this + 1); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////// 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kMinChunkSize 512 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6996fcdcc219d2a0d3579719b84b28bede76efba64halcanarySkDOM::SkDOM() : fAlloc(kMinChunkSize), fRoot(nullptr) 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDOM::~SkDOM() 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Node* SkDOM::getRootNode() const 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fRoot; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Node* SkDOM::getFirstChild(const Node* node, const char name[]) const 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Node* child = node->fFirstChild; 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (name) 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 8996fcdcc219d2a0d3579719b84b28bede76efba64halcanary for (; child != nullptr; child = child->fNextSibling) 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!strcmp(name, child->fName)) 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return child; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Node* SkDOM::getNextSibling(const Node* node, const char name[]) const 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Node* sibling = node->fNextSibling; 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (name) 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 10296fcdcc219d2a0d3579719b84b28bede76efba64halcanary for (; sibling != nullptr; sibling = sibling->fNextSibling) 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!strcmp(name, sibling->fName)) 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return sibling; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDOM::Type SkDOM::getType(const Node* node) const 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (Type)node->fType; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkDOM::getName(const Node* node) const 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return node->fName; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkDOM::findAttr(const Node* node, const char name[]) const 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Attr* attr = node->attrs(); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Attr* stop = attr + node->fAttrCount; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (attr < stop) 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!strcmp(attr->fName, name)) 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return attr->fValue; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com attr += 1; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////// 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Attr* SkDOM::getFirstAttr(const Node* node) const 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 14096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return node->fAttrCount ? node->attrs() : nullptr; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Attr* SkDOM::getNextAttr(const Node* node, const Attr* attr) const 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 14696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (attr == nullptr) 14796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 14896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return (attr - node->attrs() + 1) < node->fAttrCount ? attr + 1 : nullptr; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkDOM::getAttrName(const Node* node, const Attr* attr) const 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(attr); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return attr->fName; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkDOM::getAttrValue(const Node* node, const Attr* attr) const 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(attr); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return attr->fValue; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////// 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDOM::AttrIter::AttrIter(const SkDOM&, const SkDOM::Node* node) 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(node); 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAttr = node->attrs(); 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = fAttr + node->fAttrCount; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkDOM::AttrIter::next(const char** value) 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 17696fcdcc219d2a0d3579719b84b28bede76efba64halcanary const char* name = nullptr; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fAttr < fStop) 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com name = fAttr->fName; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (value) 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fAttr->fValue; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAttr += 1; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return name; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXMLParser.h" 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h" 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic char* dupstr(SkChunkAlloc* chunk, const char src[]) 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(chunk && src); 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t len = strlen(src); 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* dst = (char*)chunk->alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType); 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(dst, src, len + 1); 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDOMParser : public SkXMLParser { 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMParser(SkChunkAlloc* chunk) : SkXMLParser(&fParserError), fAlloc(chunk) 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2067a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita fAlloc->reset(); 20796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fRoot = nullptr; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLevel = 0; 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNeedToFlush = true; 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* getRoot() const { return fRoot; } 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkXMLParserError fParserError; 2137a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void flushAttributes() 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2177a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkASSERT(fLevel > 0); 2187a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int attrCount = fAttrs.count(); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* node = (SkDOM::Node*)fAlloc->alloc(sizeof(SkDOM::Node) + attrCount * sizeof(SkDOM::Attr), 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkChunkAlloc::kThrow_AllocFailType); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node->fName = fElemName; 22596fcdcc219d2a0d3579719b84b28bede76efba64halcanary node->fFirstChild = nullptr; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node->fAttrCount = SkToU16(attrCount); 2277a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita node->fType = fElemType; 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fRoot == nullptr) 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 23196fcdcc219d2a0d3579719b84b28bede76efba64halcanary node->fNextSibling = nullptr; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRoot = node; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else // this adds siblings in reverse order. gets corrected in onEndElement() 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* parent = fParentStack.top(); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fRoot && parent); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node->fNextSibling = parent->fFirstChild; 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parent->fFirstChild = node; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fParentStack.push() = node; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 243067e90e72fdeba83eff7aeb917b2b25f74759282mtklein sk_careful_memcpy(node->attrs(), fAttrs.begin(), attrCount * sizeof(SkDOM::Attr)); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAttrs.reset(); 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2477a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2487a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita bool onStartElement(const char elem[]) override { 2497a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita this->startCommon(elem, SkDOM::kElement_Type); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2527a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2537a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita bool onAddAttribute(const char name[], const char value[]) override { 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Attr* attr = fAttrs.append(); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com attr->fName = dupstr(fAlloc, name); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com attr->fValue = dupstr(fAlloc, value); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2597a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2607a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita bool onEndElement(const char elem[]) override { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com --fLevel; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fNeedToFlush) 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->flushAttributes(); 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNeedToFlush = false; 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* parent; 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParentStack.pop(&parent); 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* child = parent->fFirstChild; 27196fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkDOM::Node* prev = nullptr; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (child) 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::Node* next = child->fNextSibling; 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com child->fNextSibling = prev; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev = child; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com child = next; 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parent->fFirstChild = prev; 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2827a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2837a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita bool onText(const char text[], int len) override { 2847a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkString str(text, len); 2857a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita this->startCommon(str.c_str(), SkDOM::kText_Type); 2867a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita this->SkDOMParser::onEndElement(str.c_str()); 2877a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2887a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita return false; 2897a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita } 2907a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2927a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita void startCommon(const char elem[], SkDOM::Type type) { 2937a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita if (fLevel > 0 && fNeedToFlush) 2947a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita this->flushAttributes(); 2957a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 2967a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita fNeedToFlush = true; 2977a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita fElemName = dupstr(fAlloc, elem); 2987a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita fElemType = type; 2997a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita ++fLevel; 3007a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita } 3017a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<SkDOM::Node*> fParentStack; 3037a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkChunkAlloc* fAlloc; 3047a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkDOM::Node* fRoot; 3057a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita bool fNeedToFlush; 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // state needed for flushAttributes() 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<SkDOM::Attr> fAttrs; 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* fElemName; 3107a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkDOM::Type fElemType; 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fLevel; 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Node* SkDOM::build(const char doc[], size_t len) 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMParser parser(&fAlloc); 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!parser.parse(doc, len)) 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(SkDebugf("xml parse error, line %d\n", parser.fParserError.getLineNumber());) 32096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fRoot = nullptr; 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fAlloc.reset(); 32296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRoot = parser.getRoot(); 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fRoot; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////// 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void walk_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLParser* parser) 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* elem = dom.getName(node); 3337a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita if (dom.getType(node) == SkDOM::kText_Type) { 3347a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkASSERT(dom.countChildren(node) == 0); 3357a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita parser->text(elem, SkToInt(strlen(elem))); 3367a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita return; 3377a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita } 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parser->startElement(elem); 340d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM::AttrIter iter(dom, node); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name; 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* value; 34496fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((name = iter.next(&value)) != nullptr) 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parser->addAttribute(name, value); 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34796fcdcc219d2a0d3579719b84b28bede76efba64halcanary node = dom.getFirstChild(node, nullptr); 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (node) 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com walk_dom(dom, node, parser); 35196fcdcc219d2a0d3579719b84b28bede76efba64halcanary node = dom.getNextSibling(node, nullptr); 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parser->endElement(elem); 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkDOM::Node* SkDOM::copy(const SkDOM& dom, const SkDOM::Node* node) 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOMParser parser(&fAlloc); 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com walk_dom(dom, node, &parser); 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRoot = parser.getRoot(); 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fRoot; 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3677a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalitaSkXMLParser* SkDOM::beginParsing() { 3687a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkASSERT(!fParser); 369385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fParser.reset(new SkDOMParser(&fAlloc)); 3707a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 3717a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita return fParser.get(); 3727a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita} 3737a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 3747a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalitaconst SkDOM::Node* SkDOM::finishParsing() { 3757a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkASSERT(fParser); 3767a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita fRoot = fParser->getRoot(); 377852f15da7ceb53cfb49b9f728baa6dbc53b27694mtklein fParser.reset(); 3787a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 3797a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita return fRoot; 3807a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita} 3817a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////// 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkDOM::countChildren(const Node* node, const char elem[]) const 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node = this->getFirstChild(node, elem); 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (node) 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count += 1; 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node = this->getNextSibling(node, elem); 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////// 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkParse.h" 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::findS32(const Node* node, const char name[], int32_t* value) const 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindS32(vstr, value); 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::findScalars(const Node* node, const char name[], SkScalar value[], int count) const 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindScalars(vstr, value, count); 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::findHex(const Node* node, const char name[], uint32_t* value) const 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindHex(vstr, value); 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::findBool(const Node* node, const char name[], bool* value) const 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindBool(vstr, value); 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkDOM::findList(const Node* node, const char name[], const char list[]) const 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr ? SkParse::FindList(vstr, list) : -1; 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::hasAttr(const Node* node, const char name[], const char value[]) const 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && !strcmp(vstr, value); 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::hasS32(const Node* node, const char name[], int32_t target) const 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t value; 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindS32(vstr, &value) && value == target; 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::hasScalar(const Node* node, const char name[], SkScalar target) const 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar value; 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindScalar(vstr, &value) && value == target; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::hasHex(const Node* node, const char name[], uint32_t target) const 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t value; 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindHex(vstr, &value) && value == target; 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDOM::hasBool(const Node* node, const char name[], bool target) const 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* vstr = this->findAttr(node, name); 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool value; 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return vstr && SkParse::FindBool(vstr, &value) && value == target; 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////// 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDOM::dump(const Node* node, int level) const 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 47196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (node == nullptr) 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com node = this->getRootNode(); 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4747a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkDebugWStream debugStream; 4757a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita SkXMLStreamWriter xmlWriter(&debugStream); 4767a048690d3cb6b3c1bdef594c3bd4b66f6b400c1fmalita xmlWriter.writeDOM(*this, node, false); 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDOM::UnitTest() 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_SUPPORT_UNITTEST 482d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com static const char gDoc[] = 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<root a='1' b='2'>" 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<elem1 c='3' />" 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<elem2 d='4' />" 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<elem3 e='5'>" 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<subelem1/>" 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<subelem2 f='6' g='7'/>" 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</elem3>" 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "<elem4 h='8'/>" 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "</root>" 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ; 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDOM dom; 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 49696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(dom.getRootNode() == nullptr); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const Node* root = dom.build(gDoc, sizeof(gDoc) - 1); 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(root && dom.getRootNode() == root); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* v = dom.findAttr(root, "a"); 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(v && !strcmp(v, "1")); 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v = dom.findAttr(root, "b"); 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(v && !strcmp(v, "2")); 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com v = dom.findAttr(root, "c"); 50696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(v == nullptr); 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(dom.getFirstChild(root, "elem1")); 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!dom.getFirstChild(root, "subelem1")); 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dom.dump(); 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 516