diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ae0900d23c17043d98f0babfad00636216ef865..0cc11e864ef9db67ced78a2055d53d8f3360148b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,35 +32,43 @@ if(XDMF_WRAP_PYTHON) swig_link_libraries(Xdmf Xdmf ${PYTHON_LIBRARIES}) endif(XDMF_WRAP_PYTHON) -set(XdmfSources +set(XdmfCoreSources XdmfArray XdmfArrayType + XdmfCoreItemFactory + XdmfCoreReader + XdmfDataItem + XdmfHDF5Controller + XdmfHDF5Writer + XdmfItem + XdmfItemProperty + XdmfObject + XdmfVisitor + XdmfWriter +) + +set(XdmfSources XdmfAttribute XdmfAttributeCenter XdmfAttributeType - XdmfDataItem XdmfDomain XdmfGeometry XdmfGeometryType XdmfGrid XdmfGridCollection XdmfGridCollectionType - XdmfHDF5Controller - XdmfHDF5Writer - XdmfItem - XdmfItemProperty - XdmfObject + XdmfItemFactory XdmfReader XdmfSet XdmfSetType XdmfTopology XdmfTopologyType - XdmfVisitor - XdmfWriter ) +add_library(XdmfCore ${XdmfCoreSources}) +target_link_libraries(XdmfCore ${HDF5_LIBRARIES} ${LIBXML2_LIBRARIES}) add_library(Xdmf ${XdmfSources}) -target_link_libraries(Xdmf ${HDF5_LIBRARIES} ${LIBXML2_LIBRARIES}) +target_link_libraries(Xdmf XdmfCore) option(XDMF_BUILD_DOCUMENTATION OFF) if(XDMF_BUILD_DOCUMENTATION) diff --git a/XdmfCoreItemFactory.cpp b/XdmfCoreItemFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a51a82e7499771679efe2fa07d1466aa2cf5e0ba --- /dev/null +++ b/XdmfCoreItemFactory.cpp @@ -0,0 +1,9 @@ +#include "XdmfCoreItemFactory.hpp" + +XdmfCoreItemFactory::XdmfCoreItemFactory() +{ +} + +XdmfCoreItemFactory::~XdmfCoreItemFactory() +{ +} diff --git a/XdmfCoreItemFactory.hpp b/XdmfCoreItemFactory.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dfd5d6e4043aee6f3f5ea3567074d7d56fee1fa9 --- /dev/null +++ b/XdmfCoreItemFactory.hpp @@ -0,0 +1,41 @@ +#ifndef XDMFCOREITEMFACTORY_HPP_ +#define XDMFCOREITEMFACTORY_HPP_ + +// Forward Declarations +class XdmfItem; + +// Includes +#include +#include "XdmfObject.hpp" + +/** + * @brief Factory for constructing XdmfItems from their ItemTag and ItemProperties + * + * XdmfCoreItemFactory is an abstract base class. + */ +class XdmfCoreItemFactory : public XdmfObject { + +public: + + virtual ~XdmfCoreItemFactory(); + + /** + * Create a new XdmfItem. + * + * @param itemTag a string containing the tag of the XdmfItem to create. + * @param itemProperties a map of key/value properties for the the XdmfItem. + */ + virtual boost::shared_ptr createItem(const std::string & itemTag, const std::map & itemProperties) const = 0; + +protected: + + XdmfCoreItemFactory(); + +private: + + XdmfCoreItemFactory(const XdmfCoreItemFactory & itemFactory); // Not implemented. + void operator=(const XdmfCoreItemFactory & itemFactory); // Not implemented. + +}; + +#endif /* XDMFCOREITEMFACTORY_HPP_ */ diff --git a/XdmfCoreReader.cpp b/XdmfCoreReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c11eff304ad4a175768a0a073b203f7dafc1c0d --- /dev/null +++ b/XdmfCoreReader.cpp @@ -0,0 +1,96 @@ +// Kenneth Leiter +// Xdmf Smart Pointer Test + +#include +#include "XdmfCoreItemFactory.hpp" +#include "XdmfCoreReader.hpp" +#include "XdmfItem.hpp" + +/** + * PIMPL + */ +class XdmfCoreReader::XdmfCoreReaderImpl { + +public: + + XdmfCoreReaderImpl(const boost::shared_ptr itemFactory) : + mItemFactory(itemFactory) + { + }; + + ~XdmfCoreReaderImpl() + { + }; + + std::vector > read(xmlNodePtr currNode) const + { + std::vector > myItems; + + while(currNode != NULL) + { + if(currNode->type == XML_ELEMENT_NODE) + { + std::map itemProperties; + std::cout << currNode->name << std::endl; + if(currNode->children != NULL) + { + itemProperties["Content"] = (const char *)currNode->children->content; + } + else + { + itemProperties["Content"] = ""; + } + xmlAttrPtr currAttribute = currNode->properties; + while(currAttribute != NULL) + { + itemProperties[(const char *)currAttribute->name] = (const char *)currAttribute->children->content; + currAttribute = currAttribute->next; + } + std::vector > childItems = this->read(currNode->children); + boost::shared_ptr newItem = mItemFactory->createItem((const char *)currNode->name, itemProperties); + newItem->populateItem(itemProperties, childItems); + myItems.push_back(newItem); + } + currNode = currNode->next; + } + return myItems; + } + +private: + + const boost::shared_ptr mItemFactory; +}; + +XdmfCoreReader::XdmfCoreReader(const boost::shared_ptr itemFactory) : + mImpl(new XdmfCoreReaderImpl(itemFactory)) +{ + std::cout << "Created XdmfReader " << this << std::endl; +} + +XdmfCoreReader::~XdmfCoreReader() +{ + delete mImpl; + std::cout << "Deleted XdmfReader " << this << std::endl; +} + +boost::shared_ptr XdmfCoreReader::read(const std::string & filePath) const +{ + xmlDocPtr document; + xmlNodePtr currNode; + + document = xmlReadFile(filePath.c_str(), NULL, 0); + if(document == NULL) + { + assert(false); + } + currNode = xmlDocGetRootElement(document); + + std::vector > toReturn = mImpl->read(currNode->children); + + xmlFreeDoc(document); + xmlCleanupParser(); + + return toReturn[0]; +} + + diff --git a/XdmfCoreReader.hpp b/XdmfCoreReader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3a8ceeb22dcea6f865a115101b100f549cee4775 --- /dev/null +++ b/XdmfCoreReader.hpp @@ -0,0 +1,42 @@ +#ifndef XDMFCOREREADER_HPP_ +#define XDMFCOREREADER_HPP_ + +// Forward Declarations +class XdmfCoreItemFactory; +class XdmfItem; + +// Includes +#include "XdmfObject.hpp" + +/** + * @brief Reads an Xdmf structured file stored on disk into memory. + * + * Reads an Xdmf structured file stored on disk into an Xdmf structure in memory. All light data is parsed in order to create appropriate + * Xdmf objects. Heavy data controllers are created and attached to XdmfArrays but no heavy data is read into memory. + */ +class XdmfCoreReader : public XdmfObject { + +public: + + virtual ~XdmfCoreReader(); + + virtual boost::shared_ptr read(const std::string & fileName) const; + +protected: + + XdmfCoreReader(const boost::shared_ptr itemFactory); + +private: + + /** + * PIMPL + */ + class XdmfCoreReaderImpl; + + XdmfCoreReader(const XdmfCoreReader & reader); // Not implemented. + void operator=(const XdmfCoreReader & reader); // Not implemented. + + const XdmfCoreReaderImpl * const mImpl; +}; + +#endif /* XDMFCOREREADER_HPP_ */ diff --git a/XdmfItem.hpp b/XdmfItem.hpp index 9d289f146047f3c7dfdebc625d8ae4a256dbaad2..69fd5489dccd3cd42c6df9f1c6cc8c10f435537d 100644 --- a/XdmfItem.hpp +++ b/XdmfItem.hpp @@ -1,11 +1,3 @@ -/** - * An XdmfItem replaces the XdmfElement class in the previous version of Xdmf. An XdmfItem represents an item that can be - * visited by an XdmfVisitor and have it's contents added to an Xdmf file. These include XdmfGrids, XdmfSets, - * XdmfTopologies, etc. - * - * This is an abstract base class. - */ - #ifndef XDMFITEM_HPP_ #define XDMFITEM_HPP_ @@ -32,7 +24,7 @@ public: virtual ~XdmfItem(); LOKI_DEFINE_VISITABLE_BASE() - friend class XdmfReader; + friend class XdmfCoreReader; /** * Get the tag for this XdmfItem. This is equivalent to tags in XML parlance. diff --git a/XdmfItemFactory.cpp b/XdmfItemFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7447a1284b26753d458a77e8e74ddb9ce4990126 --- /dev/null +++ b/XdmfItemFactory.cpp @@ -0,0 +1,63 @@ +#include "XdmfArray.hpp" +#include "XdmfAttribute.hpp" +#include "XdmfDomain.hpp" +#include "XdmfGeometry.hpp" +#include "XdmfGrid.hpp" +#include "XdmfGridCollection.hpp" +#include "XdmfItemFactory.hpp" +#include "XdmfSet.hpp" +#include "XdmfTopology.hpp" + +XdmfItemFactory::XdmfItemFactory() +{ +} + +XdmfItemFactory::~XdmfItemFactory() +{ +} + +boost::shared_ptr XdmfItemFactory::createItem(const std::string & itemTag, const std::map & itemProperties) const +{ + boost::shared_ptr newItem; + if(itemTag.compare(XdmfArray::ItemTag) == 0) + { + newItem = XdmfArray::New(); + } + else if(itemTag.compare(XdmfAttribute::ItemTag) == 0) + { + newItem = XdmfAttribute::New(); + } + else if(itemTag.compare(XdmfDomain::ItemTag) == 0) + { + newItem = XdmfDomain::New(); + } + else if(itemTag.compare(XdmfGeometry::ItemTag) == 0) + { + newItem = XdmfGeometry::New(); + } + else if(itemTag.compare(XdmfGrid::ItemTag) == 0) + { + std::map::const_iterator gridType = itemProperties.find("GridType"); + if(gridType != itemProperties.end() && gridType->second.compare("Collection") == 0) + { + newItem = XdmfGridCollection::New(); + } + else + { + newItem = XdmfGrid::New(); + } + } + else if(itemTag.compare(XdmfSet::ItemTag) == 0) + { + newItem = XdmfSet::New(); + } + else if(itemTag.compare(XdmfTopology::ItemTag) == 0) + { + newItem = XdmfTopology::New(); + } + else + { + assert(false); + } + return newItem; +} diff --git a/XdmfItemFactory.hpp b/XdmfItemFactory.hpp new file mode 100644 index 0000000000000000000000000000000000000000..933ea3158d766fa46973e0f26580edc290c3fae9 --- /dev/null +++ b/XdmfItemFactory.hpp @@ -0,0 +1,39 @@ +#ifndef XDMFITEMFACTORY_HPP_ +#define XDMFITEMFACTORY_HPP_ + +// Forward Declarations +class XdmfItem; + +// Includes +#include "XdmfCoreItemFactory.hpp" + +/** + * @brief Factory for constructing XdmfItems from their ItemTag and ItemProperties + */ +class XdmfItemFactory : public XdmfCoreItemFactory { + +public: + + XdmfNewMacro(XdmfItemFactory); + virtual ~XdmfItemFactory(); + + /** + * Create a new XdmfItem. + * + * @param itemTag a string containing the tag of the XdmfItem to create. + * @param itemProperties a map of key/value properties for the the XdmfItem. + */ + virtual boost::shared_ptr createItem(const std::string & itemTag, const std::map & itemProperties) const; + +protected: + + XdmfItemFactory(); + +private: + + XdmfItemFactory(const XdmfItemFactory & itemFactory); // Not implemented. + void operator=(const XdmfItemFactory & itemFactory); // Not implemented. + +}; + +#endif /* XDMFITEMFACTORY_HPP_ */ diff --git a/XdmfObject.hpp b/XdmfObject.hpp index a706c0bd1b70ad59d2f38b79d56d622ab800a884..72ff83fe8af5a51aa3bdecf1a76c050c87ed9a64 100644 --- a/XdmfObject.hpp +++ b/XdmfObject.hpp @@ -27,6 +27,11 @@ protected: XdmfObject(); +private: + + XdmfObject(const XdmfObject & object); // Not implemented. + void operator=(const XdmfObject & object); // Not implemented. + }; #endif /* XDMFOBJECT_HPP_ */ diff --git a/XdmfReader.cpp b/XdmfReader.cpp index 76871aca7fd48200cdb4cb11fb558a1b3fa42f1c..e243d35fc8fa9e5895d2fbad71089c689b746005 100644 --- a/XdmfReader.cpp +++ b/XdmfReader.cpp @@ -1,143 +1,17 @@ // Kenneth Leiter // Xdmf Smart Pointer Test -#include "XdmfArray.hpp" -#include "XdmfAttribute.hpp" -#include "XdmfDomain.hpp" -#include "XdmfGeometry.hpp" -#include "XdmfGrid.hpp" -#include "XdmfGridCollection.hpp" -#include "XdmfSet.hpp" -#include "XdmfTopology.hpp" - -#include +#include "XdmfItemFactory.hpp" #include "XdmfReader.hpp" -/** - * PIMPL - */ -class XdmfReader::XdmfReaderImpl { - -public: - - XdmfReaderImpl() - { - }; - - ~XdmfReaderImpl() - { - }; - - boost::shared_ptr constructItem(const std::string & itemTag, const std::map & itemProperties, std::vector > & childItems) const - { - boost::shared_ptr newItem; - if(itemTag.compare(XdmfArray::ItemTag) == 0) - { - newItem = XdmfArray::New(); - } - else if(itemTag.compare(XdmfAttribute::ItemTag) == 0) - { - newItem = XdmfAttribute::New(); - } - else if(itemTag.compare(XdmfDomain::ItemTag) == 0) - { - newItem = XdmfDomain::New(); - } - else if(itemTag.compare(XdmfGeometry::ItemTag) == 0) - { - newItem = XdmfGeometry::New(); - } - else if(itemTag.compare(XdmfGrid::ItemTag) == 0) - { - std::map::const_iterator gridType = itemProperties.find("GridType"); - if(gridType->second.compare("Collection") == 0) - { - newItem = XdmfGridCollection::New(); - } - else - { - newItem = XdmfGrid::New(); - } - } - else if(itemTag.compare(XdmfSet::ItemTag) == 0) - { - newItem = XdmfSet::New(); - } - else if(itemTag.compare(XdmfTopology::ItemTag) == 0) - { - newItem = XdmfTopology::New(); - } - else - { - assert(false); - } - newItem->populateItem(itemProperties, childItems); - return newItem; - } - - std::vector > read(xmlNodePtr currNode) const - { - std::vector > myItems; - - while(currNode != NULL) - { - if(currNode->type == XML_ELEMENT_NODE) - { - std::map itemProperties; - std::cout << currNode->name << std::endl; - if(currNode->children != NULL) - { - itemProperties["Content"] = (const char *)currNode->children->content; - } - else - { - itemProperties["Content"] = ""; - } - xmlAttrPtr currAttribute = currNode->properties; - while(currAttribute != NULL) - { - itemProperties[(const char *)currAttribute->name] = (const char *)currAttribute->children->content; - currAttribute = currAttribute->next; - } - std::vector > childItems = this->read(currNode->children); - myItems.push_back(this->constructItem((const char *)currNode->name, itemProperties, childItems)); - } - currNode = currNode->next; - } - return myItems; - } -}; - XdmfReader::XdmfReader() : - mImpl(new XdmfReaderImpl()) + XdmfCoreReader(XdmfItemFactory::New()) { std::cout << "Created XdmfReader " << this << std::endl; } XdmfReader::~XdmfReader() { - delete mImpl; std::cout << "Deleted XdmfReader " << this << std::endl; } -boost::shared_ptr XdmfReader::read(const std::string & filePath) const -{ - xmlDocPtr document; - xmlNodePtr currNode; - - document = xmlReadFile(filePath.c_str(), NULL, 0); - if(document == NULL) - { - assert(false); - } - currNode = xmlDocGetRootElement(document); - - std::vector > toReturn = mImpl->read(currNode->children); - - xmlFreeDoc(document); - xmlCleanupParser(); - - return toReturn[0]; -} - - diff --git a/XdmfReader.hpp b/XdmfReader.hpp index 8594e58531ef9dff9f5652513abf203be30227cf..b0141f9f51edec5a0332bdd9b39d3f47594c19c3 100644 --- a/XdmfReader.hpp +++ b/XdmfReader.hpp @@ -1,11 +1,8 @@ #ifndef XDMFREADER_HPP_ #define XDMFREADER_HPP_ -// Forward Declarations -class XdmfDomain; - // Includes -#include "XdmfObject.hpp" +#include "XdmfCoreReader.hpp" /** * @brief Reads an Xdmf file stored on disk into memory. @@ -13,30 +10,21 @@ class XdmfDomain; * Reads an Xdmf file stored on disk into an Xdmf structure in memory. All light data is parsed in order to create appropriate * Xdmf objects. Heavy data controllers are created and attached to XdmfArrays but no heavy data is read into memory. */ -class XdmfReader : public XdmfObject { +class XdmfReader : public XdmfCoreReader { public: XdmfNewMacro(XdmfReader); virtual ~XdmfReader(); - boost::shared_ptr read(const std::string & fileName) const; - protected: XdmfReader(); private: - /** - * PIMPL - */ - class XdmfReaderImpl; - XdmfReader(const XdmfReader & reader); // Not implemented. void operator=(const XdmfReader & reader); // Not implemented. - - XdmfReaderImpl * mImpl; }; #endif /* XDMFREADER_HPP_ */ diff --git a/tests/Cxx/CMakeLists.txt b/tests/Cxx/CMakeLists.txt index 511ec683f2fe8e807beca7be3a9018e626f87467..c6862c40e1511e2bcd86cfc7d2e250f5cb06364b 100644 --- a/tests/Cxx/CMakeLists.txt +++ b/tests/Cxx/CMakeLists.txt @@ -1,12 +1,15 @@ -set(XdmfCxxTests +set(XdmfCoreCxxTests TestXdmfArray TestXdmfArrayWriteRead - TestXdmfAttribute TestXdmfDataItem + TestXdmfHDF5Writer +) + +set(XdmfCxxTests + TestXdmfAttribute TestXdmfGeometry TestXdmfGrid TestXdmfGridCollection - TestXdmfHDF5Writer TestXdmfReader TestXdmfSet TestXdmfTopology @@ -15,8 +18,14 @@ set(XdmfCxxTests TestXdmfWriterHDF5ThenXML ) +foreach(test ${XdmfCoreCxxTests}) + add_executable(${test} ${test}) + target_link_libraries(${test} XdmfCore) + add_test(${test} ${test}) +endforeach(test ${XdmfCoreCxxTests}) + foreach(test ${XdmfCxxTests}) add_executable(${test} ${test}) target_link_libraries(${test} Xdmf) add_test(${test} ${test}) -endforeach(test XdmfCxxTests) +endforeach(test ${XdmfCxxTests})