| 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 |