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