/* libs/graphics/xml/SkBML_XMLParser.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 "SkBML_XMLParser.h"
#include "SkBML_Verbs.h"
#include "SkStream.h"
#include "SkXMLWriter.h"

static uint8_t rbyte(SkStream& s)
{
    uint8_t b;
    size_t size = s.read(&b, 1);
    SkASSERT(size == 1);
    return b;
}

static int rdata(SkStream& s, int data)
{
    SkASSERT((data & ~31) == 0);
    if (data == 31)
    {
        data = rbyte(s);
        if (data == 0xFF)
        {
            data = rbyte(s);
            data = (data << 8) | rbyte(s);
        }
    }
    return data;
}

static void set(char* array[256], int index, SkStream& s, int data)
{
    SkASSERT((unsigned)index <= 255);

    size_t size = rdata(s, data);

    if (array[index] == NULL)
        array[index] = (char*)sk_malloc_throw(size + 1);
    else
    {
        if (strlen(array[index]) < size)
            array[index] = (char*)sk_realloc_throw(array[index], size + 1);
    }

    s.read(array[index], size);
    array[index][size] = 0;
}

static void freeAll(char* array[256])
{
    for (int i = 0; i < 256; i++)
        sk_free(array[i]);
}

struct BMLW {
    char*   fElems[256];
    char*   fNames[256];
    char*   fValues[256];

    // important that these are uint8_t, so we get automatic wrap-around
    uint8_t  fNextElem, fNextName, fNextValue;

    BMLW()
    {
        memset(fElems, 0, sizeof(fElems));
        memset(fNames, 0, sizeof(fNames));
        memset(fValues, 0, sizeof(fValues));

        fNextElem = fNextName = fNextValue = 0;
    }
    ~BMLW()
    {
        freeAll(fElems);
        freeAll(fNames);
        freeAll(fValues);
    }
};

static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
{
    int data = verb & 31;
    verb >>= 5;

    int nameIndex, valueIndex;

    switch (verb) {
    case kAttr_Value_Value_Verb:
        nameIndex = rec.fNextName;      // record before the ++
        set(rec.fNames, rec.fNextName++, s, data);
        valueIndex = rec.fNextValue;    // record before the ++
        set(rec.fValues, rec.fNextValue++, s, 31);
        break;
    case kAttr_Value_Index_Verb:
        nameIndex = rec.fNextName;      // record before the ++
        set(rec.fNames, rec.fNextName++, s, data);
        valueIndex = rbyte(s);
        break;
    case kAttr_Index_Value_Verb:
        nameIndex = rdata(s, data);
        valueIndex = rec.fNextValue;    // record before the ++
        set(rec.fValues, rec.fNextValue++, s, 31);
        break;
    case kAttr_Index_Index_Verb:
        nameIndex = rdata(s, data);
        valueIndex = rbyte(s);
        break;
    default:
        SkASSERT(!"bad verb");
        return;
    }
    writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
}

static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
{
    int data = verb & 31;
    verb >>= 5;

    int elemIndex;

    if (verb == kStartElem_Value_Verb)
    {
        elemIndex = rec.fNextElem;      // record before the ++
        set(rec.fElems, rec.fNextElem++, s, data);
    }
    else
    {
        SkASSERT(verb == kStartElem_Index_Verb);
        elemIndex = rdata(s, data);
    }

    writer.startElement(rec.fElems[elemIndex]);

    for (;;)
    {
        verb = rbyte(s);
        switch (verb >> 5) {
        case kAttr_Value_Value_Verb:
        case kAttr_Value_Index_Verb:
        case kAttr_Index_Value_Verb:
        case kAttr_Index_Index_Verb:
            rattr(verb, s, rec, writer);
            break;
        case kStartElem_Value_Verb:
        case kStartElem_Index_Verb:
            relem(verb, s, rec, writer);
            break;
        case kEndElem_Verb:
            writer.endElement();
            return;
        default:
            SkASSERT(!"bad verb");
        }
    }
}

void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
{
    BMLW rec;
    writer.writeHeader();
    relem(rbyte(s), s, rec, writer);
}

void BML_XMLParser::Read(SkStream& s, SkWStream& output)
{
    SkXMLStreamWriter writer(&output);
    Read(s, writer);
}

void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
{
    SkXMLParserWriter writer(&output);
    Read(s, writer);
}



