/* libs/graphics/ports/SkXMLParser_expat.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include "SkXMLParser.h"
#include "SkChunkAlloc.h"
#include "SkString.h"
#include "SkStream.h"

#include "expat.h"

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

static inline int count_pairs(const char** p)
{
    const char** start = p;
    while (*p)
    {
        SkASSERT(p[1] != NULL);
        p += 2;
    }
    return (p - start) >> 1;
}

struct Data {
    Data() : fAlloc(2048), fState(NORMAL) {}
    
    XML_Parser              fParser;
    SkXMLPullParser::Curr*  fCurr;
    SkChunkAlloc            fAlloc;
    
    enum State {
        NORMAL,
        MISSED_START_TAG,
        RETURN_END_TAG
    };
    State fState;
    const char* fEndTag;    // if state is RETURN_END_TAG
};

static void XMLCALL start_proc(void *data, const char *el, const char **attr)
{
    Data*                   p = (Data*)data;
    SkXMLPullParser::Curr*  c = p->fCurr;
    SkChunkAlloc&           alloc = p->fAlloc;

    c->fName = dupstr(alloc, el, strlen(el));
    
    int n = count_pairs(attr);
    SkXMLPullParser::AttrInfo* info = (SkXMLPullParser::AttrInfo*)alloc.alloc(n * sizeof(SkXMLPullParser::AttrInfo),
                                                                              SkChunkAlloc::kThrow_AllocFailType);
    c->fAttrInfoCount = n;
    c->fAttrInfos = info;

    for (int i = 0; i < n; i++)
    {
        info[i].fName = dupstr(alloc, attr[0], strlen(attr[0]));
        info[i].fValue = dupstr(alloc, attr[1], strlen(attr[1]));
        attr += 2;
    }

    c->fEventType = SkXMLPullParser::START_TAG;
    XML_StopParser(p->fParser, true);
}

static void XMLCALL end_proc(void *data, const char *el)
{
    Data*                   p = (Data*)data;
    SkXMLPullParser::Curr*  c = p->fCurr;

    if (c->fEventType == SkXMLPullParser::START_TAG)
    {
        /*  if we get here, we were called with a start_tag immediately
            followed by this end_tag. The caller will only see the end_tag,
            so we set a flag to notify them of the missed start_tag
        */
        p->fState = Data::MISSED_START_TAG;
        
        SkASSERT(c->fName != NULL);
        SkASSERT(strcmp(c->fName, el) == 0);
    }
    else
        c->fName = dupstr(p->fAlloc, el, strlen(el));

    c->fEventType = SkXMLPullParser::END_TAG;
    XML_StopParser(p->fParser, true);
}

#include <ctype.h>

static bool isws(const char s[])
{
    for (; *s; s++)
        if (!isspace(*s))
            return false;
    return true;
}

static void XMLCALL text_proc(void* data, const char* text, int len)
{
    Data*                   p = (Data*)data;
    SkXMLPullParser::Curr*  c = p->fCurr;

    c->fName = dupstr(p->fAlloc, text, len);
    c->fIsWhitespace = isws(c->fName);

    c->fEventType = SkXMLPullParser::TEXT;
    XML_StopParser(p->fParser, true);
}

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

struct SkXMLPullParser::Impl {
    Data    fData;
    void*   fBuffer;
    size_t  fBufferLen;
};

static void reportError(XML_Parser parser)
{
    XML_Error code = XML_GetErrorCode(parser);
    int lineNumber = XML_GetCurrentLineNumber(parser);
    const char* msg = XML_ErrorString(code);
    
    printf("-------- XML error [%d] on line %d, %s\n", code, lineNumber, msg);
}

bool SkXMLPullParser::onInit()
{
    fImpl = new Impl;

    XML_Parser p = XML_ParserCreate(NULL);
    SkASSERT(p);

    fImpl->fData.fParser = p;
    fImpl->fData.fCurr = &fCurr;

    XML_SetElementHandler(p, start_proc, end_proc);
    XML_SetCharacterDataHandler(p, text_proc);
    XML_SetUserData(p, &fImpl->fData);

    size_t len = fStream->read(NULL, 0);
    fImpl->fBufferLen = len;
    fImpl->fBuffer = sk_malloc_throw(len);
    fStream->rewind();
    size_t  len2 = fStream->read(fImpl->fBuffer, len);
    return len2 == len;
}

void SkXMLPullParser::onExit()
{
    sk_free(fImpl->fBuffer);
    XML_ParserFree(fImpl->fData.fParser);
    delete fImpl;
    fImpl = NULL;
}

SkXMLPullParser::EventType SkXMLPullParser::onNextToken()
{
    if (Data::RETURN_END_TAG == fImpl->fData.fState)
    {
        fImpl->fData.fState = Data::NORMAL;
        fCurr.fName = fImpl->fData.fEndTag; // restore name from (below) save
        return SkXMLPullParser::END_TAG;
    }

    fImpl->fData.fAlloc.reuse();

    XML_Parser p = fImpl->fData.fParser;
    XML_Status status;

    status = XML_ResumeParser(p);
    
CHECK_STATUS:
    switch (status) {
    case XML_STATUS_OK:
        return SkXMLPullParser::END_DOCUMENT;

    case XML_STATUS_ERROR:
        if (XML_GetErrorCode(p) != XML_ERROR_NOT_SUSPENDED)
        {
            reportError(p);
            return SkXMLPullParser::ERROR;
        }
        status = XML_Parse(p, (const char*)fImpl->fBuffer, fImpl->fBufferLen, true);
        goto CHECK_STATUS;

    case XML_STATUS_SUSPENDED:
        if (Data::MISSED_START_TAG == fImpl->fData.fState)
        {
            // return a start_tag, and clear the flag so we return end_tag next
            SkASSERT(SkXMLPullParser::END_TAG == fCurr.fEventType);
            fImpl->fData.fState = Data::RETURN_END_TAG;
            fImpl->fData.fEndTag = fCurr.fName;  // save this pointer            
            return SkXMLPullParser::START_TAG;
        }
        break;
    }
    return fCurr.fEventType;
}

