180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBML_XMLParser.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBML_Verbs.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXMLWriter.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint8_t rbyte(SkStream& s) 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t b; 18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkDEBUGCODE(size_t size = ) s.read(&b, 1); 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(size == 1); 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return b; 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int rdata(SkStream& s, int data) 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((data & ~31) == 0); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (data == 31) 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data = rbyte(s); 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (data == 0xFF) 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data = rbyte(s); 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data = (data << 8) | rbyte(s); 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return data; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void set(char* array[256], int index, SkStream& s, int data) 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)index <= 255); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t size = rdata(s, data); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (array[index] == NULL) 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru array[index] = (char*)sk_malloc_throw(size + 1); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (strlen(array[index]) < size) 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru array[index] = (char*)sk_realloc_throw(array[index], size + 1); 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru s.read(array[index], size); 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru array[index][size] = 0; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void freeAll(char* array[256]) 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 256; i++) 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(array[i]); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct BMLW { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* fElems[256]; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* fNames[256]; 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* fValues[256]; 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // important that these are uint8_t, so we get automatic wrap-around 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint8_t fNextElem, fNextName, fNextValue; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BMLW() 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(fElems, 0, sizeof(fElems)); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(fNames, 0, sizeof(fNames)); 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(fValues, 0, sizeof(fValues)); 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNextElem = fNextName = fNextValue = 0; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~BMLW() 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru freeAll(fElems); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru freeAll(fNames); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru freeAll(fValues); 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer) 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int data = verb & 31; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verb >>= 5; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int nameIndex, valueIndex; 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (verb) { 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Value_Value_Verb: 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nameIndex = rec.fNextName; // record before the ++ 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set(rec.fNames, rec.fNextName++, s, data); 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valueIndex = rec.fNextValue; // record before the ++ 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set(rec.fValues, rec.fNextValue++, s, 31); 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Value_Index_Verb: 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nameIndex = rec.fNextName; // record before the ++ 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set(rec.fNames, rec.fNextName++, s, data); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valueIndex = rbyte(s); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Index_Value_Verb: 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nameIndex = rdata(s, data); 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valueIndex = rec.fNextValue; // record before the ++ 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set(rec.fValues, rec.fNextValue++, s, 31); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Index_Index_Verb: 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nameIndex = rdata(s, data); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru valueIndex = rbyte(s); 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGFAIL("bad verb"); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer) 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int data = verb & 31; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verb >>= 5; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int elemIndex; 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (verb == kStartElem_Value_Verb) 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru elemIndex = rec.fNextElem; // record before the ++ 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set(rec.fElems, rec.fNextElem++, s, data); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(verb == kStartElem_Index_Verb); 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru elemIndex = rdata(s, data); 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru writer.startElement(rec.fElems[elemIndex]); 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (;;) 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verb = rbyte(s); 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (verb >> 5) { 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Value_Value_Verb: 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Value_Index_Verb: 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Index_Value_Verb: 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kAttr_Index_Index_Verb: 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rattr(verb, s, rec, writer); 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kStartElem_Value_Verb: 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kStartElem_Index_Verb: 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru relem(verb, s, rec, writer); 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kEndElem_Verb: 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru writer.endElement(); 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGFAIL("bad verb"); 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer) 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BMLW rec; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru writer.writeHeader(); 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru relem(rbyte(s), s, rec, writer); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkWStream& output) 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXMLStreamWriter writer(&output); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Read(s, writer); 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid BML_XMLParser::Read(SkStream& s, SkXMLParser& output) 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXMLParserWriter writer(&output); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Read(s, writer); 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 182