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 193