Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxs-native.cpp
Go to the documentation of this file.
00001 00002 // 00003 // XML storage C++ classes version 1.3 00004 // 00005 // Copyright (c) 2006, 2007, 2008, 2009 Martin Fuchs <martin-fuchs@gmx.net> 00006 // 00007 00010 00011 00012 /* 00013 00014 All rights reserved. 00015 00016 Redistribution and use in source and binary forms, with or without 00017 modification, are permitted provided that the following conditions are met: 00018 00019 * Redistributions of source code must retain the above copyright 00020 notice, this list of conditions and the following disclaimer. 00021 * Redistributions in binary form must reproduce the above copyright 00022 notice, this list of conditions and the following disclaimer in 00023 the documentation and/or other materials provided with the 00024 distribution. 00025 00026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 POSSIBILITY OF SUCH DAMAGE. 00037 00038 */ 00039 00040 #include <precomp.h> 00041 00042 #ifndef XS_NO_COMMENT 00043 #define XS_NO_COMMENT // no #pragma comment(lib, ...) statements in .lib files to enable static linking 00044 #endif 00045 00046 //#include "xmlstorage.h" 00047 00048 00049 #if !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES) 00050 00051 namespace XMLStorage { 00052 00053 00054 XMLReaderBase::~XMLReaderBase() 00055 { 00056 } 00057 00059 void XMLReaderBase::read() 00060 { 00061 if (!parse()) { 00062 XMLError error; 00063 00064 error._message = "XML parsing error"; 00065 //error._line = ; 00066 //error._column = ; 00067 00068 _errors.push_back(error); 00069 } 00070 00071 finish_read(); 00072 } 00073 00074 00076 00077 struct Buffer 00078 { 00079 Buffer() 00080 { 00081 _buffer = (char*) malloc(BUFFER_LEN); 00082 _len = BUFFER_LEN; 00083 00084 reset(); 00085 } 00086 00087 ~Buffer() 00088 { 00089 free(_buffer); 00090 } 00091 00092 void reset() 00093 { 00094 _wptr = _buffer; 00095 _buffer_str.erase(); 00096 } 00097 00098 void append(int c) 00099 { 00100 size_t wpos = _wptr-_buffer; 00101 00102 if (wpos >= _len) { 00103 _len <<= 1; 00104 _buffer = (char*) realloc(_buffer, _len); 00105 _wptr = _buffer + wpos; 00106 } 00107 00108 *_wptr++ = static_cast<char>(c); 00109 } 00110 00111 const std::string& str(bool utf8) // returns UTF-8 encoded buffer content 00112 { 00113 #if defined(_WIN32) && !defined(XS_STRING_UTF8) 00114 if (utf8) 00115 #endif 00116 _buffer_str.assign(_buffer, _wptr-_buffer); 00117 #if defined(_WIN32) && !defined(XS_STRING_UTF8) 00118 else 00119 _buffer_str = get_utf8(_buffer, _wptr-_buffer); 00120 #endif 00121 00122 return _buffer_str; 00123 } 00124 00125 size_t len() const 00126 { 00127 return _wptr - _buffer; 00128 } 00129 00130 bool has_CDEnd() const 00131 { 00132 //if (_wptr-_buffer < 3) 00133 // return false; 00134 00135 return !strncmp(_wptr-3, CDATA_END, 3); 00136 } 00137 00138 XS_String get_tag() const 00139 { 00140 const char* p = _buffer_str.c_str(); 00141 00142 if (*p == '<') 00143 ++p; 00144 00145 if (*p == '/') 00146 ++p; 00147 00148 const char* q = p; 00149 00150 if (*q == '?') 00151 ++q; 00152 00153 q = get_xmlsym_end_utf8(q); 00154 00155 #ifdef XS_STRING_UTF8 00156 return XS_String(p, q-p); 00157 #else 00158 XS_String tag; 00159 assign_utf8(tag, p, q-p); 00160 return tag; 00161 #endif 00162 } 00163 00165 void get_attributes(XMLNode::AttributeMap& attributes) const 00166 { 00167 const char* p = _buffer_str.c_str(); 00168 00169 // find end of tag name 00170 if (*p == '<') 00171 ++p; 00172 00173 if (*p == '/') 00174 ++p; 00175 else if (*p == '?') 00176 ++p; 00177 00178 p = get_xmlsym_end_utf8(p); 00179 00180 // read attributes from buffer 00181 while(*p && *p!='>' && *p!='/') { 00182 while(isspace((unsigned char)*p)) 00183 ++p; 00184 00185 const char* attr_name = p; 00186 00187 p = get_xmlsym_end_utf8(p); 00188 00189 if (*p != '=') 00190 break; //@TODO error handling 00191 00192 size_t attr_len = p - attr_name; 00193 00194 if (*++p!='"' && *p!='\'') 00195 break; //@TODO error handling 00196 00197 char delim = *p; 00198 const char* value = ++p; 00199 00200 while(*p && *p!=delim) 00201 ++p; 00202 00203 size_t value_len = p - value; 00204 00205 if (*p) 00206 ++p; // '"' 00207 00208 #ifdef XS_STRING_UTF8 00209 XS_String name_str(attr_name, attr_len); 00210 #else 00211 XS_String name_str; 00212 assign_utf8(name_str, attr_name, attr_len); 00213 #endif 00214 00215 attributes[name_str] = DecodeXMLString(std::string(value, value_len)); 00216 } 00217 } 00218 00219 protected: 00220 char* _buffer; 00221 char* _wptr; 00222 size_t _len; 00223 std::string _buffer_str; // UTF-8 encoded 00224 }; 00225 00226 bool XMLReaderBase::parse() 00227 { 00228 Buffer buffer; 00229 int c = get(); 00230 bool in_comment = false; 00231 00232 while(c != EOF) { 00233 if (in_comment || c=='<') { 00234 buffer.append(c); 00235 00236 // read start or end tag 00237 for(;;) { 00238 c = get(); 00239 00240 if (c == EOF) 00241 break; 00242 00243 buffer.append(c); 00244 00245 if (c == '>') 00246 break; 00247 } 00248 00249 const std::string& b = buffer.str(_utf8); 00250 const char* str = b.c_str(); 00251 00252 if (in_comment || !strncmp(str+1, "!--", 3)) { 00253 // XML comment 00254 DefaultHandler(b); 00255 00256 if (strcmp(str+b.length()-3, "-->")) 00257 in_comment = true; 00258 else 00259 in_comment = false; 00260 00261 c = get(); 00262 } else if (str[1] == '/') { 00263 // end tag 00264 00265 /*@TODO error handling 00266 const XS_String& tag = buffer.get_tag(); 00267 00268 if (tag != last_opened_tag) { 00269 ERROR 00270 } 00271 */ 00272 00273 EndElementHandler(); 00274 00275 c = get(); 00276 } else if (str[1] == '?') { 00277 // XML declaration 00278 const XS_String& tag = buffer.get_tag(); 00279 00280 if (tag == "?xml") { 00281 XMLNode::AttributeMap attributes; 00282 buffer.get_attributes(attributes); 00283 00284 const std::string& version = attributes.get("version"); 00285 const std::string& encoding = attributes.get("encoding"); 00286 00287 int standalone; 00288 XMLNode::AttributeMap::const_iterator found = // const_cast for ISO C++ compatibility error of GCC 00289 const_cast<const XMLNode::AttributeMap&>(attributes).find("standalone"); 00290 if (found != attributes.end()) 00291 standalone = !XS_icmp(found->second.c_str(), XS_TEXT("yes")); 00292 else 00293 standalone = -1; 00294 00295 XmlDeclHandler(version.empty()?NULL:version.c_str(), encoding.empty()?NULL:encoding.c_str(), standalone); 00296 00297 if (!encoding.empty() && !_stricmp(encoding.c_str(), "utf-8")) 00298 _utf8 = true; 00299 00300 c = eat_endl(); 00301 } else if (tag == "?xml-stylesheet") { 00302 XMLNode::AttributeMap attributes; 00303 buffer.get_attributes(attributes); 00304 00305 StyleSheet stylesheet(attributes.get("href"), attributes.get("type"), !XS_icmp(attributes.get("alternate"), XS_TEXT("yes"))); 00306 stylesheet._title = attributes.get("title"); 00307 stylesheet._media = attributes.get("media"); 00308 stylesheet._charset = attributes.get("charset"); 00309 00310 _format._stylesheets.push_back(stylesheet); 00311 00312 c = eat_endl(); 00313 } else { 00314 DefaultHandler(b); 00315 c = get(); 00316 } 00317 } else if (str[1] == '!') { 00318 if (!strncmp(str+2, "DOCTYPE ", 8)) { 00319 _format._doctype.parse(str+10); 00320 00321 c = eat_endl(); 00322 } else if (!strncmp(str+2, "[CDATA[", 7)) { // see CDATA_START 00323 // parse <![CDATA[ ... ]]> strings 00324 while(!buffer.has_CDEnd()) { 00325 c = get(); 00326 00327 if (c == EOF) 00328 break; 00329 00330 buffer.append(c); 00331 } 00332 00333 DefaultHandler(buffer.str(_utf8)); 00334 00335 c = get(); 00336 } 00337 } else { 00338 // start tag 00339 const XS_String& tag = buffer.get_tag(); 00340 00341 if (!tag.empty()) { 00342 XMLNode::AttributeMap attributes; 00343 buffer.get_attributes(attributes); 00344 00345 StartElementHandler(tag, attributes); 00346 00347 if (str[b.length()-2] == '/') 00348 EndElementHandler(); 00349 } 00350 00351 c = get(); 00352 } 00353 } else { 00354 buffer.append(c); 00355 00356 // read white space 00357 for(;;) { 00358 // check for the encoding of the first line end 00359 if (!_endl_defined) { 00360 if (c == '\n') { 00361 _format._endl = "\n"; 00362 _endl_defined = true; 00363 } else if (c == '\r') { 00364 _format._endl = "\r\n"; 00365 _endl_defined = true; 00366 } 00367 } 00368 00369 c = get(); 00370 00371 if (c == EOF) 00372 break; 00373 00374 if (c == '<') 00375 break; 00376 00377 buffer.append(c); 00378 } 00379 00380 DefaultHandler(buffer.str(_utf8)); 00381 } 00382 00383 buffer.reset(); 00384 } 00385 00386 return true; //TODO return false on invalid XML 00387 } 00388 00389 int XMLReaderBase::eat_endl() 00390 { 00391 int c = get(); 00392 00393 if (c == '\r') 00394 c = get(); 00395 00396 if (c == '\n') 00397 c = get(); 00398 00399 return c; 00400 } 00401 00403 std::string XMLReaderBase::get_position() const 00404 { 00405 /*@TODO display parser position in case of errors 00406 int line = XML_GetCurrentLineNumber(_parser); 00407 int column = XML_GetCurrentColumnNumber(_parser); 00408 00409 std::ostringstream out; 00410 out << "(" << line << ") : [column " << column << "]"; 00411 00412 return out.str(); 00413 */ 00414 return ""; 00415 } 00416 00417 00418 #ifdef XMLNODE_LOCATION 00419 00420 XMLLocation XMLReaderBase::get_location() const 00421 { 00422 return XMLLocation(); //@TODO XMLLocation for XS-native 00423 } 00424 00425 std::string XMLLocation::str() const 00426 { 00427 return ""; //TODO 00428 } 00429 00430 #endif 00431 00432 00434 void XMLReaderBase::DefaultHandler(const std::string& s) 00435 { 00436 _content.append(s); 00437 } 00438 00439 00440 } // namespace XMLStorage 00441 00442 #endif // !defined(XS_USE_EXPAT) && !defined(XS_USE_XERCES) Generated on Sun May 27 2012 04:18:46 for ReactOS by
1.7.6.1
|