OLD | NEW |
| (Empty) |
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 | |
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 | |
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 | |
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 | |
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 | |
78 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 } | |
86 ~BMLW() | |
87 { | |
88 freeAll(fElems); | |
89 freeAll(fNames); | |
90 freeAll(fValues); | |
91 } | |
92 }; | |
93 | |
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 | |
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 | |
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 | |
179 void BML_XMLParser::Read(SkStream& s, SkWStream& output) | |
180 { | |
181 SkXMLStreamWriter writer(&output); | |
182 Read(s, writer); | |
183 } | |
184 | |
185 void BML_XMLParser::Read(SkStream& s, SkXMLParser& output) | |
186 { | |
187 SkXMLParserWriter writer(&output); | |
188 Read(s, writer); | |
189 } | |
190 | |
191 | |
192 | |
OLD | NEW |