ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

xs-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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.