gfx/skia/trunk/src/xml/SkBML_XMLParser.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/xml/SkBML_XMLParser.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,181 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "SkBML_XMLParser.h"
    1.14 +#include "SkBML_Verbs.h"
    1.15 +#include "SkStream.h"
    1.16 +#include "SkXMLWriter.h"
    1.17 +
    1.18 +static uint8_t rbyte(SkStream& s)
    1.19 +{
    1.20 +    uint8_t b;
    1.21 +    SkDEBUGCODE(size_t size = ) s.read(&b, 1);
    1.22 +    SkASSERT(size == 1);
    1.23 +    return b;
    1.24 +}
    1.25 +
    1.26 +static int rdata(SkStream& s, int data)
    1.27 +{
    1.28 +    SkASSERT((data & ~31) == 0);
    1.29 +    if (data == 31)
    1.30 +    {
    1.31 +        data = rbyte(s);
    1.32 +        if (data == 0xFF)
    1.33 +        {
    1.34 +            data = rbyte(s);
    1.35 +            data = (data << 8) | rbyte(s);
    1.36 +        }
    1.37 +    }
    1.38 +    return data;
    1.39 +}
    1.40 +
    1.41 +static void set(char* array[256], int index, SkStream& s, int data)
    1.42 +{
    1.43 +    SkASSERT((unsigned)index <= 255);
    1.44 +
    1.45 +    size_t size = rdata(s, data);
    1.46 +
    1.47 +    if (array[index] == NULL)
    1.48 +        array[index] = (char*)sk_malloc_throw(size + 1);
    1.49 +    else
    1.50 +    {
    1.51 +        if (strlen(array[index]) < size)
    1.52 +            array[index] = (char*)sk_realloc_throw(array[index], size + 1);
    1.53 +    }
    1.54 +
    1.55 +    s.read(array[index], size);
    1.56 +    array[index][size] = 0;
    1.57 +}
    1.58 +
    1.59 +static void freeAll(char* array[256])
    1.60 +{
    1.61 +    for (int i = 0; i < 256; i++)
    1.62 +        sk_free(array[i]);
    1.63 +}
    1.64 +
    1.65 +struct BMLW {
    1.66 +    char*   fElems[256];
    1.67 +    char*   fNames[256];
    1.68 +    char*   fValues[256];
    1.69 +
    1.70 +    // important that these are uint8_t, so we get automatic wrap-around
    1.71 +    uint8_t  fNextElem, fNextName, fNextValue;
    1.72 +
    1.73 +    BMLW()
    1.74 +    {
    1.75 +        memset(fElems, 0, sizeof(fElems));
    1.76 +        memset(fNames, 0, sizeof(fNames));
    1.77 +        memset(fValues, 0, sizeof(fValues));
    1.78 +
    1.79 +        fNextElem = fNextName = fNextValue = 0;
    1.80 +    }
    1.81 +    ~BMLW()
    1.82 +    {
    1.83 +        freeAll(fElems);
    1.84 +        freeAll(fNames);
    1.85 +        freeAll(fValues);
    1.86 +    }
    1.87 +};
    1.88 +
    1.89 +static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
    1.90 +{
    1.91 +    int data = verb & 31;
    1.92 +    verb >>= 5;
    1.93 +
    1.94 +    int nameIndex, valueIndex;
    1.95 +
    1.96 +    switch (verb) {
    1.97 +    case kAttr_Value_Value_Verb:
    1.98 +        nameIndex = rec.fNextName;      // record before the ++
    1.99 +        set(rec.fNames, rec.fNextName++, s, data);
   1.100 +        valueIndex = rec.fNextValue;    // record before the ++
   1.101 +        set(rec.fValues, rec.fNextValue++, s, 31);
   1.102 +        break;
   1.103 +    case kAttr_Value_Index_Verb:
   1.104 +        nameIndex = rec.fNextName;      // record before the ++
   1.105 +        set(rec.fNames, rec.fNextName++, s, data);
   1.106 +        valueIndex = rbyte(s);
   1.107 +        break;
   1.108 +    case kAttr_Index_Value_Verb:
   1.109 +        nameIndex = rdata(s, data);
   1.110 +        valueIndex = rec.fNextValue;    // record before the ++
   1.111 +        set(rec.fValues, rec.fNextValue++, s, 31);
   1.112 +        break;
   1.113 +    case kAttr_Index_Index_Verb:
   1.114 +        nameIndex = rdata(s, data);
   1.115 +        valueIndex = rbyte(s);
   1.116 +        break;
   1.117 +    default:
   1.118 +        SkDEBUGFAIL("bad verb");
   1.119 +        return;
   1.120 +    }
   1.121 +    writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
   1.122 +}
   1.123 +
   1.124 +static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
   1.125 +{
   1.126 +    int data = verb & 31;
   1.127 +    verb >>= 5;
   1.128 +
   1.129 +    int elemIndex;
   1.130 +
   1.131 +    if (verb == kStartElem_Value_Verb)
   1.132 +    {
   1.133 +        elemIndex = rec.fNextElem;      // record before the ++
   1.134 +        set(rec.fElems, rec.fNextElem++, s, data);
   1.135 +    }
   1.136 +    else
   1.137 +    {
   1.138 +        SkASSERT(verb == kStartElem_Index_Verb);
   1.139 +        elemIndex = rdata(s, data);
   1.140 +    }
   1.141 +
   1.142 +    writer.startElement(rec.fElems[elemIndex]);
   1.143 +
   1.144 +    for (;;)
   1.145 +    {
   1.146 +        verb = rbyte(s);
   1.147 +        switch (verb >> 5) {
   1.148 +        case kAttr_Value_Value_Verb:
   1.149 +        case kAttr_Value_Index_Verb:
   1.150 +        case kAttr_Index_Value_Verb:
   1.151 +        case kAttr_Index_Index_Verb:
   1.152 +            rattr(verb, s, rec, writer);
   1.153 +            break;
   1.154 +        case kStartElem_Value_Verb:
   1.155 +        case kStartElem_Index_Verb:
   1.156 +            relem(verb, s, rec, writer);
   1.157 +            break;
   1.158 +        case kEndElem_Verb:
   1.159 +            writer.endElement();
   1.160 +            return;
   1.161 +        default:
   1.162 +            SkDEBUGFAIL("bad verb");
   1.163 +        }
   1.164 +    }
   1.165 +}
   1.166 +
   1.167 +void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
   1.168 +{
   1.169 +    BMLW rec;
   1.170 +    writer.writeHeader();
   1.171 +    relem(rbyte(s), s, rec, writer);
   1.172 +}
   1.173 +
   1.174 +void BML_XMLParser::Read(SkStream& s, SkWStream& output)
   1.175 +{
   1.176 +    SkXMLStreamWriter writer(&output);
   1.177 +    Read(s, writer);
   1.178 +}
   1.179 +
   1.180 +void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
   1.181 +{
   1.182 +    SkXMLParserWriter writer(&output);
   1.183 +    Read(s, writer);
   1.184 +}

mercurial