Author: martinf Date: Mon Oct 1 23:53:58 2007 New Revision: 29338
URL: http://svn.reactos.org/svn/reactos?rev=29338&view=rev Log: update explorer/xmlstorage
Modified: trunk/reactos/base/shell/explorer/ (props changed) trunk/reactos/base/shell/explorer/explorer.cpp trunk/reactos/base/shell/explorer/notifyhook/ (props changed) trunk/reactos/base/shell/explorer/res/ (props changed) trunk/reactos/base/shell/explorer/taskbar/favorites.cpp trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp trunk/reactos/base/shell/explorer/utility/xmlstorage.h trunk/reactos/base/shell/explorer/utility/xs-native.cpp
Propchange: trunk/reactos/base/shell/explorer/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Mon Oct 1 23:53:58 2007 @@ -5,3 +5,18 @@ *.ncb *.suo *.sln +Debug +doxy-doc +Release +*.chm +UDebug +URelease +Win32 +*.coff +*.exe +*.dll +*.aps +.gdbinit +*.gch +pack.cfg +pack.ign
Modified: trunk/reactos/base/shell/explorer/explorer.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/explore... ============================================================================== --- trunk/reactos/base/shell/explorer/explorer.cpp (original) +++ trunk/reactos/base/shell/explorer/explorer.cpp Mon Oct 1 23:53:58 2007 @@ -93,12 +93,12 @@ _cfg_dir.printf(TEXT("%s\ReactOS"), (LPCTSTR)SpecialFolderFSPath(CSIDL_APPDATA,0)); _cfg_path.printf(TEXT("%s\ros-explorer-cfg.xml"), _cfg_dir.c_str());
- if (!_cfg.read(_cfg_path)) { + if (!_cfg.read_file(_cfg_path)) { //if (_cfg._last_error != XML_ERROR_NO_ELEMENTS) MessageBox(_hwndDesktop, _cfg._errors.str(), TEXT("ROS Explorer - reading user settings"), MB_OK);
- _cfg.read(TEXT("explorer-cfg-template.xml")); + _cfg.read_file(TEXT("explorer-cfg-template.xml")); }
// read bookmarks @@ -115,7 +115,7 @@ // write configuration file RecursiveCreateDirectory(_cfg_dir);
- _cfg.write(_cfg_path); + _cfg.write_file(_cfg_path); _favorites.write(_favorites_path); }
Propchange: trunk/reactos/base/shell/explorer/notifyhook/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Mon Oct 1 23:53:58 2007 @@ -5,3 +5,6 @@ *.ncb *.suo *.sln +Debug +Release +Win32
Propchange: trunk/reactos/base/shell/explorer/res/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Mon Oct 1 23:53:58 2007 @@ -5,3 +5,4 @@ *.ncb *.suo *.sln +Thumbs.db
Modified: trunk/reactos/base/shell/explorer/taskbar/favorites.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/taskbar... ============================================================================== --- trunk/reactos/base/shell/explorer/taskbar/favorites.cpp (original) +++ trunk/reactos/base/shell/explorer/taskbar/favorites.cpp Mon Oct 1 23:53:58 2007 @@ -426,7 +426,7 @@ { XMLDoc xbel;
- if (!xbel.read(path)) { + if (!xbel.read_file(path)) { MessageBox(g_Globals._hwndDesktop, xbel._errors.str(), TEXT("ROS Explorer - reading bookmark file"), MB_OK); } @@ -457,7 +457,7 @@ xbel._format._doctype._public = "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"; xbel._format._doctype._system = "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd";
- xbel.write(path); + xbel.write_file(path); }
/// import Internet Explorer bookmarks from Favorites folder
Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utility... ============================================================================== --- trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp (original) +++ trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp Mon Oct 1 23:53:58 2007 @@ -1,6 +1,6 @@
// - // XML storage classes version 1.2 + // XML storage C++ classes version 1.2 // // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs martin-fuchs@gmx.net // @@ -44,6 +44,10 @@ //#include "xmlstorage.h" #include <precomp.h>
+#ifdef __GNUC__ +#include <alloca.h> +#endif +
namespace XMLStorage {
@@ -152,129 +156,91 @@
// parse relative path while(*path) { - const char* slash = strchr(path, '/'); - if (slash == path) + node = const_cast<XMLNode*>(node)->get_child_relative(path, false); // get_child_relative() ist const for create==false + + if (!node) return NULL;
- size_t l = slash? slash-path: strlen(path); - std::string comp(path, l); - path += l; - - // look for [n] and [@attr_name="attr_value"] expressions in path components - const char* bracket = strchr(comp.c_str(), '['); - l = bracket? bracket-comp.c_str(): comp.length(); - std::string child_name(comp.c_str(), l); - std::string attr_name, attr_value; - - int n = 0; - if (bracket) { - std::string expr = unescape(bracket, '[', ']'); - const char* p = expr.c_str(); - - n = atoi(p); // read index number - - if (n) - n = n - 1; // convert into zero based index - - const char* at = strchr(p, '@'); - - if (at) { - p = at + 1; - const char* equal = strchr(p, '='); - - // read attribute name and value - if (equal) { - attr_name = unescape(p, equal-p); - attr_value = unescape(equal+1); - } + if (*path == '/') + ++path; + } + + return node; +} + +XMLNode* XMLNode::create_relative(const char* path) +{ + XMLNode* node = this; + + // parse relative path + while(*path) { + node = node->get_child_relative(path, true); + + if (*path == '/') + ++path; + } + + return node; +} + +XMLNode* XMLNode::get_child_relative(const char*& path, bool create) +{ + const char* slash = strchr(path, '/'); + if (slash == path) + return NULL; + + size_t l = slash? slash-path: strlen(path); + std::string comp(path, l); + path += l; + + // look for [n] and [@attr_name="attr_value"] expressions in path components + const char* bracket = strchr(comp.c_str(), '['); + l = bracket? bracket-comp.c_str(): comp.length(); + std::string child_name(comp.c_str(), l); + std::string attr_name, attr_value; + + int n = 0; + if (bracket) { + std::string expr = unescape(bracket, '[', ']'); + const char* p = expr.c_str(); + + n = atoi(p); // read index number + + if (n) + n = n - 1; // convert into zero based index + + const char* at = strchr(p, '@'); + + if (at) { + p = at + 1; + const char* equal = strchr(p, '='); + + // read attribute name and value + if (equal) { + attr_name = unescape(p, equal-p); + attr_value = unescape(equal+1); } } - - if (attr_name.empty()) - // search n.th child node with specified name - node = node->find(child_name, n); - else - // search n.th child node with specified name and matching attribute value - node = node->find(child_name, attr_name, attr_value, n); - - if (!node) - return NULL; - - if (*path == '/') - ++path; - } - - return node; -} - -XMLNode* XMLNode::create_relative(const char* path) -{ - XMLNode* node = this; - - // parse relative path - while(*path) { - const char* slash = strchr(path, '/'); - if (slash == path) - return NULL; - - size_t l = slash? slash-path: strlen(path); - std::string comp(path, l); - path += l; - - // look for [n] and [@attr_name="attr_value"] expressions in path components - const char* bracket = strchr(comp.c_str(), '['); - l = bracket? bracket-comp.c_str(): comp.length(); - std::string child_name(comp.c_str(), l); - std::string attr_name, attr_value; - - int n = 0; - if (bracket) { - std::string expr = unescape(bracket, '[', ']'); - const char* p = expr.c_str(); - - n = atoi(p); // read index number - - if (n) - n = n - 1; // convert into zero based index - - const char* at = strchr(p, '@'); - - if (at) { - p = at + 1; - const char* equal = strchr(p, '='); - - // read attribute name and value - if (equal) { - attr_name = unescape(p, equal-p); - attr_value = unescape(equal+1); - } - } - } - - XMLNode* child; - - if (attr_name.empty()) - // search n.th child node with specified name - child = node->find(child_name, n); - else - // search n.th child node with specified name and matching attribute value - child = node->find(child_name, attr_name, attr_value, n); - - if (!child) { - child = new XMLNode(child_name); - node->add_child(child); - - if (!attr_name.empty()) - (*node)[attr_name] = attr_value; - } - - node = child; - - if (*path == '/') - ++path; - } - - return node; + } + + XMLNode* child; + + if (attr_name.empty()) + // search n.th child node with specified name + child = find(child_name, n); + else + // search n.th child node with specified name and matching attribute value + child = find(child_name, attr_name, attr_value, n); + + if (!child && create) { + child = new XMLNode(child_name); + add_child(child); + + if (!attr_name.empty()) + (*this)[attr_name] = attr_value; + } + + return child; }
@@ -426,7 +392,7 @@
/// write node with children tree to output stream using original white space -void XMLNode::write_worker(std::ostream& out, int indent) const +void XMLNode::write_worker(std::ostream& out) const { out << _leading << '<' << EncodeXMLString(*this);
@@ -437,7 +403,7 @@ out << '>' << _content;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) - (*it)->write_worker(out, indent+1); + (*it)->write_worker(out);
out << _end_leading << "</" << EncodeXMLString(*this) << '>'; } else @@ -455,8 +421,12 @@ for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it) out << ' ' << EncodeXMLString(it->first) << "="" << EncodeXMLString(it->second) << """;
- if (!_children.empty()/*@@ || !_content.empty()*/) { - out << ">"; + // strip leading white space from content + const char* content = _content.c_str(); + while(isspace((unsigned char)*content)) ++content; + + if (!_children.empty() || *content) { + out << ">" << content;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) (*it)->plain_write_worker(out); @@ -478,8 +448,15 @@ for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it) out << ' ' << EncodeXMLString(it->first) << "="" << EncodeXMLString(it->second) << """;
- if (!_children.empty()/*@@ || !_content.empty()*/) { - out << '>' << format._endl; + // strip leading white space from content + const char* content = _content.c_str(); + while(isspace((unsigned char)*content)) ++content; + + if (!_children.empty() || *content) { + out << '>' << content; + + if (!_children.empty()) + out << format._endl;
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) (*it)->pretty_write_worker(out, format, indent+1); @@ -496,26 +473,34 @@ /// write node with children tree to output stream using smart formating void XMLNode::smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const { - if (_leading.empty()) + // strip the first line feed from _leading + const char* leading = _leading.c_str(); + if (*leading == '\n') ++leading; + + if (!*leading) for(int i=indent; i--; ) out << XML_INDENT_SPACE; else - out << _leading; + out << leading;
out << '<' << EncodeXMLString(*this);
for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it) out << ' ' << EncodeXMLString(it->first) << "="" << EncodeXMLString(it->second) << """;
- if (_children.empty() && _content.empty()) + // strip leading white space from content + const char* content = _content.c_str(); + while(isspace((unsigned char)*content)) ++content; + + if (_children.empty() && !*content) out << "/>"; else { out << '>';
- if (_content.empty()) + if (!*content) out << format._endl; else - out << _content; + out << content;
Children::const_iterator it = _children.begin();
@@ -523,11 +508,15 @@ for(; it!=_children.end(); ++it) (*it)->smart_write_worker(out, format, indent+1);
- if (_end_leading.empty()) + // strip the first line feed from _end_leading + const char* end_leading = _end_leading.c_str(); + if (*end_leading == '\n') ++end_leading; + + if (!*end_leading) for(int i=indent; i--; ) out << XML_INDENT_SPACE; else - out << _end_leading; + out << end_leading; } else out << _end_leading;
@@ -710,16 +699,14 @@ /// notifications about XML start tag void XMLReaderBase::StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes) { - // search for end of first line const char* s = _content.c_str(); + const char* e = s + _content.length(); const char* p = s; - const char* e = p + _content.length(); - - for(; p<e; ++p) - if (*p == '\n') { - ++p; + + // search for content end leaving only white space for leading + for(p=e; p>s; --p) + if (!isspace((unsigned char)p[-1])) break; - }
if (p != s) if (_pos->_children.empty()) { // no children in last node? @@ -754,29 +741,27 @@ /// notifications about XML end tag void XMLReaderBase::EndElementHandler() { - // search for end of first line const char* s = _content.c_str(); - const char* p = s; - const char* e = p + _content.length(); + const char* e = s + _content.length(); + const char* p;
if (!strncmp(s,"<![CDATA[",9) && !strncmp(e-3,"]]>",3)) { s += 9; p = (e-=3); - } else - for(; p<e; ++p) - if (*p == '\n') { - ++p; - break; - } + } else { + // search for content end leaving only white space for _end_leading + for(p=e; p>s; --p) + if (!isspace((unsigned char)p[-1])) + break; + }
if (p != s) if (_pos->_children.empty()) // no children in current node? _pos->_content.append(s, p-s); + else if (_last_tag == TAG_START) + _pos->_content.append(s, p-s); else - if (_last_tag == TAG_START) - _pos->_content.append(s, p-s); - else - _pos->_children.back()->_trailing.append(s, p-s); + _pos->_children.back()->_trailing.append(s, p-s);
if (p != e) _pos->_end_leading.assign(p, e-p);
Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utility... ============================================================================== --- trunk/reactos/base/shell/explorer/utility/xmlstorage.h (original) +++ trunk/reactos/base/shell/explorer/utility/xmlstorage.h Mon Oct 1 23:53:58 2007 @@ -1,6 +1,6 @@
// - // XML storage classes version 1.2 + // XML storage C++ classes version 1.2 // // Copyright (c) 2004, 2005, 2006, 2007 Martin Fuchs martin-fuchs@gmx.net // @@ -154,6 +154,10 @@ #include <windows.h> // for LPCTSTR #include <tchar.h> #include <malloc.h> + +#ifndef _MSC_VER +#include <stdio.h> // vsnprintf(), snprintf() +#endif
#else
@@ -476,10 +480,12 @@
#ifdef __GNUC__ #include <ext/stdio_filebuf.h> -typedef __gnu_cxx::stdio_filebuf<char> STDIO_FILEBUF; -#else -typedef std::filebuf STDIO_FILEBUF; -#endif +#define FILE_FILEBUF __gnu_cxx::stdio_filebuf<char> +#elif defined(_MSC_VER) +#define FILE_FILEBUF std::filebuf +#endif + +#ifdef FILE_FILEBUF
/// base class for XMLStorage::tifstream and XMLStorage::tofstream struct FileHolder @@ -521,7 +527,7 @@ }
protected: - STDIO_FILEBUF _buf; + FILE_FILEBUF _buf; };
/// output file stream with ANSI/UNICODE file names @@ -546,8 +552,36 @@ }
protected: - STDIO_FILEBUF _buf; -}; + FILE_FILEBUF _buf; +}; + +#else // FILE_FILEBUF + +#ifdef UNICODE +#error UNICODE not supported for this platform +#endif + +struct tifstream : public std::ifstream +{ + typedef std::ifstream super; + + tifstream(const char* path) + : super(path, std::ios::in|std::ios::binary) + { + } +}; + +struct tofstream : public std::ofstream +{ + typedef std::ofstream super; + + tofstream(const char* path) + : super(path, std::ios::out|std::ios::binary) + { + } +}; + +#endif
// write XML files with 2 spaces indenting @@ -902,7 +936,7 @@ _attributes[attr_name] = value; }
- /// C++ write access to an attribute + /// index operator write access to an attribute XS_String& operator[](const XS_String& attr_name) { return _attributes[attr_name]; @@ -1023,7 +1057,7 @@ break;
case FORMAT_ORIGINAL: - write_worker(out, indent); + write_worker(out); break;
default: // FORMAT_SMART @@ -1113,10 +1147,13 @@ /// relative XPath create function XMLNode* create_relative(const char* path);
- void write_worker(std::ostream& out, int indent) const; + void write_worker(std::ostream& out) const; void plain_write_worker(std::ostream& out) const; void pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const; void smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const; + +protected: + XMLNode* get_child_relative(const char*& path, bool create); // mutable for create==true };
@@ -1367,7 +1404,7 @@ return *_cur; }
- /// C++ access to current node + /// automatic access to current node operator const XMLNode*() const {return _cur;} operator XMLNode*() {return _cur;}
@@ -1378,9 +1415,9 @@ XMLNode& operator*() {return *_cur;}
/// attribute access - XS_String get(const XS_String& attr_name) const - { - return _cur->get(attr_name); + XS_String get(const XS_String& attr_name, LPCXSSTR def=XS_EMPTY_STR) const + { + return _cur->get(attr_name, def); }
/// attribute setting @@ -1389,7 +1426,7 @@ _cur->put(attr_name, value); }
- /// C++ attribute access + /// index operator attribute access template<typename T> XS_String get(const T& attr_name) const {return (*_cur)[attr_name];} XS_String& operator[](const XS_String& attr_name) {return (*_cur)[attr_name];}
@@ -1564,7 +1601,7 @@ return *_cur; }
- /// C++ access to current node + /// automatic access to current node operator const XMLNode*() const {return _cur;}
const XMLNode* operator->() const {return _cur;} @@ -1577,7 +1614,7 @@ return _cur->get(attr_name); }
- /// C++ attribute access + /// index operator attribute access template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position @@ -1944,23 +1981,23 @@ };
/// type converter for string data with write access -struct XMStringRef -{ - XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) +struct XMLStringRef +{ + XMLStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) : _ref((*node)[attr_name]) { if (_ref.empty()) assign(def); }
- XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) + XMLStringRef(const XS_String& node_name, XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY) : _ref(node->subvalue(node_name, attr_name)) { if (_ref.empty()) assign(def); }
- XMStringRef& operator=(const XS_String& value) + XMLStringRef& operator=(const XS_String& value) { assign(value);
@@ -2304,11 +2341,11 @@ XMLDoc(LPCTSTR path) : XMLNode("") { - read(path); + read_file(path); }
#ifdef XS_USE_XERCES - bool read(LPCTSTR path) + bool read_file(LPCTSTR path) { XMLReader reader(this, path);
@@ -2319,7 +2356,7 @@ #endif }
- bool read(const char* buffer, size_t len, const std::string& system_id=std::string()) + bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string()) { XMLReader reader(this, (const XMLByte*)buffer, len, system_id);
@@ -2328,7 +2365,7 @@
#else // XS_USE_XERCES
- bool read(LPCTSTR path) + bool read_file(LPCTSTR path) { tifstream in(path); XMLReader reader(this, in); @@ -2340,7 +2377,7 @@ #endif }
- bool read(const char* buffer, size_t len, const std::string& system_id=std::string()) + bool read_buffer(const char* buffer, size_t len, const std::string& system_id=std::string()) { std::istringstream in(std::string(buffer, len));
@@ -2377,7 +2414,8 @@ return true; }
- /// write XML stream preserving previous white space and comments + /// write XML stream + // FORMAT_SMART: preserving previous white space and comments bool write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const { _format.print_header(out, mode!=FORMAT_PLAIN); @@ -2398,7 +2436,7 @@ return write(out, FORMAT_PRETTY); }
- bool write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const + bool write_file(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const { tofstream out(path);
@@ -2454,7 +2492,7 @@ { XMLMessageFromString(const std::string& xml_str, const std::string& system_id=std::string()) { - read(xml_str.c_str(), xml_str.length(), system_id); + read_buffer(xml_str.c_str(), xml_str.length(), system_id); } };
@@ -2465,7 +2503,7 @@ XMLMessageReader(const std::string& xml_str, const std::string& system_id=std::string()) : XMLPos(&_msg) { - _msg.read(xml_str.c_str(), xml_str.length(), system_id); + _msg.read_buffer(xml_str.c_str(), xml_str.length(), system_id); }
const XMLDoc& get_document() @@ -2543,7 +2581,7 @@ _stack.top()._attributes[attr_name] = value; }
- /// C++ write access to an attribute + /// index operator write access to an attribute XS_String& operator[](const XS_String& attr_name) { if (_stack.empty())
Modified: trunk/reactos/base/shell/explorer/utility/xs-native.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/utility... ============================================================================== --- trunk/reactos/base/shell/explorer/utility/xs-native.cpp (original) +++ trunk/reactos/base/shell/explorer/utility/xs-native.cpp Mon Oct 1 23:53:58 2007 @@ -1,6 +1,6 @@
// - // XML storage classes version 1.2 + // XML storage C++ classes version 1.2 // // Copyright (c) 2006, 2007 Martin Fuchs martin-fuchs@gmx.net // @@ -224,7 +224,7 @@ char* _buffer; char* _wptr; size_t _len; - std::string _buffer_str; // UF-8 encoded + std::string _buffer_str; // UTF-8 encoded };
bool XMLReaderBase::parse() @@ -386,7 +386,7 @@ buffer.reset(); }
- return true; + return true; //TODO return false on invalid XML }
int XMLReaderBase::eat_endl()