Refactor SignatureValidator and reduce interface headers
[platform/core/security/cert-svc.git] / vcore / vcore / SaxReader.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        SaxReader.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Simple c++ interface for libxml2.
21  */
22 #include <dpl/assert.h>
23 #include <dpl/log/log.h>
24
25 #include <vcore/SaxReader.h>
26
27 namespace ValidationCore {
28
29
30 SaxReader::SaxReader() :
31     m_reader(0)
32 {
33 }
34
35 SaxReader::~SaxReader()
36 {
37     if (m_reader) {
38         deinitialize();
39     }
40 }
41
42 void SaxReader::initialize(
43     const std::string &filename,
44     bool defaultArgs,
45     ValidationType validate,
46     const std::string &schema)
47 {
48     Assert(m_reader == 0 && "Double initialization of SaxReader");
49
50     LogDebug("SaxReader opening file: " << filename);
51
52     m_reader = xmlNewTextReaderFilename(filename.c_str());
53
54     if (!m_reader) {
55         VcoreThrowMsg(SaxReader::Exception::FileOpeningError,
56                       "opening file " << filename << " error");
57     }
58
59     if (validate == VALIDATION_XMLSCHEME &&
60         xmlTextReaderSchemaValidate(m_reader, schema.c_str())) {
61         /*
62          * unable to turn on schema validation
63          */
64         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
65                       "Turn on Schema validation failed");
66     }
67
68     // Path to DTD schema is taken from xml file.
69     if (validate == VALIDATION_DTD &&
70         xmlTextReaderSetParserProp(m_reader, XML_PARSER_VALIDATE, 1)) {
71         /*
72          * unable to turn on DTD validation
73          */
74         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
75                               "Turn on DTD validation failed!");
76     }
77
78     if (defaultArgs &&
79         xmlTextReaderSetParserProp(m_reader, XML_PARSER_DEFAULTATTRS, 1)) {
80         /*
81          * unable to turn on default arguments
82          */
83         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
84                               "Turn on default arguments failed");
85     }
86 }
87
88 void SaxReader::deinitialize()
89 {
90     xmlFreeTextReader(m_reader);
91     m_reader = 0;
92 }
93
94 bool SaxReader::next()
95 {
96     int res = xmlTextReaderRead(m_reader);
97
98     if (res < 0)
99         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
100                       "xmlTextReaderRead error");
101
102     if (!xmlTextReaderIsValid(m_reader))
103         VcoreThrowMsg(SaxReader::Exception::FileNotValid,
104                       "xmlTextReader is invalid");
105
106     return res ? true : false;
107 }
108
109 void SaxReader::next(const std::string &token)
110 {
111     int res = xmlTextReaderRead(m_reader);
112
113     if (res < 0)
114         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
115                       "xmlTextReaderRead error");
116
117     if (!xmlTextReaderIsValid(m_reader))
118         VcoreThrowMsg(SaxReader::Exception::FileNotValid,
119                       "xmlTextReader is invalid");
120
121     xmlChar *name = xmlTextReaderName(m_reader);
122
123     if (!name)
124         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
125                       "xmlTextReaderName returns NULL");
126
127     xmlChar *xmlToken = xmlCharStrdup(token.c_str());
128
129     if (xmlStrcmp(name, xmlToken)) {
130         xmlFree(name);
131         xmlFree(xmlToken);
132
133         VcoreThrowMsg(SaxReader::Exception::WrongToken, "Wrong Token");
134     }
135
136     xmlFree(name);
137     xmlFree(xmlToken);
138 }
139
140 bool SaxReader::isEmpty(void)
141 {
142     int ret = xmlTextReaderIsEmptyElement(m_reader);
143     if (-1 == ret)
144         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
145                       "xmlTextReaderIsEmptyElement error");
146
147     return ret ? true : false;
148 }
149
150 std::string SaxReader::attribute(const std::string &token, ThrowType throwStatus)
151 {
152     xmlChar *attr = xmlTextReaderGetAttribute(m_reader, BAD_CAST(token.c_str()));
153     if (!attr) {
154         if (throwStatus == THROW_DISABLE) {
155             return std::string();
156         }
157         else {
158             VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
159                           "xmlTextReaderGetAttribute error");
160         }
161     }
162
163     std::string value = reinterpret_cast<const char *>(attr);
164     xmlFree(attr);
165
166     return value;
167 }
168
169 std::string SaxReader::name()
170 {
171     xmlChar *name = xmlTextReaderName(m_reader);
172     if (!name)
173         VcoreThrowMsg(SaxReader::Exception::ReadingNameError,
174                       "reading name error");
175
176     std::string value = reinterpret_cast<const char *>(name);
177     xmlFree(name);
178     size_t pos = value.find_last_of(":");
179     if (pos != std::string::npos) {
180         value.erase(0, pos + 1);
181     }
182
183     return value;
184 }
185
186 std::string SaxReader::namespaceURI()
187 {
188     xmlChar *name = xmlTextReaderNamespaceUri(m_reader);
189     if (!name) {
190         return std::string();
191     }
192
193     std::string value = reinterpret_cast<const char *>(name);
194     xmlFree(name);
195
196     return value;
197 }
198
199 std::string SaxReader::value()
200 {
201     xmlChar *text = xmlTextReaderValue(m_reader);
202     if (!text)
203         VcoreThrowMsg(SaxReader::Exception::ReadingValueError,
204                       "reading value error");
205
206     std::string value = reinterpret_cast<const char*>(text);
207     xmlFree(text);
208
209     return value;
210 }
211
212 SaxReader::NodeType SaxReader::type()
213 {
214     xmlReaderTypes type =
215         static_cast<xmlReaderTypes>(xmlTextReaderNodeType(m_reader));
216     switch (type) {
217     case XML_READER_TYPE_ELEMENT:
218         return NODE_BEGIN;
219     case XML_READER_TYPE_END_ELEMENT:
220         return NODE_END;
221     case XML_READER_TYPE_TEXT:
222         return NODE_TEXT;
223     case XML_READER_TYPE_NONE:
224     case XML_READER_TYPE_ATTRIBUTE:
225     case XML_READER_TYPE_CDATA:
226     case XML_READER_TYPE_ENTITY_REFERENCE:
227     case XML_READER_TYPE_ENTITY:
228     case XML_READER_TYPE_PROCESSING_INSTRUCTION:
229     case XML_READER_TYPE_COMMENT:
230     case XML_READER_TYPE_DOCUMENT:
231     case XML_READER_TYPE_DOCUMENT_TYPE:
232     case XML_READER_TYPE_DOCUMENT_FRAGMENT:
233     case XML_READER_TYPE_NOTATION:
234     case XML_READER_TYPE_WHITESPACE:
235     case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
236     case XML_READER_TYPE_END_ENTITY:
237     case XML_READER_TYPE_XML_DECLARATION:
238     default:
239         return NODE_UNSUPPORTED;
240     }
241 }
242
243 void SaxReader::dumpNode(std::string &buffer)
244 {
245     xmlBufferPtr buff = xmlBufferCreate();
246
247     xmlNodePtr node = xmlTextReaderExpand(m_reader);
248     if (!node) {
249         xmlBufferFree(buff);
250         VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
251                       "xmlTextReaderExpand error");
252     }
253
254     int size = xmlNodeDump(buff, node->doc, node, 0, 0);
255     if (size > 0) {
256         buffer.insert(0, reinterpret_cast<char*>(buff->content), size);
257     }
258     xmlBufferFree(buff);
259 }
260
261 } // namespace ValidationCore