Home | History | Annotate | Download | only in xml
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkBML_XMLParser.h"
     11 #include "SkBML_Verbs.h"
     12 #include "SkStream.h"
     13 #include "SkXMLWriter.h"
     14 
     15 static uint8_t rbyte(SkStream& s)
     16 {
     17     uint8_t b;
     18     SkDEBUGCODE(size_t size = ) s.read(&b, 1);
     19     SkASSERT(size == 1);
     20     return b;
     21 }
     22 
     23 static int rdata(SkStream& s, int data)
     24 {
     25     SkASSERT((data & ~31) == 0);
     26     if (data == 31)
     27     {
     28         data = rbyte(s);
     29         if (data == 0xFF)
     30         {
     31             data = rbyte(s);
     32             data = (data << 8) | rbyte(s);
     33         }
     34     }
     35     return data;
     36 }
     37 
     38 static void set(char* array[256], int index, SkStream& s, int data)
     39 {
     40     SkASSERT((unsigned)index <= 255);
     41 
     42     size_t size = rdata(s, data);
     43 
     44     if (array[index] == NULL)
     45         array[index] = (char*)sk_malloc_throw(size + 1);
     46     else
     47     {
     48         if (strlen(array[index]) < size)
     49             array[index] = (char*)sk_realloc_throw(array[index], size + 1);
     50     }
     51 
     52     s.read(array[index], size);
     53     array[index][size] = 0;
     54 }
     55 
     56 static void freeAll(char* array[256])
     57 {
     58     for (int i = 0; i < 256; i++)
     59         sk_free(array[i]);
     60 }
     61 
     62 struct BMLW {
     63     char*   fElems[256];
     64     char*   fNames[256];
     65     char*   fValues[256];
     66 
     67     // important that these are uint8_t, so we get automatic wrap-around
     68     uint8_t  fNextElem, fNextName, fNextValue;
     69 
     70     BMLW()
     71     {
     72         memset(fElems, 0, sizeof(fElems));
     73         memset(fNames, 0, sizeof(fNames));
     74         memset(fValues, 0, sizeof(fValues));
     75 
     76         fNextElem = fNextName = fNextValue = 0;
     77     }
     78     ~BMLW()
     79     {
     80         freeAll(fElems);
     81         freeAll(fNames);
     82         freeAll(fValues);
     83     }
     84 };
     85 
     86 static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
     87 {
     88     int data = verb & 31;
     89     verb >>= 5;
     90 
     91     int nameIndex, valueIndex;
     92 
     93     switch (verb) {
     94     case kAttr_Value_Value_Verb:
     95         nameIndex = rec.fNextName;      // record before the ++
     96         set(rec.fNames, rec.fNextName++, s, data);
     97         valueIndex = rec.fNextValue;    // record before the ++
     98         set(rec.fValues, rec.fNextValue++, s, 31);
     99         break;
    100     case kAttr_Value_Index_Verb:
    101         nameIndex = rec.fNextName;      // record before the ++
    102         set(rec.fNames, rec.fNextName++, s, data);
    103         valueIndex = rbyte(s);
    104         break;
    105     case kAttr_Index_Value_Verb:
    106         nameIndex = rdata(s, data);
    107         valueIndex = rec.fNextValue;    // record before the ++
    108         set(rec.fValues, rec.fNextValue++, s, 31);
    109         break;
    110     case kAttr_Index_Index_Verb:
    111         nameIndex = rdata(s, data);
    112         valueIndex = rbyte(s);
    113         break;
    114     default:
    115         SkDEBUGFAIL("bad verb");
    116         return;
    117     }
    118     writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
    119 }
    120 
    121 static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
    122 {
    123     int data = verb & 31;
    124     verb >>= 5;
    125 
    126     int elemIndex;
    127 
    128     if (verb == kStartElem_Value_Verb)
    129     {
    130         elemIndex = rec.fNextElem;      // record before the ++
    131         set(rec.fElems, rec.fNextElem++, s, data);
    132     }
    133     else
    134     {
    135         SkASSERT(verb == kStartElem_Index_Verb);
    136         elemIndex = rdata(s, data);
    137     }
    138 
    139     writer.startElement(rec.fElems[elemIndex]);
    140 
    141     for (;;)
    142     {
    143         verb = rbyte(s);
    144         switch (verb >> 5) {
    145         case kAttr_Value_Value_Verb:
    146         case kAttr_Value_Index_Verb:
    147         case kAttr_Index_Value_Verb:
    148         case kAttr_Index_Index_Verb:
    149             rattr(verb, s, rec, writer);
    150             break;
    151         case kStartElem_Value_Verb:
    152         case kStartElem_Index_Verb:
    153             relem(verb, s, rec, writer);
    154             break;
    155         case kEndElem_Verb:
    156             writer.endElement();
    157             return;
    158         default:
    159             SkDEBUGFAIL("bad verb");
    160         }
    161     }
    162 }
    163 
    164 void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
    165 {
    166     BMLW rec;
    167     writer.writeHeader();
    168     relem(rbyte(s), s, rec, writer);
    169 }
    170 
    171 void BML_XMLParser::Read(SkStream& s, SkWStream& output)
    172 {
    173     SkXMLStreamWriter writer(&output);
    174     Read(s, writer);
    175 }
    176 
    177 void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
    178 {
    179     SkXMLParserWriter writer(&output);
    180     Read(s, writer);
    181 }
    182