
/*
 * 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 "SkXMLParser.h"
#include "SkString.h"
#include "SkStream.h"

#include "expat.h"

#ifdef SK_BUILD_FOR_PPI
#define CHAR_16_TO_9
#endif

#if defined CHAR_16_TO_9
inline size_t sk_wcslen(const short* char16) {
    const short* start = char16;
    while (*char16)
        char16++;
    return char16 - start;
}

inline const char* ConvertUnicodeToChar(const short* ch16, size_t len, SkAutoMalloc& ch8Malloc) {
    char* ch8 = (char*) ch8Malloc.get();
    int index;
    for (index = 0; index < len; index++)
        ch8[index] = (char) ch16[index];
    ch8[index] = '\0';
    return ch8;
}
#endif

static void XMLCALL start_proc(void *data, const char *el, const char **attr)
{
#if defined CHAR_16_TO_9
    size_t len = sk_wcslen((const short*) el);
    SkAutoMalloc    el8(len + 1);
    el = ConvertUnicodeToChar((const short*) el, len, el8);
#endif
    if (((SkXMLParser*)data)->startElement(el)) {
        XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
        return;
    }
    while (*attr)
    {
        const char* attr0 = attr[0];
        const char* attr1 = attr[1];
#if defined CHAR_16_TO_9
        size_t len0 = sk_wcslen((const short*) attr0);
        SkAutoMalloc    attr0_8(len0 + 1);
        attr0 = ConvertUnicodeToChar((const short*) attr0, len0, attr0_8);
        size_t len1 = sk_wcslen((const short*) attr1);
        SkAutoMalloc    attr1_8(len1 + 1);
        attr1 = ConvertUnicodeToChar((const short*) attr1, len1, attr1_8);
#endif
        if (((SkXMLParser*)data)->addAttribute(attr0, attr1)) {
            XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
            return;
        }
        attr += 2;
    }
}

static void XMLCALL end_proc(void *data, const char *el)
{
#if defined CHAR_16_TO_9
    size_t len = sk_wcslen((const short*) el);
    SkAutoMalloc    el8(len + 1);
    el = ConvertUnicodeToChar((const short*) el, len, el8);
#endif
    if (((SkXMLParser*)data)->endElement(el))
        XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
}

static void XMLCALL text_proc(void* data, const char* text, int len)
{
#if defined CHAR_16_TO_9
    SkAutoMalloc    text8(len + 1);
    text = ConvertUnicodeToChar((const short*) text, len, text8);
#endif
    if (((SkXMLParser*)data)->text(text, len))
        XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
}

bool SkXMLParser::parse(const char doc[], size_t len)
{
    if (len == 0) {
        fError->fCode = SkXMLParserError::kEmptyFile;
        reportError(NULL);
        return false;
    }
    XML_Parser p = XML_ParserCreate(NULL);
    SkASSERT(p);
    fParser = p;
    XML_SetElementHandler(p, start_proc, end_proc);
    XML_SetCharacterDataHandler(p, text_proc);
    XML_SetUserData(p, this);

    bool success = true;
    int error = XML_Parse(p, doc, len, true);
    if (error == XML_STATUS_ERROR) {
        reportError(p);
        success = false;
    }
    XML_ParserFree(p);
    return success;
}

bool SkXMLParser::parse(SkStream& input)
{
    size_t          len = input.getLength();
    SkAutoMalloc    am(len);
    char*           doc = (char*)am.get();

    input.rewind();
    size_t  len2 = input.read(doc, len);
    SkASSERT(len2 == len);

    return this->parse(doc, len2);
}

void SkXMLParser::reportError(void* p)
{
    XML_Parser parser = (XML_Parser) p;
    if (fError && parser) {
        fError->fNativeCode = XML_GetErrorCode(parser);
        fError->fLineNumber = XML_GetCurrentLineNumber(parser);
    }
}

void SkXMLParser::GetNativeErrorString(int error, SkString* str)
{
    if (str)
        str->set(XML_ErrorString((XML_Error) error));
}
