7 // Copyright (c) 2006 Martin Fuchs <martin-fuchs@gmx.net>
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions are met:
18 * Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
20 * Redistributions in binary form must reproduce the above copyright
21 notice, this list of conditions and the following disclaimer in
22 the documentation and/or other materials provided with the
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 POSSIBILITY OF SUCH DAMAGE.
40 #define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files to enable static linking
43 //#include "xmlstorage.h"
47 #if !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES)
49 namespace XMLStorage
{
52 XMLReaderBase::~XMLReaderBase()
56 /// read XML stream into XML tree below _pos
57 void XMLReaderBase::read()
62 error
._message
= "XML parsing error";
66 _errors
.push_back(error
);
77 _buffer
= (char*) malloc(BUFFER_LEN
);
96 size_t wpos
= _wptr
-_buffer
;
100 _buffer
= (char*) realloc(_buffer
, _len
);
101 _wptr
= _buffer
+ wpos
;
107 const std::string
& str(bool utf8
) // returns UTF-8 encoded buffer content
110 _buffer_str
.assign(_buffer
, _wptr
-_buffer
);
112 _buffer_str
= get_utf8(_buffer
, _wptr
-_buffer
);
119 return _wptr
- _buffer
;
122 bool has_CDEnd() const
124 //if (_wptr-_buffer < 3)
127 return !strncmp(_wptr
-3, "]]>", 3);
130 XS_String
get_tag() const
132 const char* p
= _buffer_str
.c_str();
148 #ifdef XS_STRING_UTF8
149 return XS_String(p
, q
-p
);
152 assign_utf8(tag
, p
, q
-p
);
157 /// read attributes and values
158 void get_attributes(XMLNode::AttributeMap
& attributes
) const
160 const char* p
= _buffer_str
.c_str();
162 // find end of tag name
174 // read attributes from buffer
175 while(*p
&& *p
!='>' && *p
!='/') {
176 while(isspace((unsigned char)*p
))
179 const char* attr_name
= p
;
185 break; //@TODO error handling
187 size_t attr_len
= p
- attr_name
;
189 if (*++p
!='"' && *p
!='\'')
190 break; //@TODO error handling
193 const char* value
= ++p
;
195 while(*p
&& *p
!=delim
)
198 size_t value_len
= p
- value
;
203 #ifdef XS_STRING_UTF8
204 XS_String
name_str(attr_name
, attr_len
);
205 XS_String
value_str(value
, value_len
);
207 XS_String name_str
, value_str
;
208 assign_utf8(name_str
, attr_name
, attr_len
);
209 assign_utf8(value_str
, value
, value_len
);
212 attributes
[name_str
] = DecodeXMLString(value_str
);
220 std::string _buffer_str
; // UF-8 encoded
223 bool XMLReaderBase::parse()
227 bool in_comment
= false;
230 if (in_comment
|| c
=='<') {
233 // read start or end tag
246 const std::string
& b
= buffer
.str(_utf8
);
247 const char* str
= b
.c_str();
249 if (in_comment
|| !strncmp(str
+1, "!--", 3)) {
253 if (strcmp(str
+b
.length()-3, "-->"))
259 } else if (str
[1] == '/') {
262 /*@TODO error handling
263 const XS_String& tag = buffer.get_tag();
265 if (tag != last_opened_tag) {
273 } else if (str
[1] == '?') {
275 const XS_String
& tag
= buffer
.get_tag();
278 XMLNode::AttributeMap attributes
;
279 buffer
.get_attributes(attributes
);
281 const std::string
& version
= attributes
.get("version");
282 const std::string
& encoding
= attributes
.get("encoding");
285 XMLNode::AttributeMap::const_iterator found
= // const_cast for ISO C++ compatibility error of GCC
286 const_cast<const XMLNode::AttributeMap
&>(attributes
).find("standalone");
287 if (found
!= attributes
.end())
288 standalone
= !XS_icmp(found
->second
.c_str(), XS_TEXT("yes"));
292 XmlDeclHandler(version
.empty()?NULL
:version
.c_str(), encoding
.empty()?NULL
:encoding
.c_str(), standalone
);
294 if (!encoding
.empty() && !_stricmp(encoding
.c_str(), "utf-8"))
298 } else if (tag
== "?xml-stylesheet") {
299 XMLNode::AttributeMap attributes
;
300 buffer
.get_attributes(attributes
);
302 StyleSheet
stylesheet(attributes
.get("href"), attributes
.get("type"), !XS_icmp(attributes
.get("alternate"), XS_TEXT("yes")));
303 stylesheet
._title
= attributes
.get("title");
304 stylesheet
._media
= attributes
.get("media");
305 stylesheet
._charset
= attributes
.get("charset");
307 _format
._stylesheets
.push_back(stylesheet
);
314 } else if (str
[1] == '!') {
315 if (!strncmp(str
+2, "DOCTYPE ", 8)) {
316 _format
._doctype
.parse(str
+10);
319 } else if (!strncmp(str
+2, "[CDATA[", 7)) {
320 // parse <![CDATA[ ... ]]> strings
321 while(!buffer
.has_CDEnd()) {
330 DefaultHandler(buffer
.str(_utf8
));
336 const XS_String
& tag
= buffer
.get_tag();
339 XMLNode::AttributeMap attributes
;
340 buffer
.get_attributes(attributes
);
342 StartElementHandler(tag
, attributes
);
344 if (str
[b
.length()-2] == '/')
355 // check for the encoding of the first line end
358 _format
._endl
= "\n";
359 _endl_defined
= true;
360 } else if (c
== '\r') {
361 _format
._endl
= "\r\n";
362 _endl_defined
= true;
376 DefaultHandler(buffer
.str(_utf8
));
385 int XMLReaderBase::eat_endl()
398 /// return current parser position as string
399 std::string
XMLReaderBase::get_position() const
401 /*@TODO display parser position in case of errors
402 int line = XML_GetCurrentLineNumber(_parser);
403 int column = XML_GetCurrentColumnNumber(_parser);
405 std::ostringstream out;
406 out << "(" << line << ") : [column " << column << "]";
414 #ifdef XMLNODE_LOCATION
416 XMLLocation
XMLReaderBase::get_location() const
418 return XMLLocation(); //@TODO XMLLocation for XS-native
421 std::string
XMLLocation::str() const
429 /// store content, white space and comments
430 void XMLReaderBase::DefaultHandler(const std::string
& s
)
436 } // namespace XMLStorage
438 #endif // !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES)