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