Line data Source code
1 : /*************************************************************************
2 : *
3 : * Copyright (c) 2010 Kohei Yoshida
4 : *
5 : * Permission is hereby granted, free of charge, to any person
6 : * obtaining a copy of this software and associated documentation
7 : * files (the "Software"), to deal in the Software without
8 : * restriction, including without limitation the rights to use,
9 : * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 : * copies of the Software, and to permit persons to whom the
11 : * Software is furnished to do so, subject to the following
12 : * conditions:
13 : *
14 : * The above copyright notice and this permission notice shall be
15 : * included in all copies or substantial portions of the Software.
16 : *
17 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 : * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 : * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 : * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 : * OTHER DEALINGS IN THE SOFTWARE.
25 : *
26 : ************************************************************************/
27 :
28 : #include "orcus/xml_context.hpp"
29 : #include "orcus/exception.hpp"
30 : #include "orcus/tokens.hpp"
31 :
32 : #include <iostream>
33 : #include <sstream>
34 :
35 : using namespace std;
36 :
37 : namespace orcus {
38 :
39 : namespace {
40 :
41 0 : void print_stack(const tokens& tokens, const xml_elem_stack_t& elem_stack)
42 : {
43 0 : cerr << "[ ";
44 : xml_elem_stack_t::const_iterator itr, itr_beg = elem_stack.begin(), itr_end = elem_stack.end();
45 0 : for (itr = itr_beg; itr != itr_end; ++itr)
46 : {
47 0 : if (itr != itr_beg)
48 0 : cerr << " -> ";
49 0 : cerr << tokens.get_nstoken_name(itr->first) << ":" << tokens.get_token_name(itr->second);
50 : }
51 0 : cerr << " ]";
52 0 : }
53 :
54 : }
55 :
56 0 : xml_context_base::xml_context_base(const tokens& tokens) :
57 : m_tokens(tokens),
58 0 : m_default_ns(XMLNS_UNKNOWN_TOKEN)
59 0 : {}
60 :
61 0 : xml_context_base::~xml_context_base()
62 : {
63 0 : }
64 :
65 0 : const tokens& xml_context_base::get_tokens() const
66 : {
67 0 : return m_tokens;
68 : }
69 :
70 0 : xml_token_pair_t xml_context_base::push_stack(xmlns_token_t ns, xml_token_t name)
71 : {
72 0 : if (ns == XMLNS_UNKNOWN_TOKEN)
73 0 : ns = m_default_ns;
74 :
75 0 : xml_token_pair_t parent = m_stack.empty() ? xml_token_pair_t(XMLNS_UNKNOWN_TOKEN, XML_UNKNOWN_TOKEN) : m_stack.back();
76 0 : m_stack.push_back(xml_token_pair_t(ns, name));
77 0 : return parent;
78 : }
79 :
80 0 : bool xml_context_base::pop_stack(xmlns_token_t ns, xml_token_t name)
81 : {
82 0 : if (ns == XMLNS_UNKNOWN_TOKEN)
83 0 : ns = m_default_ns;
84 :
85 : const xml_token_pair_t& r = m_stack.back();
86 :
87 0 : if (ns != r.first || name != r.second)
88 0 : throw general_error("mismatched element name");
89 :
90 : m_stack.pop_back();
91 0 : return m_stack.empty();
92 : }
93 :
94 0 : xml_token_pair_t& xml_context_base::get_current_element()
95 : {
96 0 : if (m_stack.empty())
97 0 : throw general_error("element stack is empty!");
98 0 : return m_stack.back();
99 : }
100 :
101 0 : const xml_token_pair_t& xml_context_base::get_current_element() const
102 : {
103 0 : if (m_stack.empty())
104 0 : throw general_error("element stack is empty!");
105 0 : return m_stack.back();
106 : }
107 :
108 0 : xml_token_pair_t& xml_context_base::get_parent_element()
109 : {
110 0 : if(m_stack.size() < 2)
111 0 : throw general_error("element stack has no parent element");
112 :
113 0 : return m_stack[m_stack.size() - 2];
114 : }
115 :
116 0 : const xml_token_pair_t& xml_context_base::get_parent_element() const
117 : {
118 0 : if(m_stack.size() < 2)
119 0 : throw general_error("element stack has no parent element");
120 :
121 0 : return m_stack[m_stack.size() - 2];
122 : }
123 :
124 0 : void xml_context_base::warn_unhandled() const
125 : {
126 0 : cerr << "warning: unhandled element ";
127 0 : print_stack(m_tokens, m_stack);
128 : cerr << endl;
129 0 : }
130 :
131 0 : void xml_context_base::warn_unexpected() const
132 : {
133 0 : cerr << "warning: unexpected element ";
134 0 : print_stack(m_tokens, m_stack);
135 : cerr << endl;
136 0 : }
137 :
138 0 : void xml_context_base::warn(const char* msg) const
139 : {
140 0 : cerr << "warning: " << msg << endl;
141 0 : }
142 :
143 0 : void xml_context_base::set_default_ns(xmlns_token_t ns)
144 : {
145 0 : m_default_ns = ns;
146 0 : }
147 :
148 0 : xmlns_token_t xml_context_base::get_default_ns() const
149 : {
150 0 : return m_default_ns;
151 : }
152 :
153 0 : void xml_context_base::xml_element_expected(
154 : const xml_token_pair_t& elem, xmlns_token_t ns, xml_token_t name,
155 : const string* error)
156 : {
157 0 : if (elem.first == ns && elem.second == name)
158 : // This is an expected element. Good.
159 0 : return;
160 :
161 0 : if (error)
162 : {
163 0 : throw xml_structure_error(*error);
164 : }
165 :
166 : // Create a generic error message.
167 0 : ostringstream os;
168 0 : os << "element '" << m_tokens.get_nstoken_name(ns) << ":" << m_tokens.get_token_name(name) << "' expected, but '";
169 0 : os << m_tokens.get_nstoken_name(elem.first) << ":" << m_tokens.get_token_name(elem.second) << "' encountered.";
170 0 : throw xml_structure_error(os.str());
171 : }
172 :
173 0 : void xml_context_base::xml_element_expected(
174 : const xml_token_pair_t& elem, const xml_elem_stack_t& expected_elems)
175 : {
176 : xml_elem_stack_t::const_iterator itr = expected_elems.begin(), itr_end = expected_elems.end();
177 0 : for (; itr != itr_end; ++itr)
178 : {
179 0 : if (elem == *itr)
180 0 : return;
181 : }
182 :
183 : // Create a generic error message.
184 0 : ostringstream os;
185 0 : os << "unexpected element encountered: " << m_tokens.get_nstoken_name(elem.first) << ":" << m_tokens.get_token_name(elem.second);
186 0 : throw xml_structure_error(os.str());
187 : }
188 :
189 24 : }
|