180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXMLWriter.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLWriter::SkXMLWriter(bool doEscapeMarkup) : fDoEscapeMarkup(doEscapeMarkup)
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLWriter::~SkXMLWriter()
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fElems.count() == 0);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::flush()
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (fElems.count())
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->endElement();
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::addAttribute(const char name[], const char value[])
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->addAttributeLen(name, value, strlen(value));
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::addS32Attribute(const char name[], int32_t value)
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    tmp;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp.appendS32(value);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->addAttribute(name, tmp.c_str());
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::addHexAttribute(const char name[], uint32_t value, int minDigits)
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    tmp("0x");
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp.appendHex(value, minDigits);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->addAttribute(name, tmp.c_str());
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::addScalarAttribute(const char name[], SkScalar value)
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    tmp;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp.appendScalar(value);
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->addAttribute(name, tmp.c_str());
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::doEnd(Elem* elem)
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    delete elem;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkXMLWriter::doStart(const char name[], size_t length)
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int level = fElems.count();
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool firstChild = level > 0 && !fElems[level-1]->fHasChildren;
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (firstChild)
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fElems[level-1]->fHasChildren = true;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Elem** elem = fElems.push();
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *elem = new Elem;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (*elem)->fName.set(name, length);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (*elem)->fHasChildren = 0;
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return firstChild;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLWriter::Elem* SkXMLWriter::getEnd()
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Elem* elem;
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fElems.pop(&elem);
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return elem;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkXMLWriter::getHeader()
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const char gHeader[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return gHeader;
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::startElement(const char name[])
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->startElementLen(name, strlen(name));
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const char* escape_char(char c, char storage[2])
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const char* gEscapeChars[] = {
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "<&lt;",
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        ">&gt;",
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //"\"&quot;",
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //"'&apos;",
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        "&&amp;"
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char** array = gEscapeChars;
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (unsigned i = 0; i < SK_ARRAY_COUNT(gEscapeChars); i++)
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (array[i][0] == c)
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return &array[i][1];
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    storage[0] = c;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    storage[1] = 0;
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return storage;
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic size_t escape_markup(char dst[], const char src[], size_t length)
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t      extra = 0;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* stop = src + length;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (src < stop)
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        char        orig[2];
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* seq = escape_char(*src, orig);
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        size_t      seqSize = strlen(seq);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (dst)
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            memcpy(dst, seq, seqSize);
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            dst += seqSize;
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // now record the extra size needed
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        extra += seqSize - 1;   // minus one to subtract the original char
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // bump to the next src char
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        src += 1;
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return extra;
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::addAttributeLen(const char name[], const char value[], size_t length)
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString valueStr;
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fDoEscapeMarkup)
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        size_t   extra = escape_markup(NULL, value, length);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (extra)
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            valueStr.resize(length + extra);
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (void)escape_markup(valueStr.writable_str(), value, length);
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value = valueStr.c_str();
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            length += extra;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->onAddAttributeLen(name, value, length);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::startElementLen(const char elem[], size_t length)
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->onStartElementLen(elem, length);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void write_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLWriter* w, bool skipRoot)
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!skipRoot)
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w->startElement(dom.getName(node));
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDOM::AttrIter iter(dom, node);
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* name;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* value;
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        while ((name = iter.next(&value)) != NULL)
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            w->addAttribute(name, value);
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    node = dom.getFirstChild(node, NULL);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (node)
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        write_dom(dom, node, w, false);
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        node = dom.getNextSibling(node, NULL);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!skipRoot)
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w->endElement();
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::writeDOM(const SkDOM& dom, const SkDOM::Node* node, bool skipRoot)
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (node)
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        write_dom(dom, node, this, skipRoot);
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLWriter::writeHeader()
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkXMLStreamWriter
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void tab(SkWStream& stream, int level)
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < level; i++)
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        stream.writeText("\t");
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLStreamWriter::SkXMLStreamWriter(SkWStream* stream) : fStream(*stream)
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLStreamWriter::~SkXMLStreamWriter()
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flush();
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLStreamWriter::onAddAttributeLen(const char name[], const char value[], size_t length)
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(!fElems.top()->fHasChildren);
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.writeText(" ");
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.writeText(name);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.writeText("=\"");
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.write(value, length);
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.writeText("\"");
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLStreamWriter::onEndElement()
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Elem* elem = getEnd();
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (elem->fHasChildren)
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tab(fStream, fElems.count());
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.writeText("</");
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.writeText(elem->fName.c_str());
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.writeText(">");
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.writeText("/>");
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.newline();
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    doEnd(elem);
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLStreamWriter::onStartElementLen(const char name[], size_t length)
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int level = fElems.count();
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this->doStart(name, length))
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // the first child, need to close with >
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.writeText(">");
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fStream.newline();
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tab(fStream, level);
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.writeText("<");
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.write(name, length);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLStreamWriter::writeHeader()
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* header = getHeader();
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.write(header, strlen(header));
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fStream.newline();
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////////////
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXMLParser.h"
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLParserWriter::SkXMLParserWriter(SkXMLParser* parser)
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : SkXMLWriter(false), fParser(*parser)
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXMLParserWriter::~SkXMLParserWriter()
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flush();
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLParserWriter::onAddAttributeLen(const char name[], const char value[], size_t length)
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fElems.count() == 0 || !fElems.top()->fHasChildren);
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString str(value, length);
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fParser.addAttribute(name, str.c_str());
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLParserWriter::onEndElement()
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Elem* elem = this->getEnd();
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fParser.endElement(elem->fName.c_str());
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->doEnd(elem);
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLParserWriter::onStartElementLen(const char name[], size_t length)
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (void)this->doStart(name, length);
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString str(name, length);
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fParser.startElement(str.c_str());
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXMLStreamWriter::UnitTest()
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SUPPORT_UNITTEST
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugWStream  s;
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkXMLStreamWriter       w(&s);
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.startElement("elem0");
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.addAttribute("hello", "world");
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.addS32Attribute("dec", 42);
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.addHexAttribute("hex", 0x42, 3);
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.addScalarAttribute("scalar", -4.2f);
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.startElement("elem1");
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.endElement();
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.startElement("elem1");
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.addAttribute("name", "value");
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.endElement();
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.startElement("elem1");
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            w.startElement("elem2");
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                w.startElement("elem3");
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                w.addAttribute("name", "value");
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                w.endElement();
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            w.endElement();
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            w.startElement("elem2");
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            w.endElement();
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        w.endElement();
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    w.endElement();
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
334