Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: third_party/libjingle_xmpp/xmllite/xmlparser.cc

Issue 2443903004: Add xmllite and xmpp sources to third_party/ (Closed)
Patch Set: Explicitly use webrtc_overrides/webrtc/base/logging.h Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "third_party/libjingle_xmpp/xmllite/xmlparser.h"
12
13 #include <string>
14 #include <vector>
15
16 #include "third_party/libjingle_xmpp/xmllite/xmlconstants.h"
17 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
18 #include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h"
19 #include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h"
20 #include "third_party/webrtc/base/common.h"
21
22 namespace buzz {
23
24
25 static void
26 StartElementCallback(void * userData, const char *name, const char **atts) {
27 (static_cast<XmlParser *>(userData))->ExpatStartElement(name, atts);
28 }
29
30 static void
31 EndElementCallback(void * userData, const char *name) {
32 (static_cast<XmlParser *>(userData))->ExpatEndElement(name);
33 }
34
35 static void
36 CharacterDataCallback(void * userData, const char *text, int len) {
37 (static_cast<XmlParser *>(userData))->ExpatCharacterData(text, len);
38 }
39
40 static void
41 XmlDeclCallback(void * userData, const char * ver, const char * enc, int st) {
42 (static_cast<XmlParser *>(userData))->ExpatXmlDecl(ver, enc, st);
43 }
44
45 XmlParser::XmlParser(XmlParseHandler *pxph) :
46 pxph_(pxph), sentError_(false) {
47 expat_ = XML_ParserCreate(NULL);
48 XML_SetUserData(expat_, this);
49 XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
50 XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
51 XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
52 }
53
54 void
55 XmlParser::Reset() {
56 if (!XML_ParserReset(expat_, NULL)) {
57 XML_ParserFree(expat_);
58 expat_ = XML_ParserCreate(NULL);
59 }
60 XML_SetUserData(expat_, this);
61 XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
62 XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
63 XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
64 context_.Reset();
65 sentError_ = false;
66 }
67
68 static bool
69 XmlParser_StartsWithXmlns(const char *name) {
70 return name[0] == 'x' &&
71 name[1] == 'm' &&
72 name[2] == 'l' &&
73 name[3] == 'n' &&
74 name[4] == 's';
75 }
76
77 void
78 XmlParser::ExpatStartElement(const char *name, const char **atts) {
79 if (context_.RaisedError() != XML_ERROR_NONE)
80 return;
81 const char **att;
82 context_.StartElement();
83 for (att = atts; *att; att += 2) {
84 if (XmlParser_StartsWithXmlns(*att)) {
85 if ((*att)[5] == '\0') {
86 context_.StartNamespace("", *(att + 1));
87 }
88 else if ((*att)[5] == ':') {
89 if (**(att + 1) == '\0') {
90 // In XML 1.0 empty namespace illegal with prefix (not in 1.1)
91 context_.RaiseError(XML_ERROR_SYNTAX);
92 return;
93 }
94 context_.StartNamespace((*att) + 6, *(att + 1));
95 }
96 }
97 }
98 context_.SetPosition(XML_GetCurrentLineNumber(expat_),
99 XML_GetCurrentColumnNumber(expat_),
100 XML_GetCurrentByteIndex(expat_));
101 pxph_->StartElement(&context_, name, atts);
102 }
103
104 void
105 XmlParser::ExpatEndElement(const char *name) {
106 if (context_.RaisedError() != XML_ERROR_NONE)
107 return;
108 context_.EndElement();
109 context_.SetPosition(XML_GetCurrentLineNumber(expat_),
110 XML_GetCurrentColumnNumber(expat_),
111 XML_GetCurrentByteIndex(expat_));
112 pxph_->EndElement(&context_, name);
113 }
114
115 void
116 XmlParser::ExpatCharacterData(const char *text, int len) {
117 if (context_.RaisedError() != XML_ERROR_NONE)
118 return;
119 context_.SetPosition(XML_GetCurrentLineNumber(expat_),
120 XML_GetCurrentColumnNumber(expat_),
121 XML_GetCurrentByteIndex(expat_));
122 pxph_->CharacterData(&context_, text, len);
123 }
124
125 void
126 XmlParser::ExpatXmlDecl(const char * ver, const char * enc, int standalone) {
127 if (context_.RaisedError() != XML_ERROR_NONE)
128 return;
129
130 if (ver && std::string("1.0") != ver) {
131 context_.RaiseError(XML_ERROR_SYNTAX);
132 return;
133 }
134
135 if (standalone == 0) {
136 context_.RaiseError(XML_ERROR_SYNTAX);
137 return;
138 }
139
140 if (enc && !((enc[0] == 'U' || enc[0] == 'u') &&
141 (enc[1] == 'T' || enc[1] == 't') &&
142 (enc[2] == 'F' || enc[2] == 'f') &&
143 enc[3] == '-' && enc[4] =='8')) {
144 context_.RaiseError(XML_ERROR_INCORRECT_ENCODING);
145 return;
146 }
147
148 }
149
150 bool
151 XmlParser::Parse(const char *data, size_t len, bool isFinal) {
152 if (sentError_)
153 return false;
154
155 if (XML_Parse(expat_, data, static_cast<int>(len), isFinal) !=
156 XML_STATUS_OK) {
157 context_.SetPosition(XML_GetCurrentLineNumber(expat_),
158 XML_GetCurrentColumnNumber(expat_),
159 XML_GetCurrentByteIndex(expat_));
160 context_.RaiseError(XML_GetErrorCode(expat_));
161 }
162
163 if (context_.RaisedError() != XML_ERROR_NONE) {
164 sentError_ = true;
165 pxph_->Error(&context_, context_.RaisedError());
166 return false;
167 }
168
169 return true;
170 }
171
172 XmlParser::~XmlParser() {
173 XML_ParserFree(expat_);
174 }
175
176 void
177 XmlParser::ParseXml(XmlParseHandler *pxph, std::string text) {
178 XmlParser parser(pxph);
179 parser.Parse(text.c_str(), text.length(), true);
180 }
181
182 XmlParser::ParseContext::ParseContext() :
183 xmlnsstack_(),
184 raised_(XML_ERROR_NONE),
185 line_number_(0),
186 column_number_(0),
187 byte_index_(0) {
188 }
189
190 void
191 XmlParser::ParseContext::StartNamespace(const char *prefix, const char *ns) {
192 xmlnsstack_.AddXmlns(*prefix ? prefix : STR_EMPTY, ns);
193 }
194
195 void
196 XmlParser::ParseContext::StartElement() {
197 xmlnsstack_.PushFrame();
198 }
199
200 void
201 XmlParser::ParseContext::EndElement() {
202 xmlnsstack_.PopFrame();
203 }
204
205 QName
206 XmlParser::ParseContext::ResolveQName(const char* qname, bool isAttr) {
207 const char *c;
208 for (c = qname; *c; ++c) {
209 if (*c == ':') {
210 const std::pair<std::string, bool> result =
211 xmlnsstack_.NsForPrefix(std::string(qname, c - qname));
212 if (!result.second)
213 return QName();
214 return QName(result.first, c + 1);
215 }
216 }
217 if (isAttr)
218 return QName(STR_EMPTY, qname);
219
220 std::pair<std::string, bool> result = xmlnsstack_.NsForPrefix(STR_EMPTY);
221 if (!result.second)
222 return QName();
223
224 return QName(result.first, qname);
225 }
226
227 void
228 XmlParser::ParseContext::Reset() {
229 xmlnsstack_.Reset();
230 raised_ = XML_ERROR_NONE;
231 }
232
233 void
234 XmlParser::ParseContext::SetPosition(int line, int column,
235 long byte_index) {
236 line_number_ = line;
237 column_number_ = column;
238 byte_index_ = byte_index;
239 }
240
241 void
242 XmlParser::ParseContext::GetPosition(unsigned long * line,
243 unsigned long * column,
244 unsigned long * byte_index) {
245 if (line != NULL) {
246 *line = static_cast<unsigned long>(line_number_);
247 }
248
249 if (column != NULL) {
250 *column = static_cast<unsigned long>(column_number_);
251 }
252
253 if (byte_index != NULL) {
254 *byte_index = static_cast<unsigned long>(byte_index_);
255 }
256 }
257
258 XmlParser::ParseContext::~ParseContext() {
259 }
260
261 } // namespace buzz
OLDNEW
« no previous file with comments | « third_party/libjingle_xmpp/xmllite/xmlparser.h ('k') | third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698