• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
sk_wcslen(const short * char16)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 
ConvertUnicodeToChar(const short * ch16,size_t len,SkAutoMalloc & ch8Malloc)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 
start_proc(void * data,const char * el,const char ** attr)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 
end_proc(void * data,const char * el)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 
text_proc(void * data,const char * text,int len)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 
parse(const char doc[],size_t len)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 
parse(SkStream & input)114 bool SkXMLParser::parse(SkStream& input)
115 {
116     size_t          len = input.read(NULL, 0);
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 
reportError(void * p)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 
GetNativeErrorString(int error,SkString * str)136 void SkXMLParser::GetNativeErrorString(int error, SkString* str)
137 {
138     if (str)
139         str->set(XML_ErrorString((XML_Error) error));
140 }
141 
142