From: <m97...@us...> - 2010-06-12 21:32:24
|
Revision: 11511 http://openmsx.svn.sourceforge.net/openmsx/?rev=11511&view=rev Author: m9710797 Date: 2010-06-12 21:32:18 +0000 (Sat, 12 Jun 2010) Log Message: ----------- Removed some methods that are no longer used. Modified Paths: -------------- openmsx/trunk/src/config/XMLElement.cc openmsx/trunk/src/config/XMLElement.hh Modified: openmsx/trunk/src/config/XMLElement.cc =================================================================== --- openmsx/trunk/src/config/XMLElement.cc 2010-06-12 21:28:17 UTC (rev 11510) +++ openmsx/trunk/src/config/XMLElement.cc 2010-06-12 21:32:18 UTC (rev 11511) @@ -345,40 +345,6 @@ } } -struct ShallowEqualTo { - ShallowEqualTo(const XMLElement& rhs_) : rhs(rhs_) {} - bool operator()(const XMLElement* lhs) const { - return lhs->isShallowEqual(rhs); - } - const XMLElement& rhs; -}; - -void XMLElement::merge(const XMLElement& source) -{ - assert(isShallowEqual(source)); - Children srcChildrenCopy(children.begin(), children.end()); - const Children& sourceChildren = source.getChildren(); - for (Children::const_iterator it = sourceChildren.begin(); - it != sourceChildren.end(); ++it) { - const XMLElement& srcChild = **it; - Children::iterator it2 = std::find_if(srcChildrenCopy.begin(), - srcChildrenCopy.end(), ShallowEqualTo(srcChild)); - if (it2 != srcChildrenCopy.end()) { - (*it2)->merge(srcChild); - srcChildrenCopy.erase(it2); // don't merge to same child twice - } else { - addChild(auto_ptr<XMLElement>(new XMLElement(srcChild))); - } - } - setData(source.getData()); -} - -bool XMLElement::isShallowEqual(const XMLElement& other) const -{ - return (getName() == other.getName()) && - (getAttributes() == other.getAttributes()); -} - string XMLElement::XMLEscape(const string& str) { xmlChar* buffer = xmlEncodeEntitiesReentrant( Modified: openmsx/trunk/src/config/XMLElement.hh =================================================================== --- openmsx/trunk/src/config/XMLElement.hh 2010-06-12 21:28:17 UTC (rev 11510) +++ openmsx/trunk/src/config/XMLElement.hh 2010-06-12 21:32:18 UTC (rev 11511) @@ -108,9 +108,6 @@ // various std::string dump() const; - void merge(const XMLElement& source); - bool isShallowEqual(const XMLElement& other) const; - static std::string XMLEscape(const std::string& str); template<typename Archive> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m97...@us...> - 2010-07-09 21:06:50
|
Revision: 11582 http://openmsx.svn.sourceforge.net/openmsx/?rev=11582&view=rev Author: m9710797 Date: 2010-07-09 21:06:44 +0000 (Fri, 09 Jul 2010) Log Message: ----------- Parse XML files slightly more efficient We use a SAX parser to turn XML files into our internal XMLElement data structure. A SAX parser also processes all string data of non-leaf nodes. In our XML data formats we don't care about this data (it only contains spaces and newlines to properly indent the XML file). This patch detects and ignores this kind of data a bit earlier. Modified Paths: -------------- openmsx/trunk/src/config/XMLElement.cc openmsx/trunk/src/config/XMLElement.hh openmsx/trunk/src/config/XMLLoader.cc Modified: openmsx/trunk/src/config/XMLElement.cc =================================================================== --- openmsx/trunk/src/config/XMLElement.cc 2010-07-09 21:06:22 UTC (rev 11581) +++ openmsx/trunk/src/config/XMLElement.cc 2010-07-09 21:06:44 UTC (rev 11582) @@ -48,8 +48,7 @@ void XMLElement::addChild(auto_ptr<XMLElement> child) { - data.clear(); // no mixed-content elements - + assert(data.empty()); // no mixed-content elements assert(child.get()); assert(!child->getParent()); child->parent = this; @@ -104,10 +103,8 @@ void XMLElement::setData(const string& data_) { - //assert(children.empty()); // no mixed-content elements - if (children.empty()) { - data = data_; - } + assert(children.empty()); // no mixed-content elements + data = data_; } void XMLElement::getChildren(const string& name, Children& result) const Modified: openmsx/trunk/src/config/XMLElement.hh =================================================================== --- openmsx/trunk/src/config/XMLElement.hh 2010-07-09 21:06:22 UTC (rev 11581) +++ openmsx/trunk/src/config/XMLElement.hh 2010-07-09 21:06:44 UTC (rev 11582) @@ -51,6 +51,7 @@ void addChild(std::auto_ptr<XMLElement> child); std::auto_ptr<XMLElement> removeChild(const XMLElement& child); const Children& getChildren() const { return children; } + bool hasChildren() const { return !children.empty(); } // filecontext void setFileContext(std::auto_ptr<FileContext> context); Modified: openmsx/trunk/src/config/XMLLoader.cc =================================================================== --- openmsx/trunk/src/config/XMLLoader.cc 2010-07-09 21:06:22 UTC (rev 11581) +++ openmsx/trunk/src/config/XMLLoader.cc 2010-07-09 21:06:44 UTC (rev 11582) @@ -71,15 +71,18 @@ == helper->current->getName()); (void)localname; - helper->current->setData(helper->data); + if (!helper->current->hasChildren()) { + helper->current->setData(helper->data); + } helper->current = helper->current->getParent(); - helper->data.clear(); } static void cbCharacters(XMLLoaderHelper* helper, const xmlChar* chars, int len) { assert(helper->current); - helper->data.append(reinterpret_cast<const char*>(chars), len); + if (!helper->current->hasChildren()) { + helper->data.append(reinterpret_cast<const char*>(chars), len); + } } static void cbInternalSubset(XMLLoaderHelper* helper, const xmlChar* /*name*/, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m97...@us...> - 2010-07-09 21:07:33
|
Revision: 11584 http://openmsx.svn.sourceforge.net/openmsx/?rev=11584&view=rev Author: m9710797 Date: 2010-07-09 21:07:27 +0000 (Fri, 09 Jul 2010) Log Message: ----------- Store XMLElement attributes in a vector instead of a map The obvious data structure to store attributes in is a 'map<string, string>'. This patch replaces that with a 'vector<pair<string, string>>'. The map has the advantage of easier implementation and O(log(n)) instead of O(n) lookup time. Though for very small n (our XML nodes mostly only have 0 or 1 attribute) this big-O complexity advantage doesn't come into play yet and the simpler vector data struture is actually faster than map. Switching from map to vector requires to manually implement the lookup-by-key routine. Though as an extra advantage this allowed to implement the lookup using 'std::string / const char*' comparisons (instead of 'string / string' comparisons). And this avoids a lot of temporary string objects. Modified Paths: -------------- openmsx/trunk/src/config/XMLElement.cc openmsx/trunk/src/config/XMLElement.hh Modified: openmsx/trunk/src/config/XMLElement.cc =================================================================== --- openmsx/trunk/src/config/XMLElement.cc 2010-07-09 21:07:07 UTC (rev 11583) +++ openmsx/trunk/src/config/XMLElement.cc 2010-07-09 21:07:27 UTC (rev 11584) @@ -65,17 +65,42 @@ return auto_ptr<XMLElement>(&child2); } -void XMLElement::addAttribute(const string& name, const string& value) +XMLElement::Attributes::iterator XMLElement::findAttribute(const char* name) { - assert(attributes.find(name) == attributes.end()); - attributes[name] = value; + for (Attributes::iterator it = attributes.begin(); + it != attributes.end(); ++it) { + if (it->first == name) { + return it; + } + } + return attributes.end(); } +XMLElement::Attributes::const_iterator XMLElement::findAttribute(const char* name) const +{ + for (Attributes::const_iterator it = attributes.begin(); + it != attributes.end(); ++it) { + if (it->first == name) { + return it; + } + } + return attributes.end(); +} -void XMLElement::setAttribute(const string& name, const string& value) +void XMLElement::addAttribute(const char* name, const string& value) { - attributes[name] = value; + assert(findAttribute(name) == attributes.end()); + attributes.push_back(make_pair(string(name), value)); } +void XMLElement::setAttribute(const char* name, const string& value) +{ + Attributes::iterator it = findAttribute(name); + if (it != attributes.end()) { + it->second = value; + } + attributes.push_back(make_pair(name, value)); +} + bool XMLElement::getDataAsBool() const { return StringOp::stringToBool(getData()); @@ -153,7 +178,7 @@ } XMLElement* XMLElement::findChildWithAttribute(const string& name, - const string& attName, const string& attValue) + const char* attName, const string& attValue) { Children children; getChildren(name, children); @@ -167,7 +192,7 @@ } const XMLElement* XMLElement::findChildWithAttribute(const string& name, - const string& attName, const string& attValue) const + const char* attName, const string& attValue) const { return const_cast<XMLElement*>(this)->findChildWithAttribute( name, attName, attValue); @@ -199,7 +224,7 @@ } XMLElement& XMLElement::getCreateChildWithAttribute( - const string& name, const string& attName, + const string& name, const char* attName, const string& attValue, const string& defaultValue) { XMLElement* result = findChildWithAttribute(name, attName, attValue); @@ -255,52 +280,48 @@ children.clear(); } -bool XMLElement::hasAttribute(const string& name) const +bool XMLElement::hasAttribute(const char* name) const { - return attributes.find(name) != attributes.end(); + return findAttribute(name) != attributes.end(); } -const XMLElement::Attributes& XMLElement::getAttributes() const +const string& XMLElement::getAttribute(const char* attName) const { - return attributes; -} - -const string& XMLElement::getAttribute(const string& attName) const -{ - Attributes::const_iterator it = attributes.find(attName); + Attributes::const_iterator it = findAttribute(attName); if (it == attributes.end()) { - throw ConfigException("Missing attribute \"" + attName + "\"."); + throw ConfigException("Missing attribute \"" + + string(attName) + "\"."); } return it->second; } -const string XMLElement::getAttribute(const string& attName, +const string XMLElement::getAttribute(const char* attName, const string defaultValue) const { - Attributes::const_iterator it = attributes.find(attName); + Attributes::const_iterator it = findAttribute(attName); return (it == attributes.end()) ? defaultValue : it->second; } -bool XMLElement::getAttributeAsBool(const string& attName, +bool XMLElement::getAttributeAsBool(const char* attName, bool defaultValue) const { - Attributes::const_iterator it = attributes.find(attName); + Attributes::const_iterator it = findAttribute(attName); return (it == attributes.end()) ? defaultValue : StringOp::stringToBool(it->second); } -int XMLElement::getAttributeAsInt(const string& attName, +int XMLElement::getAttributeAsInt(const char* attName, int defaultValue) const { - Attributes::const_iterator it = attributes.find(attName); + Attributes::const_iterator it = findAttribute(attName); return (it == attributes.end()) ? defaultValue : StringOp::stringToInt(it->second); } -bool XMLElement::findAttributeInt(const string& attName, +bool XMLElement::findAttributeInt(const char* attName, unsigned& result) const { - Attributes::const_iterator it = attributes.find(attName); + Attributes::const_iterator it = findAttribute(attName); if (it != attributes.end()) { result = StringOp::stringToInt(it->second); return true; @@ -313,7 +334,7 @@ { const XMLElement* elem = this; while (elem) { - Attributes::const_iterator it = elem->attributes.find("id"); + Attributes::const_iterator it = elem->findAttribute("id"); if (it != elem->attributes.end()) { return it->second; } @@ -395,16 +416,25 @@ template<typename Archive> void XMLElement::serialize(Archive& ar, unsigned /*version*/) { - // note: filecontext is not (yet?) serialized + // note1: filecontext is not (yet?) serialized + // + // note2: In the past attributes were stored in a map instead of a + // vector. To keep backwards compatible with the serialized + // format, we still convert attributes to this format. + typedef std::map<std::string, std::string> AttributesMap; + if (!ar.isLoader()) { - ar.serialize("attributes", getAttributes()); + AttributesMap tmpAtt(attributes.begin(), attributes.end()); + ar.serialize("attributes", tmpAtt); ar.serialize("children", getChildren()); } else { - XMLElement::Attributes tmpAtt; + AttributesMap tmpAtt; ar.serialize("attributes", tmpAtt); - for (XMLElement::Attributes::const_iterator it = tmpAtt.begin(); + for (AttributesMap::const_iterator it = tmpAtt.begin(); it != tmpAtt.end(); ++it) { - addAttribute(it->first, it->second); + // TODO "string -> char* -> string" conversion can + // be optimized + addAttribute(it->first.c_str(), it->second); } XMLElement::Children tmp; Modified: openmsx/trunk/src/config/XMLElement.hh =================================================================== --- openmsx/trunk/src/config/XMLElement.hh 2010-07-09 21:07:07 UTC (rev 11583) +++ openmsx/trunk/src/config/XMLElement.hh 2010-07-09 21:07:27 UTC (rev 11584) @@ -4,7 +4,7 @@ #define XMLELEMENT_HH #include "serialize_constr.hh" -#include <map> +#include <utility> #include <string> #include <vector> #include <memory> @@ -37,10 +37,8 @@ void setData(const std::string& data); // attribute - typedef std::map<std::string, std::string> Attributes; - void addAttribute(const std::string& name, const std::string& value); - void setAttribute(const std::string& name, const std::string& value); - const Attributes& getAttributes() const; + void addAttribute(const char* name, const std::string& value); + void setAttribute(const char* name, const std::string& value); // parent XMLElement* getParent(); @@ -67,15 +65,15 @@ double getDataAsDouble() const; // attribute - bool hasAttribute(const std::string& name) const; - const std::string& getAttribute(const std::string& attName) const; - const std::string getAttribute(const std::string& attName, + bool hasAttribute(const char* name) const; + const std::string& getAttribute(const char* attName) const; + const std::string getAttribute(const char* attName, const std::string defaultValue) const; - bool getAttributeAsBool(const std::string& attName, + bool getAttributeAsBool(const char* attName, bool defaultValue = false) const; - int getAttributeAsInt(const std::string& attName, + int getAttributeAsInt(const char* attName, int defaultValue = 0) const; - bool findAttributeInt(const std::string& attName, + bool findAttributeInt(const char* attName, unsigned& result) const; const std::string& getId() const; @@ -84,10 +82,10 @@ XMLElement* findChild(const std::string& name); const XMLElement& getChild(const std::string& name) const; const XMLElement* findChildWithAttribute( - const std::string& name, const std::string& attName, + const std::string& name, const char* attName, const std::string& attValue) const; XMLElement* findChildWithAttribute( - const std::string& name, const std::string& attName, + const std::string& name, const char* attName, const std::string& attValue); const XMLElement* findNextChild(const char* name, unsigned& fromIndex) const; @@ -98,7 +96,7 @@ XMLElement& getCreateChild(const std::string& name, const std::string& defaultValue = ""); XMLElement& getCreateChildWithAttribute( - const std::string& name, const std::string& attName, + const std::string& name, const char* attName, const std::string& attValue, const std::string& defaultValue = ""); const std::string& getChildData(const std::string& name) const; @@ -120,6 +118,10 @@ void serialize(Archive& ar, unsigned version); private: + typedef std::pair<std::string, std::string> Attribute; + typedef std::vector<Attribute> Attributes; + Attributes::iterator findAttribute(const char* name); + Attributes::const_iterator findAttribute(const char* name) const; void dump(std::string& result, unsigned indentNum) const; std::string name; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m97...@us...> - 2012-05-19 11:29:37
|
Revision: 12534 http://openmsx.svn.sourceforge.net/openmsx/?rev=12534&view=rev Author: m9710797 Date: 2012-05-19 11:29:31 +0000 (Sat, 19 May 2012) Log Message: ----------- Fixed cppcheck style-warning Fixed style warning generated by the 'cppcheck' static analysis tool: Assignment operator should return reference to non-const. Modified Paths: -------------- openmsx/trunk/src/config/XMLElement.cc openmsx/trunk/src/config/XMLElement.hh Modified: openmsx/trunk/src/config/XMLElement.cc =================================================================== --- openmsx/trunk/src/config/XMLElement.cc 2012-05-19 10:35:49 UTC (rev 12533) +++ openmsx/trunk/src/config/XMLElement.cc 2012-05-19 11:29:31 UTC (rev 12534) @@ -347,7 +347,7 @@ } } -const XMLElement& XMLElement::operator=(const XMLElement& element) +XMLElement& XMLElement::operator=(const XMLElement& element) { if (&element == this) { // assign to itself Modified: openmsx/trunk/src/config/XMLElement.hh =================================================================== --- openmsx/trunk/src/config/XMLElement.hh 2012-05-19 10:35:49 UTC (rev 12533) +++ openmsx/trunk/src/config/XMLElement.hh 2012-05-19 11:29:31 UTC (rev 12534) @@ -29,7 +29,7 @@ XMLElement(const std::string& name, const std::string& data); XMLElement(const char* name, const char* data); XMLElement(const XMLElement& element); - const XMLElement& operator=(const XMLElement& element); + XMLElement& operator=(const XMLElement& element); ~XMLElement(); // name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <m97...@us...> - 2013-03-11 19:06:26
|
Revision: 13197 http://openmsx.svn.sourceforge.net/openmsx/?rev=13197&view=rev Author: m9710797 Date: 2013-03-11 19:06:15 +0000 (Mon, 11 Mar 2013) Log Message: ----------- Increase the serialization-version of HardwareConfig Revision 13177 changed the HardwareConfig::config member variable type from 'unique_ptr<XMLElement>' to 'XMLElement'. This has a (small) impact on the generated XML serialization output: the 'id' attributes in some XML tags are gone now. To load old savestates this doesn't matter (the attributes are simply ignored), so we didn't need bw-compat serialization (load) code. However when a new savestate is loaded in an older version, then the 'id' attributes will be searched for and the savestate fails to load. It's of course much nicer if the loading fails with an error about an unsupported savestate version than with an error about missing stuff in the XML file. So revision 13177 should have increased the serialization version. I've increased the version in this revision. Unfortunately savestates created between this revision and 13177 will still not give a proper error message when loaded in an older (but not too much older) openMSX version. Revision Links: -------------- http://openmsx.svn.sourceforge.net/openmsx/?rev=13177&view=rev http://openmsx.svn.sourceforge.net/openmsx/?rev=13177&view=rev Modified Paths: -------------- openmsx/trunk/src/config/HardwareConfig.cc openmsx/trunk/src/config/HardwareConfig.hh Modified: openmsx/trunk/src/config/HardwareConfig.cc =================================================================== --- openmsx/trunk/src/config/HardwareConfig.cc 2013-03-10 09:48:43 UTC (rev 13196) +++ openmsx/trunk/src/config/HardwareConfig.cc 2013-03-11 19:06:15 UTC (rev 13197) @@ -370,6 +370,7 @@ // version 1: initial version // version 2: moved FileContext here (was part of config) +// version 3: hold 'config' by-value instead of by-pointer template<typename Archive> void HardwareConfig::serialize(Archive& ar, unsigned version) { Modified: openmsx/trunk/src/config/HardwareConfig.hh =================================================================== --- openmsx/trunk/src/config/HardwareConfig.hh 2013-03-10 09:48:43 UTC (rev 13196) +++ openmsx/trunk/src/config/HardwareConfig.hh 2013-03-11 19:06:15 UTC (rev 13197) @@ -83,7 +83,7 @@ friend struct SerializeConstructorArgs<HardwareConfig>; }; -SERIALIZE_CLASS_VERSION(HardwareConfig, 2); +SERIALIZE_CLASS_VERSION(HardwareConfig, 3); template<> struct SerializeConstructorArgs<HardwareConfig> { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |