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 "SkBML_XMLParser.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBML_Verbs.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXMLWriter.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint8_t rbyte(SkStream& s)
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t b;
18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkDEBUGCODE(size_t size = ) s.read(&b, 1);
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(size == 1);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return b;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int rdata(SkStream& s, int data)
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((data & ~31) == 0);
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (data == 31)
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        data = rbyte(s);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (data == 0xFF)
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            data = rbyte(s);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            data = (data << 8) | rbyte(s);
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return data;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void set(char* array[256], int index, SkStream& s, int data)
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)index <= 255);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t size = rdata(s, data);
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (array[index] == NULL)
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        array[index] = (char*)sk_malloc_throw(size + 1);
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (strlen(array[index]) < size)
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            array[index] = (char*)sk_realloc_throw(array[index], size + 1);
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s.read(array[index], size);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    array[index][size] = 0;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void freeAll(char* array[256])
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < 256; i++)
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        sk_free(array[i]);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct BMLW {
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char*   fElems[256];
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char*   fNames[256];
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    char*   fValues[256];
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // important that these are uint8_t, so we get automatic wrap-around
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint8_t  fNextElem, fNextName, fNextValue;
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    BMLW()
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(fElems, 0, sizeof(fElems));
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(fNames, 0, sizeof(fNames));
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memset(fValues, 0, sizeof(fValues));
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fNextElem = fNextName = fNextValue = 0;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~BMLW()
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        freeAll(fElems);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        freeAll(fNames);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        freeAll(fValues);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int data = verb & 31;
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    verb >>= 5;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int nameIndex, valueIndex;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (verb) {
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case kAttr_Value_Value_Verb:
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        nameIndex = rec.fNextName;      // record before the ++
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        set(rec.fNames, rec.fNextName++, s, data);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        valueIndex = rec.fNextValue;    // record before the ++
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        set(rec.fValues, rec.fNextValue++, s, 31);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case kAttr_Value_Index_Verb:
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        nameIndex = rec.fNextName;      // record before the ++
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        set(rec.fNames, rec.fNextName++, s, data);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        valueIndex = rbyte(s);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case kAttr_Index_Value_Verb:
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        nameIndex = rdata(s, data);
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        valueIndex = rec.fNextValue;    // record before the ++
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        set(rec.fValues, rec.fNextValue++, s, 31);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case kAttr_Index_Index_Verb:
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        nameIndex = rdata(s, data);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        valueIndex = rbyte(s);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    default:
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDEBUGFAIL("bad verb");
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int data = verb & 31;
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    verb >>= 5;
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int elemIndex;
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (verb == kStartElem_Value_Verb)
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        elemIndex = rec.fNextElem;      // record before the ++
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        set(rec.fElems, rec.fNextElem++, s, data);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(verb == kStartElem_Index_Verb);
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        elemIndex = rdata(s, data);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writer.startElement(rec.fElems[elemIndex]);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (;;)
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        verb = rbyte(s);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        switch (verb >> 5) {
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kAttr_Value_Value_Verb:
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kAttr_Value_Index_Verb:
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kAttr_Index_Value_Verb:
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kAttr_Index_Index_Verb:
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            rattr(verb, s, rec, writer);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kStartElem_Value_Verb:
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kStartElem_Index_Verb:
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            relem(verb, s, rec, writer);
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kEndElem_Verb:
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            writer.endElement();
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        default:
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDEBUGFAIL("bad verb");
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    BMLW rec;
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    writer.writeHeader();
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    relem(rbyte(s), s, rec, writer);
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkWStream& output)
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkXMLStreamWriter writer(&output);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Read(s, writer);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkXMLParserWriter writer(&output);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Read(s, writer);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
182