| Index: src/xml/SkDOM.cpp
|
| diff --git a/src/xml/SkDOM.cpp b/src/xml/SkDOM.cpp
|
| index 98546089fa287ccc389b327000fdd5323f74b829..eb1bc092fecb9e1f9f7a1397873d14da56ff0617 100644
|
| --- a/src/xml/SkDOM.cpp
|
| +++ b/src/xml/SkDOM.cpp
|
| @@ -8,11 +8,12 @@
|
|
|
|
|
| #include "SkDOM.h"
|
| +#include "SkStream.h"
|
| +#include "SkXMLWriter.h"
|
|
|
| /////////////////////////////////////////////////////////////////////////
|
|
|
| #include "SkXMLParser.h"
|
| -
|
| bool SkXMLParser::parse(const SkDOM& dom, const SkDOMNode* node)
|
| {
|
| const char* elemName = dom.getName(node);
|
| @@ -199,19 +200,22 @@ static char* dupstr(SkChunkAlloc* chunk, const char src[])
|
| }
|
|
|
| class SkDOMParser : public SkXMLParser {
|
| - bool fNeedToFlush;
|
| public:
|
| SkDOMParser(SkChunkAlloc* chunk) : SkXMLParser(&fParserError), fAlloc(chunk)
|
| {
|
| + fAlloc->reset();
|
| fRoot = NULL;
|
| fLevel = 0;
|
| fNeedToFlush = true;
|
| }
|
| SkDOM::Node* getRoot() const { return fRoot; }
|
| SkXMLParserError fParserError;
|
| +
|
| protected:
|
| void flushAttributes()
|
| {
|
| + SkASSERT(fLevel > 0);
|
| +
|
| int attrCount = fAttrs.count();
|
|
|
| SkDOM::Node* node = (SkDOM::Node*)fAlloc->alloc(sizeof(SkDOM::Node) + attrCount * sizeof(SkDOM::Attr),
|
| @@ -220,7 +224,7 @@ protected:
|
| node->fName = fElemName;
|
| node->fFirstChild = NULL;
|
| node->fAttrCount = SkToU16(attrCount);
|
| - node->fType = SkDOM::kElement_Type;
|
| + node->fType = fElemType;
|
|
|
| if (fRoot == NULL)
|
| {
|
| @@ -240,24 +244,20 @@ protected:
|
| fAttrs.reset();
|
|
|
| }
|
| - virtual bool onStartElement(const char elem[])
|
| - {
|
| - if (fLevel > 0 && fNeedToFlush)
|
| - this->flushAttributes();
|
| - fNeedToFlush = true;
|
| - fElemName = dupstr(fAlloc, elem);
|
| - ++fLevel;
|
| +
|
| + bool onStartElement(const char elem[]) override {
|
| + this->startCommon(elem, SkDOM::kElement_Type);
|
| return false;
|
| }
|
| - virtual bool onAddAttribute(const char name[], const char value[])
|
| - {
|
| +
|
| + bool onAddAttribute(const char name[], const char value[]) override {
|
| SkDOM::Attr* attr = fAttrs.append();
|
| attr->fName = dupstr(fAlloc, name);
|
| attr->fValue = dupstr(fAlloc, value);
|
| return false;
|
| }
|
| - virtual bool onEndElement(const char elem[])
|
| - {
|
| +
|
| + bool onEndElement(const char elem[]) override {
|
| --fLevel;
|
| if (fNeedToFlush)
|
| this->flushAttributes();
|
| @@ -279,20 +279,40 @@ protected:
|
| parent->fFirstChild = prev;
|
| return false;
|
| }
|
| +
|
| + bool onText(const char text[], int len) override {
|
| + SkString str(text, len);
|
| + this->startCommon(str.c_str(), SkDOM::kText_Type);
|
| + this->SkDOMParser::onEndElement(str.c_str());
|
| +
|
| + return false;
|
| + }
|
| +
|
| private:
|
| + void startCommon(const char elem[], SkDOM::Type type) {
|
| + if (fLevel > 0 && fNeedToFlush)
|
| + this->flushAttributes();
|
| +
|
| + fNeedToFlush = true;
|
| + fElemName = dupstr(fAlloc, elem);
|
| + fElemType = type;
|
| + ++fLevel;
|
| + }
|
| +
|
| SkTDArray<SkDOM::Node*> fParentStack;
|
| - SkChunkAlloc* fAlloc;
|
| - SkDOM::Node* fRoot;
|
| + SkChunkAlloc* fAlloc;
|
| + SkDOM::Node* fRoot;
|
| + bool fNeedToFlush;
|
|
|
| // state needed for flushAttributes()
|
| SkTDArray<SkDOM::Attr> fAttrs;
|
| char* fElemName;
|
| + SkDOM::Type fElemType;
|
| int fLevel;
|
| };
|
|
|
| const SkDOM::Node* SkDOM::build(const char doc[], size_t len)
|
| {
|
| - fAlloc.reset();
|
| SkDOMParser parser(&fAlloc);
|
| if (!parser.parse(doc, len))
|
| {
|
| @@ -310,6 +330,11 @@ const SkDOM::Node* SkDOM::build(const char doc[], size_t len)
|
| static void walk_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLParser* parser)
|
| {
|
| const char* elem = dom.getName(node);
|
| + if (dom.getType(node) == SkDOM::kText_Type) {
|
| + SkASSERT(dom.countChildren(node) == 0);
|
| + parser->text(elem, SkToInt(strlen(elem)));
|
| + return;
|
| + }
|
|
|
| parser->startElement(elem);
|
|
|
| @@ -331,7 +356,6 @@ static void walk_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLParser* par
|
|
|
| const SkDOM::Node* SkDOM::copy(const SkDOM& dom, const SkDOM::Node* node)
|
| {
|
| - fAlloc.reset();
|
| SkDOMParser parser(&fAlloc);
|
|
|
| walk_dom(dom, node, &parser);
|
| @@ -340,6 +364,21 @@ const SkDOM::Node* SkDOM::copy(const SkDOM& dom, const SkDOM::Node* node)
|
| return fRoot;
|
| }
|
|
|
| +SkXMLParser* SkDOM::beginParsing() {
|
| + SkASSERT(!fParser);
|
| + fParser.reset(SkNEW_ARGS(SkDOMParser, (&fAlloc)));
|
| +
|
| + return fParser.get();
|
| +}
|
| +
|
| +const SkDOM::Node* SkDOM::finishParsing() {
|
| + SkASSERT(fParser);
|
| + fRoot = fParser->getRoot();
|
| + fParser.free();
|
| +
|
| + return fRoot;
|
| +}
|
| +
|
| //////////////////////////////////////////////////////////////////////////
|
|
|
| int SkDOM::countChildren(const Node* node, const char elem[]) const
|
| @@ -427,41 +466,14 @@ bool SkDOM::hasBool(const Node* node, const char name[], bool target) const
|
|
|
| #ifdef SK_DEBUG
|
|
|
| -static void tab(int level)
|
| -{
|
| - while (--level >= 0)
|
| - SkDebugf("\t");
|
| -}
|
| -
|
| void SkDOM::dump(const Node* node, int level) const
|
| {
|
| if (node == NULL)
|
| node = this->getRootNode();
|
| - if (node)
|
| - {
|
| - tab(level);
|
| - SkDebugf("<%s", this->getName(node));
|
| -
|
| - const Attr* attr = node->attrs();
|
| - const Attr* stop = attr + node->fAttrCount;
|
| - for (; attr < stop; attr++)
|
| - SkDebugf(" %s=\"%s\"", attr->fName, attr->fValue);
|
|
|
| - const Node* child = this->getFirstChild(node);
|
| - if (child)
|
| - {
|
| - SkDebugf(">\n");
|
| - while (child)
|
| - {
|
| - this->dump(child, level+1);
|
| - child = this->getNextSibling(child);
|
| - }
|
| - tab(level);
|
| - SkDebugf("</%s>\n", node->fName);
|
| - }
|
| - else
|
| - SkDebugf("/>\n");
|
| - }
|
| + SkDebugWStream debugStream;
|
| + SkXMLStreamWriter xmlWriter(&debugStream);
|
| + xmlWriter.writeDOM(*this, node, false);
|
| }
|
|
|
| void SkDOM::UnitTest()
|
|
|