Home | History | Annotate | Download | only in ports
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkXMLParser.h"
     11 #include "SkString.h"
     12 #include "SkStream.h"
     13 
     14 #include "expat.h"
     15 
     16 #ifdef SK_BUILD_FOR_PPI
     17 #define CHAR_16_TO_9
     18 #endif
     19 
     20 #if defined CHAR_16_TO_9
     21 inline size_t sk_wcslen(const short* char16) {
     22     const short* start = char16;
     23     while (*char16)
     24         char16++;
     25     return char16 - start;
     26 }
     27 
     28 inline const char* ConvertUnicodeToChar(const short* ch16, size_t len, SkAutoMalloc& ch8Malloc) {
     29     char* ch8 = (char*) ch8Malloc.get();
     30     int index;
     31     for (index = 0; index < len; index++)
     32         ch8[index] = (char) ch16[index];
     33     ch8[index] = '\0';
     34     return ch8;
     35 }
     36 #endif
     37 
     38 static void XMLCALL start_proc(void *data, const char *el, const char **attr)
     39 {
     40 #if defined CHAR_16_TO_9
     41     size_t len = sk_wcslen((const short*) el);
     42     SkAutoMalloc    el8(len + 1);
     43     el = ConvertUnicodeToChar((const short*) el, len, el8);
     44 #endif
     45     if (((SkXMLParser*)data)->startElement(el)) {
     46         XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
     47         return;
     48     }
     49     while (*attr)
     50     {
     51         const char* attr0 = attr[0];
     52         const char* attr1 = attr[1];
     53 #if defined CHAR_16_TO_9
     54         size_t len0 = sk_wcslen((const short*) attr0);
     55         SkAutoMalloc    attr0_8(len0 + 1);
     56         attr0 = ConvertUnicodeToChar((const short*) attr0, len0, attr0_8);
     57         size_t len1 = sk_wcslen((const short*) attr1);
     58         SkAutoMalloc    attr1_8(len1 + 1);
     59         attr1 = ConvertUnicodeToChar((const short*) attr1, len1, attr1_8);
     60 #endif
     61         if (((SkXMLParser*)data)->addAttribute(attr0, attr1)) {
     62             XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
     63             return;
     64         }
     65         attr += 2;
     66     }
     67 }
     68 
     69 static void XMLCALL end_proc(void *data, const char *el)
     70 {
     71 #if defined CHAR_16_TO_9
     72     size_t len = sk_wcslen((const short*) el);
     73     SkAutoMalloc    el8(len + 1);
     74     el = ConvertUnicodeToChar((const short*) el, len, el8);
     75 #endif
     76     if (((SkXMLParser*)data)->endElement(el))
     77         XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
     78 }
     79 
     80 static void XMLCALL text_proc(void* data, const char* text, int len)
     81 {
     82 #if defined CHAR_16_TO_9
     83     SkAutoMalloc    text8(len + 1);
     84     text = ConvertUnicodeToChar((const short*) text, len, text8);
     85 #endif
     86     if (((SkXMLParser*)data)->text(text, len))
     87         XML_StopParser((XML_Parser) ((SkXMLParser*)data)->fParser, false);
     88 }
     89 
     90 bool SkXMLParser::parse(const char doc[], size_t len)
     91 {
     92     if (len == 0) {
     93         fError->fCode = SkXMLParserError::kEmptyFile;
     94         reportError(NULL);
     95         return false;
     96     }
     97     XML_Parser p = XML_ParserCreate(NULL);
     98     SkASSERT(p);
     99     fParser = p;
    100     XML_SetElementHandler(p, start_proc, end_proc);
    101     XML_SetCharacterDataHandler(p, text_proc);
    102     XML_SetUserData(p, this);
    103 
    104     bool success = true;
    105     int error = XML_Parse(p, doc, len, true);
    106     if (error == XML_STATUS_ERROR) {
    107         reportError(p);
    108         success = false;
    109     }
    110     XML_ParserFree(p);
    111     return success;
    112 }
    113 
    114 bool SkXMLParser::parse(SkStream& input)
    115 {
    116     size_t          len = input.getLength();
    117     SkAutoMalloc    am(len);
    118     char*           doc = (char*)am.get();
    119 
    120     input.rewind();
    121     size_t  len2 = input.read(doc, len);
    122     SkASSERT(len2 == len);
    123 
    124     return this->parse(doc, len2);
    125 }
    126 
    127 void SkXMLParser::reportError(void* p)
    128 {
    129     XML_Parser parser = (XML_Parser) p;
    130     if (fError && parser) {
    131         fError->fNativeCode = XML_GetErrorCode(parser);
    132         fError->fLineNumber = XML_GetCurrentLineNumber(parser);
    133     }
    134 }
    135 
    136 void SkXMLParser::GetNativeErrorString(int error, SkString* str)
    137 {
    138     if (str)
    139         str->set(XML_ErrorString((XML_Error) error));
    140 }
    141