Commit fcfd3891 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Split Xdmf into XdmfCore and Xdmf libraries in anticipation of NetDMF...

ENH: Split Xdmf into XdmfCore and Xdmf libraries in anticipation of NetDMF development.  Create a couple abstract base classes
in order to support generic reading from disk.
parent e6f105ce
...@@ -32,35 +32,43 @@ if(XDMF_WRAP_PYTHON) ...@@ -32,35 +32,43 @@ if(XDMF_WRAP_PYTHON)
swig_link_libraries(Xdmf Xdmf ${PYTHON_LIBRARIES}) swig_link_libraries(Xdmf Xdmf ${PYTHON_LIBRARIES})
endif(XDMF_WRAP_PYTHON) endif(XDMF_WRAP_PYTHON)
set(XdmfSources set(XdmfCoreSources
XdmfArray XdmfArray
XdmfArrayType XdmfArrayType
XdmfCoreItemFactory
XdmfCoreReader
XdmfDataItem
XdmfHDF5Controller
XdmfHDF5Writer
XdmfItem
XdmfItemProperty
XdmfObject
XdmfVisitor
XdmfWriter
)
set(XdmfSources
XdmfAttribute XdmfAttribute
XdmfAttributeCenter XdmfAttributeCenter
XdmfAttributeType XdmfAttributeType
XdmfDataItem
XdmfDomain XdmfDomain
XdmfGeometry XdmfGeometry
XdmfGeometryType XdmfGeometryType
XdmfGrid XdmfGrid
XdmfGridCollection XdmfGridCollection
XdmfGridCollectionType XdmfGridCollectionType
XdmfHDF5Controller XdmfItemFactory
XdmfHDF5Writer
XdmfItem
XdmfItemProperty
XdmfObject
XdmfReader XdmfReader
XdmfSet XdmfSet
XdmfSetType XdmfSetType
XdmfTopology XdmfTopology
XdmfTopologyType XdmfTopologyType
XdmfVisitor
XdmfWriter
) )
add_library(XdmfCore ${XdmfCoreSources})
target_link_libraries(XdmfCore ${HDF5_LIBRARIES} ${LIBXML2_LIBRARIES})
add_library(Xdmf ${XdmfSources}) add_library(Xdmf ${XdmfSources})
target_link_libraries(Xdmf ${HDF5_LIBRARIES} ${LIBXML2_LIBRARIES}) target_link_libraries(Xdmf XdmfCore)
option(XDMF_BUILD_DOCUMENTATION OFF) option(XDMF_BUILD_DOCUMENTATION OFF)
if(XDMF_BUILD_DOCUMENTATION) if(XDMF_BUILD_DOCUMENTATION)
......
#include "XdmfCoreItemFactory.hpp"
XdmfCoreItemFactory::XdmfCoreItemFactory()
{
}
XdmfCoreItemFactory::~XdmfCoreItemFactory()
{
}
#ifndef XDMFCOREITEMFACTORY_HPP_
#define XDMFCOREITEMFACTORY_HPP_
// Forward Declarations
class XdmfItem;
// Includes
#include <map>
#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<XdmfItem> createItem(const std::string & itemTag, const std::map<std::string, std::string> & itemProperties) const = 0;
protected:
XdmfCoreItemFactory();
private:
XdmfCoreItemFactory(const XdmfCoreItemFactory & itemFactory); // Not implemented.
void operator=(const XdmfCoreItemFactory & itemFactory); // Not implemented.
};
#endif /* XDMFCOREITEMFACTORY_HPP_ */
// Kenneth Leiter
// Xdmf Smart Pointer Test
#include <libxml/xmlreader.h>
#include "XdmfCoreItemFactory.hpp"
#include "XdmfCoreReader.hpp"
#include "XdmfItem.hpp"
/**
* PIMPL
*/
class XdmfCoreReader::XdmfCoreReaderImpl {
public:
XdmfCoreReaderImpl(const boost::shared_ptr<XdmfCoreItemFactory> itemFactory) :
mItemFactory(itemFactory)
{
};
~XdmfCoreReaderImpl()
{
};
std::vector<boost::shared_ptr<XdmfItem> > read(xmlNodePtr currNode) const
{
std::vector<boost::shared_ptr<XdmfItem> > myItems;
while(currNode != NULL)
{
if(currNode->type == XML_ELEMENT_NODE)
{
std::map<std::string, std::string> 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<boost::shared_ptr<XdmfItem> > childItems = this->read(currNode->children);
boost::shared_ptr<XdmfItem> 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<XdmfCoreItemFactory> mItemFactory;
};
XdmfCoreReader::XdmfCoreReader(const boost::shared_ptr<XdmfCoreItemFactory> 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<XdmfItem> 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<boost::shared_ptr<XdmfItem> > toReturn = mImpl->read(currNode->children);
xmlFreeDoc(document);
xmlCleanupParser();
return toReturn[0];
}
#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<XdmfItem> read(const std::string & fileName) const;
protected:
XdmfCoreReader(const boost::shared_ptr<XdmfCoreItemFactory> 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_ */
/**
* 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_ #ifndef XDMFITEM_HPP_
#define XDMFITEM_HPP_ #define XDMFITEM_HPP_
...@@ -32,7 +24,7 @@ public: ...@@ -32,7 +24,7 @@ public:
virtual ~XdmfItem(); virtual ~XdmfItem();
LOKI_DEFINE_VISITABLE_BASE() LOKI_DEFINE_VISITABLE_BASE()
friend class XdmfReader; friend class XdmfCoreReader;
/** /**
* Get the tag for this XdmfItem. This is equivalent to tags in XML parlance. * Get the tag for this XdmfItem. This is equivalent to tags in XML parlance.
......
#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<XdmfItem> XdmfItemFactory::createItem(const std::string & itemTag, const std::map<std::string, std::string> & itemProperties) const
{
boost::shared_ptr<XdmfItem> 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<std::string, std::string>::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;
}
#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<XdmfItem> createItem(const std::string & itemTag, const std::map<std::string, std::string> & itemProperties) const;
protected:
XdmfItemFactory();
private:
XdmfItemFactory(const XdmfItemFactory & itemFactory); // Not implemented.
void operator=(const XdmfItemFactory & itemFactory); // Not implemented.
};
#endif /* XDMFITEMFACTORY_HPP_ */
...@@ -27,6 +27,11 @@ protected: ...@@ -27,6 +27,11 @@ protected:
XdmfObject(); XdmfObject();
private:
XdmfObject(const XdmfObject & object); // Not implemented.
void operator=(const XdmfObject & object); // Not implemented.
}; };
#endif /* XDMFOBJECT_HPP_ */ #endif /* XDMFOBJECT_HPP_ */
// Kenneth Leiter // Kenneth Leiter
// Xdmf Smart Pointer Test // Xdmf Smart Pointer Test
#include "XdmfArray.hpp" #include "XdmfItemFactory.hpp"
#include "XdmfAttribute.hpp"
#include "XdmfDomain.hpp"
#include "XdmfGeometry.hpp"
#include "XdmfGrid.hpp"
#include "XdmfGridCollection.hpp"
#include "XdmfSet.hpp"
#include "XdmfTopology.hpp"
#include <libxml/xmlreader.h>
#include "XdmfReader.hpp" #include "XdmfReader.hpp"
/**
* PIMPL
*/
class XdmfReader::XdmfReaderImpl {
public:
XdmfReaderImpl()
{
};
~XdmfReaderImpl()
{
};
boost::shared_ptr<XdmfItem> constructItem(const std::string & itemTag, const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems) const
{
boost::shared_ptr<XdmfItem> 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<std::string, std::string>::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<boost::shared_ptr<XdmfItem> > read(xmlNodePtr currNode) const
{
std::vector<boost::shared_ptr<XdmfItem> > myItems;
while(currNode != NULL)
{
if(currNode->type == XML_ELEMENT_NODE)
{
std::map<std::string, std::string> 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<boost::shared_ptr<XdmfItem> > childItems = this->read(currNode->children);
myItems.push_back(this->constructItem((const char *)currNode->name, itemProperties, childItems));
}
currNode = currNode->next;
}
return myItems;
}
};
XdmfReader::XdmfReader() : XdmfReader::XdmfReader() :
mImpl(new XdmfReaderImpl()) XdmfCoreReader(XdmfItemFactory::New())
{ {
std::cout << "Created XdmfReader " << this << std::endl; std::cout << "Created XdmfReader " << this << std::endl;
} }
XdmfReader::~XdmfReader() XdmfReader::~XdmfReader()
{ {
delete mImpl;
std::cout << "Deleted XdmfReader " << this << std::endl; std::cout << "Deleted XdmfReader " << this << std::endl;
} }
boost::shared_ptr<XdmfItem> 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<boost::shared_ptr<XdmfItem> > toReturn = mImpl->read(currNode->children);
xmlFreeDoc(document);
xmlCleanupParser();
return toReturn[0];
}
#ifndef XDMFREADER_HPP_ #ifndef XDMFREADER_HPP_
#define XDMFREADER_HPP_ #define XDMFREADER_HPP_
// Forward Declarations
class XdmfDomain;
// Includes // Includes
#include "XdmfObject.hpp" #include "XdmfCoreReader.hpp"
/** /**
* @brief Reads an Xdmf file stored on disk into memory. * @brief Reads an Xdmf file stored on disk into memory.
...@@ -13,30 +10,21 @@ class XdmfDomain; ...@@ -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 * 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. * 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: public:
XdmfNewMacro(XdmfReader); XdmfNewMacro(XdmfReader);
virtual ~XdmfReader(); virtual ~XdmfReader();
boost::shared_ptr<XdmfItem> read(const std::string & fileName) const;
protected: protected:
XdmfReader(); XdmfReader();
private: private:
/**
* PIMPL
*/
class XdmfReaderImpl;
XdmfReader(const XdmfReader & reader); // Not implemented. XdmfReader(const XdmfReader & reader); // Not implemented.
void operator=(const XdmfReader & reader); // Not implemented. void operator=(const XdmfReader & reader); // Not implemented.
XdmfReaderImpl * mImpl;
}; };
#endif /* XDMFREADER_HPP_ */ #endif /* XDMFREADER_HPP_ */
set(XdmfCxxTests set(XdmfCoreCxxTests