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