OLD | NEW |
| (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 "webrtc/libjingle/xmllite/xmlbuilder.h" | |
12 | |
13 #include <set> | |
14 #include <vector> | |
15 #include "webrtc/libjingle/xmllite/xmlconstants.h" | |
16 #include "webrtc/libjingle/xmllite/xmlelement.h" | |
17 #include "webrtc/base/common.h" | |
18 | |
19 namespace buzz { | |
20 | |
21 XmlBuilder::XmlBuilder() : | |
22 pelCurrent_(NULL), | |
23 pelRoot_(), | |
24 pvParents_(new std::vector<XmlElement *>()) { | |
25 } | |
26 | |
27 void | |
28 XmlBuilder::Reset() { | |
29 pelRoot_.reset(); | |
30 pelCurrent_ = NULL; | |
31 pvParents_->clear(); | |
32 } | |
33 | |
34 XmlElement * | |
35 XmlBuilder::BuildElement(XmlParseContext * pctx, | |
36 const char * name, const char ** atts) { | |
37 QName tagName(pctx->ResolveQName(name, false)); | |
38 if (tagName.IsEmpty()) | |
39 return NULL; | |
40 | |
41 XmlElement * pelNew = new XmlElement(tagName); | |
42 | |
43 if (!*atts) | |
44 return pelNew; | |
45 | |
46 std::set<QName> seenNonlocalAtts; | |
47 | |
48 while (*atts) { | |
49 QName attName(pctx->ResolveQName(*atts, true)); | |
50 if (attName.IsEmpty()) { | |
51 delete pelNew; | |
52 return NULL; | |
53 } | |
54 | |
55 // verify that namespaced names are unique | |
56 if (!attName.Namespace().empty()) { | |
57 if (seenNonlocalAtts.count(attName)) { | |
58 delete pelNew; | |
59 return NULL; | |
60 } | |
61 seenNonlocalAtts.insert(attName); | |
62 } | |
63 | |
64 pelNew->AddAttr(attName, std::string(*(atts + 1))); | |
65 atts += 2; | |
66 } | |
67 | |
68 return pelNew; | |
69 } | |
70 | |
71 void | |
72 XmlBuilder::StartElement(XmlParseContext * pctx, | |
73 const char * name, const char ** atts) { | |
74 XmlElement * pelNew = BuildElement(pctx, name, atts); | |
75 if (pelNew == NULL) { | |
76 pctx->RaiseError(XML_ERROR_SYNTAX); | |
77 return; | |
78 } | |
79 | |
80 if (!pelCurrent_) { | |
81 pelCurrent_ = pelNew; | |
82 pelRoot_.reset(pelNew); | |
83 pvParents_->push_back(NULL); | |
84 } else { | |
85 pelCurrent_->AddElement(pelNew); | |
86 pvParents_->push_back(pelCurrent_); | |
87 pelCurrent_ = pelNew; | |
88 } | |
89 } | |
90 | |
91 void | |
92 XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) { | |
93 RTC_UNUSED(pctx); | |
94 RTC_UNUSED(name); | |
95 pelCurrent_ = pvParents_->back(); | |
96 pvParents_->pop_back(); | |
97 } | |
98 | |
99 void | |
100 XmlBuilder::CharacterData(XmlParseContext * pctx, | |
101 const char * text, int len) { | |
102 RTC_UNUSED(pctx); | |
103 if (pelCurrent_) { | |
104 pelCurrent_->AddParsedText(text, len); | |
105 } | |
106 } | |
107 | |
108 void | |
109 XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) { | |
110 RTC_UNUSED(pctx); | |
111 RTC_UNUSED(err); | |
112 pelRoot_.reset(NULL); | |
113 pelCurrent_ = NULL; | |
114 pvParents_->clear(); | |
115 } | |
116 | |
117 XmlElement * | |
118 XmlBuilder::CreateElement() { | |
119 return pelRoot_.release(); | |
120 } | |
121 | |
122 XmlElement * | |
123 XmlBuilder::BuiltElement() { | |
124 return pelRoot_.get(); | |
125 } | |
126 | |
127 XmlBuilder::~XmlBuilder() { | |
128 } | |
129 | |
130 } // namespace buzz | |
OLD | NEW |