
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkDOM.h"

/////////////////////////////////////////////////////////////////////////

#include "SkXMLParser.h"

bool SkXMLParser::parse(const SkDOM& dom, const SkDOMNode* node)
{
    const char* elemName = dom.getName(node);

    if (this->startElement(elemName))
        return false;
    
    SkDOM::AttrIter iter(dom, node);
    const char*     name, *value;
    
    while ((name = iter.next(&value)) != NULL)
        if (this->addAttribute(name, value))
            return false;

    if ((node = dom.getFirstChild(node)) != NULL)
        do {
            if (!this->parse(dom, node))
                return false;
        } while ((node = dom.getNextSibling(node)) != NULL);
    
    return !this->endElement(elemName);
}

/////////////////////////////////////////////////////////////////////////

struct SkDOMAttr {
    const char* fName;
    const char* fValue;
};

struct SkDOMNode {
    const char* fName;
    SkDOMNode*  fFirstChild;
    SkDOMNode*  fNextSibling;
    uint16_t    fAttrCount;
    uint8_t     fType;
    uint8_t     fPad;

    const SkDOMAttr* attrs() const
    {
        return (const SkDOMAttr*)(this + 1);
    }
    SkDOMAttr* attrs()
    {
        return (SkDOMAttr*)(this + 1);
    }
};

/////////////////////////////////////////////////////////////////////////

#define kMinChunkSize   512

SkDOM::SkDOM() : fAlloc(kMinChunkSize), fRoot(NULL)
{
}

SkDOM::~SkDOM()
{
}

const SkDOM::Node* SkDOM::getRootNode() const
{
    return fRoot;
}

const SkDOM::Node* SkDOM::getFirstChild(const Node* node, const char name[]) const
{
    SkASSERT(node);
    const Node* child = node->fFirstChild;

    if (name)
    {
        for (; child != NULL; child = child->fNextSibling)
            if (!strcmp(name, child->fName))
                break;
    }
    return child;
}

const SkDOM::Node* SkDOM::getNextSibling(const Node* node, const char name[]) const
{
    SkASSERT(node);
    const Node* sibling = node->fNextSibling;
    if (name)
    {
        for (; sibling != NULL; sibling = sibling->fNextSibling)
            if (!strcmp(name, sibling->fName))
                break;
    }
    return sibling;
}

SkDOM::Type SkDOM::getType(const Node* node) const
{
    SkASSERT(node);
    return (Type)node->fType;
}

const char* SkDOM::getName(const Node* node) const
{
    SkASSERT(node);
    return node->fName;
}

const char* SkDOM::findAttr(const Node* node, const char name[]) const
{
    SkASSERT(node);
    const Attr* attr = node->attrs();
    const Attr* stop = attr + node->fAttrCount;

    while (attr < stop)
    {
        if (!strcmp(attr->fName, name))
            return attr->fValue;
        attr += 1;
    }
    return NULL;
}

/////////////////////////////////////////////////////////////////////////////////////

const SkDOM::Attr* SkDOM::getFirstAttr(const Node* node) const
{
    return node->fAttrCount ? node->attrs() : NULL;
}

const SkDOM::Attr* SkDOM::getNextAttr(const Node* node, const Attr* attr) const
{
    SkASSERT(node);
    if (attr == NULL)
        return NULL;
    return (attr - node->attrs() + 1) < node->fAttrCount ? attr + 1 : NULL;
}

const char* SkDOM::getAttrName(const Node* node, const Attr* attr) const
{
    SkASSERT(node);
    SkASSERT(attr);
    return attr->fName;
}

const char* SkDOM::getAttrValue(const Node* node, const Attr* attr) const
{
    SkASSERT(node);
    SkASSERT(attr);
    return attr->fValue;
}

/////////////////////////////////////////////////////////////////////////////////////

SkDOM::AttrIter::AttrIter(const SkDOM&, const SkDOM::Node* node)
{
    SkASSERT(node);
    fAttr = node->attrs();
    fStop = fAttr + node->fAttrCount;
}

const char* SkDOM::AttrIter::next(const char** value)
{
    const char* name = NULL;

    if (fAttr < fStop)
    {
        name = fAttr->fName;
        if (value)
            *value = fAttr->fValue;
        fAttr += 1;
    }
    return name;
}

//////////////////////////////////////////////////////////////////////////////

#include "SkXMLParser.h"
#include "SkTDArray.h"

static char* dupstr(SkChunkAlloc* chunk, const char src[])
{
    SkASSERT(chunk && src);
    size_t  len = strlen(src);
    char*   dst = (char*)chunk->alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
    memcpy(dst, src, len + 1);
    return dst;
}

class SkDOMParser : public SkXMLParser {
    bool fNeedToFlush;
public:
    SkDOMParser(SkChunkAlloc* chunk) : SkXMLParser(&fParserError), fAlloc(chunk)
    {
        fRoot = NULL;
        fLevel = 0;
        fNeedToFlush = true;
    }
    SkDOM::Node* getRoot() const { return fRoot; }
    SkXMLParserError fParserError;
protected:
    void flushAttributes()
    {
        int attrCount = fAttrs.count();

        SkDOM::Node* node = (SkDOM::Node*)fAlloc->alloc(sizeof(SkDOM::Node) + attrCount * sizeof(SkDOM::Attr),
                                                        SkChunkAlloc::kThrow_AllocFailType);

        node->fName = fElemName;
        node->fFirstChild = NULL;
        node->fAttrCount = SkToU16(attrCount);
        node->fType = SkDOM::kElement_Type;

        if (fRoot == NULL)
        {
            node->fNextSibling = NULL;
            fRoot = node;
        }
        else    // this adds siblings in reverse order. gets corrected in onEndElement()
        {
            SkDOM::Node* parent = fParentStack.top();
            SkASSERT(fRoot && parent);
            node->fNextSibling = parent->fFirstChild;
            parent->fFirstChild = node;
        }
        *fParentStack.push() = node;

        memcpy(node->attrs(), fAttrs.begin(), attrCount * sizeof(SkDOM::Attr));
        fAttrs.reset();

    }
    virtual bool onStartElement(const char elem[])
    {
        if (fLevel > 0 && fNeedToFlush)
            this->flushAttributes();
        fNeedToFlush = true;
        fElemName = dupstr(fAlloc, elem);
        ++fLevel;
        return false;
    }
    virtual bool onAddAttribute(const char name[], const char value[])
    {
        SkDOM::Attr* attr = fAttrs.append();
        attr->fName = dupstr(fAlloc, name);
        attr->fValue = dupstr(fAlloc, value);
        return false;
    }
    virtual bool onEndElement(const char elem[])
    {
        --fLevel;
        if (fNeedToFlush)
            this->flushAttributes();
        fNeedToFlush = false;

        SkDOM::Node* parent;

        fParentStack.pop(&parent);

        SkDOM::Node* child = parent->fFirstChild;
        SkDOM::Node* prev = NULL;
        while (child)
        {
            SkDOM::Node* next = child->fNextSibling;
            child->fNextSibling = prev;
            prev = child;
            child = next;
        }
        parent->fFirstChild = prev;
        return false;
    }
private:
    SkTDArray<SkDOM::Node*> fParentStack;
    SkChunkAlloc*   fAlloc;
    SkDOM::Node*    fRoot;

    // state needed for flushAttributes()
    SkTDArray<SkDOM::Attr>  fAttrs;
    char*                   fElemName;
    int                     fLevel;
};

const SkDOM::Node* SkDOM::build(const char doc[], size_t len)
{
    fAlloc.reset();
    SkDOMParser parser(&fAlloc);
    if (!parser.parse(doc, len))
    {
        SkDEBUGCODE(SkDebugf("xml parse error, line %d\n", parser.fParserError.getLineNumber());)
        fRoot = NULL;
        fAlloc.reset();
        return NULL;
    }
    fRoot = parser.getRoot();
    return fRoot;
}

///////////////////////////////////////////////////////////////////////////

static void walk_dom(const SkDOM& dom, const SkDOM::Node* node, SkXMLParser* parser)
{
    const char* elem = dom.getName(node);

    parser->startElement(elem);
    
    SkDOM::AttrIter iter(dom, node);
    const char*     name;
    const char*     value;
    while ((name = iter.next(&value)) != NULL)
        parser->addAttribute(name, value);

    node = dom.getFirstChild(node, NULL);
    while (node)
    {
        walk_dom(dom, node, parser);
        node = dom.getNextSibling(node, NULL);
    }

    parser->endElement(elem);
}

const SkDOM::Node* SkDOM::copy(const SkDOM& dom, const SkDOM::Node* node)
{
    fAlloc.reset();
    SkDOMParser parser(&fAlloc);

    walk_dom(dom, node, &parser);

    fRoot = parser.getRoot();
    return fRoot;
}

//////////////////////////////////////////////////////////////////////////

int SkDOM::countChildren(const Node* node, const char elem[]) const
{
    int count = 0;

    node = this->getFirstChild(node, elem);
    while (node)
    {
        count += 1;
        node = this->getNextSibling(node, elem);
    }
    return count;
}

//////////////////////////////////////////////////////////////////////////

#include "SkParse.h"

bool SkDOM::findS32(const Node* node, const char name[], int32_t* value) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr && SkParse::FindS32(vstr, value);
}

bool SkDOM::findScalars(const Node* node, const char name[], SkScalar value[], int count) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr && SkParse::FindScalars(vstr, value, count);
}

bool SkDOM::findHex(const Node* node, const char name[], uint32_t* value) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr && SkParse::FindHex(vstr, value);
}

bool SkDOM::findBool(const Node* node, const char name[], bool* value) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr && SkParse::FindBool(vstr, value);
}

int SkDOM::findList(const Node* node, const char name[], const char list[]) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr ? SkParse::FindList(vstr, list) : -1;
}

bool SkDOM::hasAttr(const Node* node, const char name[], const char value[]) const
{
    const char* vstr = this->findAttr(node, name);
    return vstr && !strcmp(vstr, value);
}

bool SkDOM::hasS32(const Node* node, const char name[], int32_t target) const
{
    const char* vstr = this->findAttr(node, name);
    int32_t     value;
    return vstr && SkParse::FindS32(vstr, &value) && value == target;
}

bool SkDOM::hasScalar(const Node* node, const char name[], SkScalar target) const
{
    const char* vstr = this->findAttr(node, name);
    SkScalar    value;
    return vstr && SkParse::FindScalar(vstr, &value) && value == target;
}

bool SkDOM::hasHex(const Node* node, const char name[], uint32_t target) const
{
    const char* vstr = this->findAttr(node, name);
    uint32_t    value;
    return vstr && SkParse::FindHex(vstr, &value) && value == target;
}

bool SkDOM::hasBool(const Node* node, const char name[], bool target) const
{
    const char* vstr = this->findAttr(node, name);
    bool        value;
    return vstr && SkParse::FindBool(vstr, &value) && value == target;
}

//////////////////////////////////////////////////////////////////////////

#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");
    }
}

void SkDOM::UnitTest()
{
#ifdef SK_SUPPORT_UNITTEST
    static const char gDoc[] = 
        "<root a='1' b='2'>"
            "<elem1 c='3' />"
            "<elem2 d='4' />"
            "<elem3 e='5'>"
                "<subelem1/>"
                "<subelem2 f='6' g='7'/>"
            "</elem3>"
            "<elem4 h='8'/>"
        "</root>"
        ;

    SkDOM   dom;

    SkASSERT(dom.getRootNode() == NULL);

    const Node* root = dom.build(gDoc, sizeof(gDoc) - 1);
    SkASSERT(root && dom.getRootNode() == root);

    const char* v = dom.findAttr(root, "a");
    SkASSERT(v && !strcmp(v, "1"));
    v = dom.findAttr(root, "b");
    SkASSERT(v && !strcmp(v, "2"));
    v = dom.findAttr(root, "c");
    SkASSERT(v == NULL);

    SkASSERT(dom.getFirstChild(root, "elem1"));
    SkASSERT(!dom.getFirstChild(root, "subelem1"));

    dom.dump();
#endif
}

#endif

