• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
sk_wcslen(const short * char16)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 
ConvertUnicodeToChar(const short * ch16,size_t len,SkAutoMalloc & ch8Malloc)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 
start_proc(void * data,const char * el,const char ** attr)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 
end_proc(void * data,const char * el)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 
text_proc(void * data,const char * text,int len)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 
parse(const char doc[],size_t len)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 
parse(SkStream & input)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 
reportError(void * p)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 
GetNativeErrorString(int error,SkString * str)144 void SkXMLParser::GetNativeErrorString(int error, SkString* str)
145 {
146     if (str)
147         str->set(XML_ErrorString((XML_Error) error));
148 }
149 
150