tizen beta release
[framework/web/wrt-commons.git] / modules / vcore / src / 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/exception.h>
24 #include <dpl/log/log.h>
25
26 #include "SaxReader.h"
27
28 namespace ValidationCore {
29 SaxReader::SaxReader() :
30     m_reader(0)
31 {
32 }
33
34 SaxReader::~SaxReader()
35 {
36     if (m_reader) {
37         deinitialize();
38     }
39 }
40
41 void SaxReader::initialize(const std::string &filename,
42         bool defaultArgs,
43         ValidationType validate,
44         const std::string &schema)
45 {
46     Assert(m_reader == 0 && "Double initialization of SaxReader");
47
48     LogDebug("SaxReader opening file: " << filename);
49
50     /*
51      * create a new xml text reader
52      */
53     m_reader = xmlNewTextReaderFilename(filename.c_str());
54
55     if (m_reader == NULL) {
56         /*
57          * no such file, return
58          */
59         LogWarning("Error during opening file " << filename);
60         Throw(Exception::FileOpeningError);
61     }
62     if (validate == VALIDATION_XMLSCHEME &&
63         xmlTextReaderSchemaValidate(m_reader, schema.c_str())) {
64         /*
65          * unable to turn on schema validation
66          */
67         LogError("Turn on Schema validation failed.");
68         ThrowMsg(Exception::ParserInternalError,
69                  "Turn on Scheme validation failed!");
70     }
71     // Path to DTD schema is taken from xml file.
72     if (validate == VALIDATION_DTD &&
73         xmlTextReaderSetParserProp(m_reader, XML_PARSER_VALIDATE, 1)) {
74         /*
75          * unable to turn on DTD validation
76          */
77         LogError("Turn on DTD validation failed!");
78         ThrowMsg(Exception::ParserInternalError,
79                  "Turn on DTD validation failed!");
80     }
81     if (defaultArgs &&
82         xmlTextReaderSetParserProp(m_reader, XML_PARSER_DEFAULTATTRS, 1)) {
83         /*
84          * unable to turn on default arguments
85          */
86         LogError("Turn on default arguments failed");
87         ThrowMsg(Exception::ParserInternalError,
88                  "Turn on Default Arguments failed!");
89     }
90 }
91
92 void SaxReader::deinitialize()
93 {
94     xmlFreeTextReader(m_reader);
95     m_reader = 0;
96 }
97
98 bool SaxReader::next()
99 {
100     int res = xmlTextReaderRead(m_reader);
101
102     if (0 == xmlTextReaderIsValid(m_reader)) {
103         LogWarning("Throw exception file not valid!");
104         Throw(Exception::FileNotValid);
105     }
106
107     if (res == 1) {
108         return true;
109     }
110
111     if (res == 0) {
112         return false;
113     }
114     LogError("ParserInternalError");
115     Throw(Exception::ParserInternalError);
116 }
117
118 void SaxReader::next(const std::string &token)
119 {
120     xmlTextReaderRead(m_reader);
121     if (0 == xmlTextReaderIsValid(m_reader)) {
122         /*
123          * invalid file
124          */
125         LogWarning("Throw exception file not valid!");
126         Throw(Exception::FileNotValid);
127     }
128
129     xmlChar *name = xmlTextReaderName(m_reader);
130
131     if (name == NULL) {
132         /*
133          * invalid file
134          */
135         LogWarning("File not Valid");
136         Throw(Exception::FileNotValid);
137     }
138
139     if (token == reinterpret_cast<const char*>(name)) {
140         xmlFree(name);
141     } else {
142         /*
143          * we encountered wrong token
144          */
145         xmlFree(name);
146         LogWarning("Wrong Token");
147         Throw(Exception::WrongToken);
148     }
149 }
150
151 bool SaxReader::isEmpty(void)
152 {
153     int ret = xmlTextReaderIsEmptyElement(m_reader);
154     if (-1 == ret) {
155         LogError("Parser Internal Error");
156         Throw(Exception::ParserInternalErrorInEmptyQuery);
157     }
158     return ret;
159 }
160
161 std::string SaxReader::attribute(const std::string &token,
162         ThrowType throwStatus)
163 {
164     std::string value;
165     xmlChar *attr = xmlTextReaderGetAttribute(m_reader, BAD_CAST(token.c_str()));
166     if ((NULL == attr) && (throwStatus == THROW_DISABLE)) {
167         /*
168          * return empty string
169          */
170         //TODO why not DPL::Optional?
171         return std::string();
172     }
173     if (NULL == attr) {
174         /*
175          * error during read attribute
176          */
177         LogError("Error in reading attribute.");
178         Throw(Exception::ParserInternalErrorInReadingAttribute);
179     }
180
181     /*
182      * cast it to val and return it
183      */
184     value = reinterpret_cast<const char *>(attr);
185     xmlFree(attr);
186     return value;
187 }
188
189 // KW std::string SaxReader::fullName(){
190 // KW     std::string value;
191 // KW     xmlChar *name = xmlTextReaderName(m_reader);
192 // KW     if(NULL == name) {
193 // KW         LogError("Error in reading name.");
194 // KW         Throw(Exception::ErrorReadingName);
195 // KW     }
196 // KW     value = reinterpret_cast<const char *>(name);
197 // KW     xmlFree(name);
198 // KW     return value;
199 // KW }
200
201 std::string SaxReader::name()
202 {
203     std::string value;
204     xmlChar *name = xmlTextReaderName(m_reader);
205     if (NULL == name) {
206         LogError("Error in reading name.");
207         Throw(Exception::ErrorReadingName);
208     }
209     value = reinterpret_cast<const char *>(name);
210     xmlFree(name);
211     size_t pos = value.find_last_of(":");
212     if (pos != std::string::npos) {
213         value.erase(0, pos + 1);
214     }
215     return value;
216 }
217
218 std::string SaxReader::namespaceURI()
219 {
220     std::string value;
221     xmlChar *name = xmlTextReaderNamespaceUri(m_reader);
222     if (NULL != name) {
223         value = reinterpret_cast<const char *>(name);
224         xmlFree(name);
225     }
226     return value;
227 }
228
229 std::string SaxReader::value()
230 {
231     std::string value;
232     /*
233      * get value of node
234      */
235     xmlChar *text = xmlTextReaderValue(m_reader);
236     if (NULL == text) {
237         LogError("Error in reading value");
238         Throw(Exception::ErrorReadingValue);
239     }
240     value = reinterpret_cast<const char*>(text);
241     /*
242      * free text and return the val
243      */
244     xmlFree(text);
245     return value;
246 }
247
248 SaxReader::NodeType SaxReader::type()
249 {
250     xmlReaderTypes type =
251         static_cast<xmlReaderTypes>(xmlTextReaderNodeType(m_reader));
252     switch (type) {
253     case XML_READER_TYPE_ELEMENT:
254         return NODE_BEGIN;
255     case XML_READER_TYPE_END_ELEMENT:
256         return NODE_END;
257     case XML_READER_TYPE_TEXT:
258         return NODE_TEXT;
259     case XML_READER_TYPE_NONE:
260     case XML_READER_TYPE_ATTRIBUTE:
261     case XML_READER_TYPE_CDATA:
262     case XML_READER_TYPE_ENTITY_REFERENCE:
263     case XML_READER_TYPE_ENTITY:
264     case XML_READER_TYPE_PROCESSING_INSTRUCTION:
265     case XML_READER_TYPE_COMMENT:
266     case XML_READER_TYPE_DOCUMENT:
267     case XML_READER_TYPE_DOCUMENT_TYPE:
268     case XML_READER_TYPE_DOCUMENT_FRAGMENT:
269     case XML_READER_TYPE_NOTATION:
270     case XML_READER_TYPE_WHITESPACE:
271     case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
272     case XML_READER_TYPE_END_ENTITY:
273     case XML_READER_TYPE_XML_DECLARATION:
274     default:
275         return NODE_UNSUPPORTED;
276     }
277 }
278
279 void SaxReader::dumpNode(std::string &buffer)
280 {
281     /*
282      * size of buffer
283      */
284     int size;
285     /*
286      * pointer to buffer
287      */
288     xmlBufferPtr buff = xmlBufferCreate();
289
290     xmlNodePtr node = xmlTextReaderExpand(m_reader);
291
292     if (node == NULL) {
293         /*
294          * internal parser error
295          */
296         xmlBufferFree(buff);
297         LogError("Parser Internal Error");
298         Throw(Exception::ParserInternalError);
299     }
300
301     /*
302      * get a size and fill in a buffer
303      */
304     size = xmlNodeDump(buff, node->doc, node, 0, 0);
305     buffer.insert(0, reinterpret_cast<char*>(buff->content), size);
306     xmlBufferFree(buff);
307 }
308 } // namespace ValidationCore