1 /* libs/graphics/xml/SkBML_XMLParser.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkBML_XMLParser.h"
19 #include "SkBML_Verbs.h"
20 #include "SkStream.h"
21 #include "SkXMLWriter.h"
22
rbyte(SkStream & s)23 static uint8_t rbyte(SkStream& s)
24 {
25 uint8_t b;
26 size_t size = s.read(&b, 1);
27 SkASSERT(size == 1);
28 return b;
29 }
30
rdata(SkStream & s,int data)31 static int rdata(SkStream& s, int data)
32 {
33 SkASSERT((data & ~31) == 0);
34 if (data == 31)
35 {
36 data = rbyte(s);
37 if (data == 0xFF)
38 {
39 data = rbyte(s);
40 data = (data << 8) | rbyte(s);
41 }
42 }
43 return data;
44 }
45
set(char * array[256],int index,SkStream & s,int data)46 static void set(char* array[256], int index, SkStream& s, int data)
47 {
48 SkASSERT((unsigned)index <= 255);
49
50 size_t size = rdata(s, data);
51
52 if (array[index] == NULL)
53 array[index] = (char*)sk_malloc_throw(size + 1);
54 else
55 {
56 if (strlen(array[index]) < size)
57 array[index] = (char*)sk_realloc_throw(array[index], size + 1);
58 }
59
60 s.read(array[index], size);
61 array[index][size] = 0;
62 }
63
freeAll(char * array[256])64 static void freeAll(char* array[256])
65 {
66 for (int i = 0; i < 256; i++)
67 sk_free(array[i]);
68 }
69
70 struct BMLW {
71 char* fElems[256];
72 char* fNames[256];
73 char* fValues[256];
74
75 // important that these are uint8_t, so we get automatic wrap-around
76 uint8_t fNextElem, fNextName, fNextValue;
77
BMLWBMLW78 BMLW()
79 {
80 memset(fElems, 0, sizeof(fElems));
81 memset(fNames, 0, sizeof(fNames));
82 memset(fValues, 0, sizeof(fValues));
83
84 fNextElem = fNextName = fNextValue = 0;
85 }
~BMLWBMLW86 ~BMLW()
87 {
88 freeAll(fElems);
89 freeAll(fNames);
90 freeAll(fValues);
91 }
92 };
93
rattr(unsigned verb,SkStream & s,BMLW & rec,SkXMLWriter & writer)94 static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
95 {
96 int data = verb & 31;
97 verb >>= 5;
98
99 int nameIndex, valueIndex;
100
101 switch (verb) {
102 case kAttr_Value_Value_Verb:
103 nameIndex = rec.fNextName; // record before the ++
104 set(rec.fNames, rec.fNextName++, s, data);
105 valueIndex = rec.fNextValue; // record before the ++
106 set(rec.fValues, rec.fNextValue++, s, 31);
107 break;
108 case kAttr_Value_Index_Verb:
109 nameIndex = rec.fNextName; // record before the ++
110 set(rec.fNames, rec.fNextName++, s, data);
111 valueIndex = rbyte(s);
112 break;
113 case kAttr_Index_Value_Verb:
114 nameIndex = rdata(s, data);
115 valueIndex = rec.fNextValue; // record before the ++
116 set(rec.fValues, rec.fNextValue++, s, 31);
117 break;
118 case kAttr_Index_Index_Verb:
119 nameIndex = rdata(s, data);
120 valueIndex = rbyte(s);
121 break;
122 default:
123 SkASSERT(!"bad verb");
124 return;
125 }
126 writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
127 }
128
relem(unsigned verb,SkStream & s,BMLW & rec,SkXMLWriter & writer)129 static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
130 {
131 int data = verb & 31;
132 verb >>= 5;
133
134 int elemIndex;
135
136 if (verb == kStartElem_Value_Verb)
137 {
138 elemIndex = rec.fNextElem; // record before the ++
139 set(rec.fElems, rec.fNextElem++, s, data);
140 }
141 else
142 {
143 SkASSERT(verb == kStartElem_Index_Verb);
144 elemIndex = rdata(s, data);
145 }
146
147 writer.startElement(rec.fElems[elemIndex]);
148
149 for (;;)
150 {
151 verb = rbyte(s);
152 switch (verb >> 5) {
153 case kAttr_Value_Value_Verb:
154 case kAttr_Value_Index_Verb:
155 case kAttr_Index_Value_Verb:
156 case kAttr_Index_Index_Verb:
157 rattr(verb, s, rec, writer);
158 break;
159 case kStartElem_Value_Verb:
160 case kStartElem_Index_Verb:
161 relem(verb, s, rec, writer);
162 break;
163 case kEndElem_Verb:
164 writer.endElement();
165 return;
166 default:
167 SkASSERT(!"bad verb");
168 }
169 }
170 }
171
Read(SkStream & s,SkXMLWriter & writer)172 void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
173 {
174 BMLW rec;
175 writer.writeHeader();
176 relem(rbyte(s), s, rec, writer);
177 }
178
Read(SkStream & s,SkWStream & output)179 void BML_XMLParser::Read(SkStream& s, SkWStream& output)
180 {
181 SkXMLStreamWriter writer(&output);
182 Read(s, writer);
183 }
184
Read(SkStream & s,SkXMLParser & output)185 void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
186 {
187 SkXMLParserWriter writer(&output);
188 Read(s, writer);
189 }
190
191
192
193