Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F7877880
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Subscribers
None
View Options
diff --git a/Utilities/XML/Element.cc b/Utilities/XML/Element.cc
--- a/Utilities/XML/Element.cc
+++ b/Utilities/XML/Element.cc
@@ -1,196 +1,204 @@
// -*- C++ -*-
//
// Element.cpp is a part of myXML
// Copyright (C) 2012-2013 Simon Platzer
//
// myXML is licenced under version 2 of the GPL, see COPYING for details.
//
#include "Element.h"
#include <exception>
#include <stdexcept>
using namespace XML;
using namespace std;
Element::Element(const Element& other)
: theType(other.theType),
theNameOrContent(other.theNameOrContent),
theAttributes(other.theAttributes),
theChildren(other.theChildren) {
index();
}
Element& Element::operator=(const Element& other) {
theType = other.theType;
theNameOrContent = other.theNameOrContent;
theAttributes = other.theAttributes;
theChildren = other.theChildren;
index();
return *this;
}
namespace XML {
bool operator==(const XML::Element &one, const XML::Element &two) {
return(one.theType == two.theType &&
one.theNameOrContent == two.theNameOrContent &&
one.theAttributes == two.theAttributes &&
one.theChildren == two.theChildren
);
}
- bool operator!=(const XML::Element &one, const XML::Element &two)
- {
+ bool operator!=(const XML::Element &one, const XML::Element &two) {
return !(one == two);
}
+
+ XML::Element operator+(const XML::Element& one, const XML::Element& two) {
+ if ( one.type() != two.type())
+ throw logic_error("[XML::Element] Trying to combine elements with different types");
+
+ XML::Element returnElement = XML::Element(one);
+ return returnElement;
+ }
}
+
const string& Element::name() const {
assertNamed();
return theNameOrContent;
}
const string& Element::content() const {
assertContent();
return theNameOrContent;
}
string& Element::content() {
assertContent();
return theNameOrContent;
}
bool Element::hasAttribute(const string& id) const {
assertAttributes();
return theAttributes.find(id) != theAttributes.end();
}
const map<string,string>& Element::attributes() const {
assertAttributes();
return theAttributes;
}
const string& Element::attribute(const string& id) const {
assertAttributes();
map<string,string>::const_iterator ait = theAttributes.find(id);
if ( ait == theAttributes.end() )
throw runtime_error("[XML::Element] no such attribute found.");
return ait->second;
}
string& Element::attribute(const string& id) {
assertAttributes();
string& ret = theAttributes[id];
return ret;
}
Element& Element::operator<<(const Element::Attribute& a) {
attribute(a.name) = a.value;
return *this;
}
const list<Element>& Element::children() const {
assertChildren();
return theChildren;
}
list<Element>& Element::children() {
assertChildren();
return theChildren;
}
Element& Element::append(const Element& e) {
assertChildren();
theChildren.push_back(e);
index();
return theChildren.back();
}
Element& Element::prepend(const Element& e) {
assertChildren();
theChildren.push_front(e);
index();
return theChildren.front();
}
void Element::insert(list<Element>::iterator pos,
const Element& e) {
assertChildren();
theChildren.insert(pos,e);
index();
}
void Element::erase(list<Element>::iterator pos) {
assertChildren();
theChildren.erase(pos);
index();
}
Element& Element::operator<<(const Element& e) {
append(e);
return *this;
}
void Element::index() {
theIndex.clear();
for ( list<Element>::iterator i = theChildren.begin();
i != theChildren.end(); ++i ) {
if ( i->type() == ElementTypes::Element ||
i->type() == ElementTypes::EmptyElement )
theIndex.insert(make_pair(pair<int,string>(i->type(),i->name()),i));
else
theIndex.insert(make_pair(pair<int,string>(i->type(),string("")),i));
}
}
list<Element>::const_iterator
Element::findFirst(int type, const string& name) const {
assertChildren();
typedef
multimap<pair<int,string>,list<Element>::iterator>::const_iterator
IndexIterator;
IndexIterator i = theIndex.find(make_pair(type,name));
if ( i == theIndex.end() )
return theChildren.end();
return i->second;
}
pair<multimap<pair<int,string>,list<Element>::iterator>::const_iterator,
multimap<pair<int,string>,list<Element>::iterator>::const_iterator>
Element::findAll(int type, const string& name) const {
assertChildren();
return theIndex.equal_range(make_pair(type,name));
}
void Element::assertContent() const {
if ( type() == ElementTypes::ProcessingInstruction ||
type() == ElementTypes::CharacterData ||
type() == ElementTypes::ParsedCharacterData ||
type() == ElementTypes::Comment )
return;
throw logic_error("[XML::Element] element has no plain character content.");
}
void Element::assertNamed() const {
if ( type() == ElementTypes::EmptyElement ||
type() == ElementTypes::Element )
return;
throw logic_error("[XML::Element] element has no name.");
}
void Element::assertAttributes() const {
if ( type() == ElementTypes::EmptyElement ||
type() == ElementTypes::Element )
return;
throw logic_error("[XML::Element] element has no attributes.");
}
void Element::assertChildren() const {
if ( type() == ElementTypes::Element ||
type() == ElementTypes::Root )
return;
throw logic_error("[XML::Element] element has no children elements.");
}
diff --git a/Utilities/XML/Element.h b/Utilities/XML/Element.h
--- a/Utilities/XML/Element.h
+++ b/Utilities/XML/Element.h
@@ -1,339 +1,346 @@
// -*- C++ -*-
//
// Element.hpp is a part of myXML
// Copyright (C) 2012-2013 Simon Platzer
//
// myXML is licenced under version 2 of the GPL, see COPYING for details.
//
#ifndef MYXML_Element_hpp_included
#define MYXML_Element_hpp_included
#include <string>
#include <map>
#include <list>
#include <sstream>
#include <iomanip>
namespace XML {
/**
* \brief ElementTypes contains the element type enumeration
* \author Simon Platzer
*/
namespace ElementTypes {
/**
* The element type enumeration
*/
enum EnumerateElementTypes {
Unknown = -1,
/** Unknown element type */
Root = 0,
/** The entire document */
EmptyElement = 1,
/** An empty element */
Element = 2,
/** An element */
ProcessingInstruction = 3,
/** A processing instruction */
CharacterData = 4,
/** Character data */
ParsedCharacterData = 5,
/** Parsed character data */
Comment = 6
/** A comment */
};
}
/**
* \brief Element represents a (tree of) XML elements
* \author Simon Platzer
*/
class Element {
public:
/**
* The default constructor
*/
Element()
: theType(ElementTypes::Unknown) {}
/**
* The standard constructor
*/
explicit Element(int newType,
const std::string& newNameOrContent = "")
: theType(newType), theNameOrContent(newNameOrContent) {}
/**
* The copy constructor
*/
Element(const Element& other);
/**
* Assignment
*/
Element& operator=(const Element& other);
/**
* Comparison operator
*
*/
friend bool operator==(const XML::Element &one, const XML::Element &two);
friend bool operator!=(const XML::Element &one, const XML::Element &two);
+ /**
+ * Combine operator
+ *
+ * Operator checks if type and name is equal otherwises throws exception
+ */
+ friend XML::Element operator+(const XML::Element& one, const XML::Element& two);
+
public:
/**
* Return the type of this element
*/
int type() const { return theType; }
/**
* Return the name of this element
*/
const std::string& name() const;
public:
/**
* Return the content of this element
*/
const std::string& content() const;
/**
* Access the content of this element
*/
std::string& content();
/**
* Append to the content of this element
*/
template<class T>
Element& operator<<(const T& t) {
assertContent();
std::ostringstream out;
out << std::setprecision(16) << t;
theNameOrContent += out.str();
return *this;
}
public:
/**
* Return true, if this element has attributes
*/
bool hasAttributes() const {
return
type() == ElementTypes::Element ||
type() == ElementTypes::EmptyElement;
}
/**
* Return true, if this element contains an attribute of the given name
*/
bool hasAttribute(const std::string&) const;
/**
* Return the attributes
*/
const std::map<std::string,std::string>& attributes() const;
/**
* Return the attribute of the given name
*/
const std::string& attribute(const std::string&) const;
/**
* Access the attribute of the given name
*/
std::string& attribute(const std::string&);
/**
* Represent an attribute
*/
struct Attribute {
/**
* The attribute name
*/
std::string name;
/**
* The attribute value
*/
std::string value;
/**
* Construct an attribute
*/
template<class T>
Attribute(const std::string& newName,
const T& newValue)
: name(newName) {
std::ostringstream valueOut;
valueOut << std::setprecision(16) << newValue;
value = valueOut.str();
}
/**
* Comparison operators for attributes
*/
inline bool operator==(const Attribute& other) {
return ( name == other.name &&
value == other.value);
}
inline bool operator!=(const Attribute& other) {
return !(*this == other);
}
};
/**
* Append an attribute to this element
*/
Element& operator<<(const Attribute&);
/**
* Append an attribute to this element
*/
template<class T>
void appendAttribute(const std::string& name, const T& t) {
*this << Attribute(name,t);
}
/**
* Get a value from an attribute
*/
template<class T>
void getFromAttribute(const std::string& name, T& t) const {
std::istringstream in(attribute(name));
in >> std::setprecision(16) >> t;
}
public:
/**
* Return true, if this element has children
*/
bool hasChildren() const {
return
type() == ElementTypes::Root ||
type() == ElementTypes::Element;
}
/**
* Return the list of children elements
*/
const std::list<Element>& children() const;
/**
* Access the list of children elements
*/
std::list<Element>& children();
/**
* Append a child element to this element
*/
Element& append(const Element&);
/**
* Prepend a child element to this element
*/
Element& prepend(const Element&);
/**
* Append a child element to this element
*/
Element& operator<<(const Element&);
/**
* Insert an element before the given position
*/
void insert(std::list<Element>::iterator, const Element&);
/**
* Erase an element at the given position
*/
void erase(std::list<Element>::iterator);
/**
* Find the first element of the given type and name
*/
std::list<Element>::const_iterator
findFirst(int type, const std::string& name) const;
/**
* Find all elements of the given type and name
*/
std::pair<std::multimap<std::pair<int,std::string>,std::list<Element>::iterator>::const_iterator,
std::multimap<std::pair<int,std::string>,std::list<Element>::iterator>::const_iterator>
findAll(int type, const std::string& name) const;
private:
/**
* The type of this element
*/
int theType;
/**
* The name or character content of the element
*/
std::string theNameOrContent;
/**
* The attributes of this element
*/
std::map<std::string,std::string> theAttributes;
/**
* The children elements of this element
*/
std::list<Element> theChildren;
/**
* Index children elements by type and name
*/
std::multimap<std::pair<int,std::string>,std::list<Element>::iterator> theIndex;
private:
/**
* Index elements by type and name
*/
void index();
/**
* Assert that this element got a character content
*/
void assertContent() const;
/**
* Assert that this element is named
*/
void assertNamed() const;
/**
* Assert that this element contains attributes
*/
void assertAttributes() const;
/**
* Assert that this element contains children elements
*/
void assertChildren() const;
};
}
#endif // MYXML_Element_hpp_included
diff --git a/Utilities/XML/tests/xmlTests.cc b/Utilities/XML/tests/xmlTests.cc
--- a/Utilities/XML/tests/xmlTests.cc
+++ b/Utilities/XML/tests/xmlTests.cc
@@ -1,192 +1,205 @@
// -*- C++ -*-
//
// xmlTests.cc is a part of myXML
// Copyright (C) 2015 Simon Plaetzer, Marco A. Harrendorf
//
// myXML is licenced under version 2 of the GPL, see COPYING for details.
//
#include "Herwig++/Utilities/XML/Element.h"
#include "Herwig++/Utilities/XML/ElementIO.h"
#define BOOST_TEST_MODULE xmlTest
#include <boost/test/included/unit_test.hpp>
/*
* Fixture which defines the common variables for testing Element class
*/
struct Fix1 {
Fix1() : elementUnknown(XML::ElementTypes::Unknown,""),
elementRoot(XML::ElementTypes::Root,"Root"),
elementEmpty(XML::ElementTypes::EmptyElement,""),
elementElement(XML::ElementTypes::Element, "Element"),
elementProcessingInstruction(XML::ElementTypes::ProcessingInstruction, "ProcessingInstruction"),
elementCharacterData(XML::ElementTypes::CharacterData, "CharacterData"),
elementParsedCharacterData(XML::ElementTypes::ParsedCharacterData, "ParsedCharacterData"),
elementComment(XML::ElementTypes::Comment, "Comment"),
elementGrids(XML::ElementTypes::Element,"Grids")
{BOOST_TEST_MESSAGE( "setup fixture for xmlTest" ); }
~Fix1() { BOOST_TEST_MESSAGE( "teardown fixture for xmlTest" ); }
XML::Element elementUnknown;
XML::Element elementRoot;
XML::Element elementEmpty;
XML::Element elementElement;
XML::Element elementProcessingInstruction;
XML::Element elementCharacterData;
XML::Element elementParsedCharacterData;
XML::Element elementComment;
XML::Element elementGrids;
};
//____________________________________________________________________________//
/*
* Start of boost unit tests
* @todo Implement tests for ElementIO
*/
BOOST_FIXTURE_TEST_SUITE(xmlTestElement, Fix1 )
-
/*
* Boost unit tests for Element.h
* @todo Implement further tests for child operations
*/
BOOST_AUTO_TEST_CASE(elementTypes)
{
BOOST_CHECK_EQUAL(elementUnknown.type(), -1);
BOOST_CHECK_EQUAL(elementRoot.type(), 0);
BOOST_CHECK_EQUAL(elementEmpty.type(), 1);
BOOST_CHECK_EQUAL(elementElement.type(), 2);
BOOST_CHECK_EQUAL(elementGrids.type(), 2);
BOOST_CHECK_EQUAL(elementProcessingInstruction.type(), 3);
BOOST_CHECK_EQUAL(elementCharacterData.type(), 4);
BOOST_CHECK_EQUAL(elementParsedCharacterData.type(), 5);
BOOST_CHECK_EQUAL(elementComment.type(), 6);
}
BOOST_AUTO_TEST_CASE(constructors)
{
BOOST_CHECK(elementUnknown == XML::Element());
BOOST_CHECK(elementComment == XML::Element(XML::ElementTypes::Comment, "Comment"));
BOOST_CHECK(elementUnknown != elementComment);
XML::Element elementCopy = elementComment;
BOOST_CHECK(elementCopy == elementComment);
XML::Element elementAssignment = XML::Element();
elementAssignment = elementGrids;
BOOST_CHECK(elementAssignment == elementGrids);
}
-
+BOOST_AUTO_TEST_CASE(combineOperator)
+{
+
+ BOOST_CHECK(elementElement + elementElement == elementElement);
+ BOOST_CHECK_THROW((elementElement + elementComment), std::logic_error);
+ XML::Element elementName1 = XML::Element(XML::ElementTypes::Element, "Name1") ;
+ XML::Element elementName2 = XML::Element(XML::ElementTypes::Element, "Name2") ;
+ BOOST_CHECK_THROW(elementElement + elementGrids, std::logic_error);
+
+ XML::Element elementWithBothChildren = XML::Element(elementElement);
+ elementWithBothChildren.append(elementComment);
+ elementWithBothChildren.append(elementParsedCharacterData);
+ XML::Element elementWithChild1 = XML::Element(elementElement);
+ elementWithChild1.append(elementComment);
+ XML::Element elementWithChild2 = XML::Element(elementElement);
+ elementWithChild2.append(elementParsedCharacterData);
+ BOOST_CHECK(elementWithChild1 + elementWithChild2 == elementWithBothChildren);
+}
BOOST_AUTO_TEST_CASE(type)
{
BOOST_CHECK(elementUnknown.type() != elementGrids.type());
BOOST_CHECK_EQUAL(elementGrids.type(), XML::ElementTypes::Element);
}
BOOST_AUTO_TEST_CASE(name)
{
BOOST_CHECK(elementElement.name() != elementEmpty.name());
BOOST_CHECK_EQUAL(elementGrids.name(), "Grids");
}
BOOST_AUTO_TEST_CASE(content)
{
BOOST_CHECK_EQUAL(elementProcessingInstruction.content(), "ProcessingInstruction");
BOOST_CHECK_EQUAL(elementCharacterData.content(), "CharacterData");
BOOST_CHECK_EQUAL(elementParsedCharacterData.content(), "ParsedCharacterData");
BOOST_CHECK_EQUAL(elementComment.content(), "Comment");
XML::Element elementAppendContent = XML::Element(elementComment);
elementAppendContent << std::string("Test");
BOOST_CHECK_EQUAL(elementAppendContent.content(), "CommentTest");
}
-
BOOST_AUTO_TEST_CASE(attributes)
{
BOOST_CHECK(elementEmpty.hasAttributes());
BOOST_CHECK(elementElement.hasAttributes());
BOOST_CHECK(elementGrids.hasAttributes());
XML::Element elementEmptyWithAttributes = XML::Element(elementEmpty);
elementEmptyWithAttributes.appendAttribute("Entry1", "Value1");
BOOST_CHECK(elementEmptyWithAttributes.hasAttribute("Entry1"));
XML::Element elementElementWithAttributes = XML::Element(elementElement);
XML::Element::Attribute elementAttribute = XML::Element::Attribute("Entry2","Value2");
elementElementWithAttributes << elementAttribute;
elementElementWithAttributes.appendAttribute("Entry3","Value3");
BOOST_CHECK(elementElementWithAttributes.hasAttribute("Entry2"));
BOOST_CHECK(elementElementWithAttributes.hasAttribute("Entry3"));
std::map<std::string,std::string> comparisonAttributes;
comparisonAttributes.insert(std::pair<std::string,std::string>("Entry2", "Value2"));
comparisonAttributes.insert(std::pair<std::string,std::string>("Entry3", "Value3"));
std::map<std::string,std::string> elementElementWithAttributesMap = elementElementWithAttributes.attributes();
BOOST_CHECK(comparisonAttributes == elementElementWithAttributesMap);
BOOST_CHECK_EQUAL(elementElementWithAttributes.attribute("Entry3"), "Value3");
std::string elementAttributeOutput;
elementElementWithAttributes.getFromAttribute("Entry3", elementAttributeOutput);
BOOST_CHECK_EQUAL(elementAttributeOutput, "Value3");
XML::Element::Attribute elementAttribute4 = XML::Element::Attribute("Entry4","Value4");
XML::Element::Attribute elementAttribute5 = XML::Element::Attribute("Entry5","Value5");
BOOST_CHECK(elementAttribute4 == XML::Element::Attribute("Entry4","Value4"));
BOOST_CHECK(elementAttribute4 != XML::Element::Attribute("Entry4",""));
BOOST_CHECK(elementAttribute4 != XML::Element::Attribute("","Value4"));
BOOST_CHECK(elementAttribute4 != elementAttribute5);
}
BOOST_AUTO_TEST_CASE(children)
{
BOOST_CHECK(elementRoot.hasChildren());
BOOST_CHECK(elementElement.hasChildren());
BOOST_CHECK(elementGrids.hasChildren());
std::list<XML::Element> listWithoutElement;
BOOST_CHECK(elementRoot.children() == listWithoutElement);
BOOST_CHECK(elementElement.children() == listWithoutElement);
std::list<XML::Element> listWithElement;
listWithElement.push_back(elementComment);
listWithElement.push_front(elementParsedCharacterData);
XML::Element elementWithChildren = XML::Element(elementElement);
elementWithChildren.append(elementComment);
elementWithChildren.prepend(elementParsedCharacterData);
BOOST_CHECK(elementWithChildren.children() == listWithElement);
elementWithChildren << elementGrids;
listWithElement.push_back(elementGrids);
BOOST_CHECK(elementWithChildren.children() == listWithElement);
}
-
-
-
+
BOOST_AUTO_TEST_CASE(generalTest)
{
BOOST_FAIL( "Test finished" );
}
BOOST_AUTO_TEST_SUITE_END()
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Nov 19, 4:36 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805193
Default Alt Text
(20 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment