• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
rbyte(SkStream & s)15 static uint8_t rbyte(SkStream& s)
16 {
17     uint8_t b;
18     size_t size = s.read(&b, 1);
19     SkASSERT(size == 1);
20     return b;
21 }
22 
rdata(SkStream & s,int data)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 
set(char * array[256],int index,SkStream & s,int data)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 
freeAll(char * array[256])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 
BMLWBMLW70     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     }
~BMLWBMLW78     ~BMLW()
79     {
80         freeAll(fElems);
81         freeAll(fNames);
82         freeAll(fValues);
83     }
84 };
85 
rattr(unsigned verb,SkStream & s,BMLW & rec,SkXMLWriter & writer)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 
relem(unsigned verb,SkStream & s,BMLW & rec,SkXMLWriter & writer)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 
Read(SkStream & s,SkXMLWriter & writer)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 
Read(SkStream & s,SkWStream & output)171 void BML_XMLParser::Read(SkStream& s, SkWStream& output)
172 {
173     SkXMLStreamWriter writer(&output);
174     Read(s, writer);
175 }
176 
Read(SkStream & s,SkXMLParser & output)177 void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
178 {
179     SkXMLParserWriter writer(&output);
180     Read(s, writer);
181 }
182 
183 
184 
185