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)
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)
......
#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_
#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.
......
#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:
XdmfObject();
private:
XdmfObject(const XdmfObject & object); // Not implemented.
void operator=(const XdmfObject & object); // Not implemented.
};
#endif /* XDMFOBJECT_HPP_ */
// 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 <libxml/xmlreader.h>
#include "XdmfItemFactory.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() :
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<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_
#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<XdmfItem> 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_ */
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})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment