aboutsummaryrefslogtreecommitdiffstats
path: root/libsgl/xml/SkBML_XMLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsgl/xml/SkBML_XMLParser.cpp')
-rw-r--r--libsgl/xml/SkBML_XMLParser.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/libsgl/xml/SkBML_XMLParser.cpp b/libsgl/xml/SkBML_XMLParser.cpp
new file mode 100644
index 0000000..53b7f61
--- /dev/null
+++ b/libsgl/xml/SkBML_XMLParser.cpp
@@ -0,0 +1,192 @@
+/* libs/graphics/xml/SkBML_XMLParser.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkBML_XMLParser.h"
+#include "SkBML_Verbs.h"
+#include "SkStream.h"
+#include "SkXMLWriter.h"
+
+static uint8_t rbyte(SkStream& s)
+{
+ uint8_t b;
+ size_t size = s.read(&b, 1);
+ SkASSERT(size == 1);
+ return b;
+}
+
+static int rdata(SkStream& s, int data)
+{
+ SkASSERT((data & ~31) == 0);
+ if (data == 31)
+ {
+ data = rbyte(s);
+ if (data == 0xFF)
+ {
+ data = rbyte(s);
+ data = (data << 8) | rbyte(s);
+ }
+ }
+ return data;
+}
+
+static void set(char* array[256], int index, SkStream& s, int data)
+{
+ SkASSERT((unsigned)index <= 255);
+
+ size_t size = rdata(s, data);
+
+ if (array[index] == NULL)
+ array[index] = (char*)sk_malloc_throw(size + 1);
+ else
+ {
+ if (strlen(array[index]) < size)
+ array[index] = (char*)sk_realloc_throw(array[index], size + 1);
+ }
+
+ s.read(array[index], size);
+ array[index][size] = 0;
+}
+
+static void freeAll(char* array[256])
+{
+ for (int i = 0; i < 256; i++)
+ sk_free(array[i]);
+}
+
+struct BMLW {
+ char* fElems[256];
+ char* fNames[256];
+ char* fValues[256];
+
+ // important that these are uint8_t, so we get automatic wrap-around
+ uint8_t fNextElem, fNextName, fNextValue;
+
+ BMLW()
+ {
+ memset(fElems, 0, sizeof(fElems));
+ memset(fNames, 0, sizeof(fNames));
+ memset(fValues, 0, sizeof(fValues));
+
+ fNextElem = fNextName = fNextValue = 0;
+ }
+ ~BMLW()
+ {
+ freeAll(fElems);
+ freeAll(fNames);
+ freeAll(fValues);
+ }
+};
+
+static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
+{
+ int data = verb & 31;
+ verb >>= 5;
+
+ int nameIndex, valueIndex;
+
+ switch (verb) {
+ case kAttr_Value_Value_Verb:
+ nameIndex = rec.fNextName; // record before the ++
+ set(rec.fNames, rec.fNextName++, s, data);
+ valueIndex = rec.fNextValue; // record before the ++
+ set(rec.fValues, rec.fNextValue++, s, 31);
+ break;
+ case kAttr_Value_Index_Verb:
+ nameIndex = rec.fNextName; // record before the ++
+ set(rec.fNames, rec.fNextName++, s, data);
+ valueIndex = rbyte(s);
+ break;
+ case kAttr_Index_Value_Verb:
+ nameIndex = rdata(s, data);
+ valueIndex = rec.fNextValue; // record before the ++
+ set(rec.fValues, rec.fNextValue++, s, 31);
+ break;
+ case kAttr_Index_Index_Verb:
+ nameIndex = rdata(s, data);
+ valueIndex = rbyte(s);
+ break;
+ default:
+ SkASSERT(!"bad verb");
+ return;
+ }
+ writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
+}
+
+static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
+{
+ int data = verb & 31;
+ verb >>= 5;
+
+ int elemIndex;
+
+ if (verb == kStartElem_Value_Verb)
+ {
+ elemIndex = rec.fNextElem; // record before the ++
+ set(rec.fElems, rec.fNextElem++, s, data);
+ }
+ else
+ {
+ SkASSERT(verb == kStartElem_Index_Verb);
+ elemIndex = rdata(s, data);
+ }
+
+ writer.startElement(rec.fElems[elemIndex]);
+
+ for (;;)
+ {
+ verb = rbyte(s);
+ switch (verb >> 5) {
+ case kAttr_Value_Value_Verb:
+ case kAttr_Value_Index_Verb:
+ case kAttr_Index_Value_Verb:
+ case kAttr_Index_Index_Verb:
+ rattr(verb, s, rec, writer);
+ break;
+ case kStartElem_Value_Verb:
+ case kStartElem_Index_Verb:
+ relem(verb, s, rec, writer);
+ break;
+ case kEndElem_Verb:
+ writer.endElement();
+ return;
+ default:
+ SkASSERT(!"bad verb");
+ }
+ }
+}
+
+void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
+{
+ BMLW rec;
+ writer.writeHeader();
+ relem(rbyte(s), s, rec, writer);
+}
+
+void BML_XMLParser::Read(SkStream& s, SkWStream& output)
+{
+ SkXMLStreamWriter writer(&output);
+ Read(s, writer);
+}
+
+void BML_XMLParser::Read(SkStream& s, SkXMLParser& output)
+{
+ SkXMLParserWriter writer(&output);
+ Read(s, writer);
+}
+
+
+