gfx/skia/trunk/src/xml/SkBML_XMLParser.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial