XdmfHDF5Writer.cpp 4.08 KB
Newer Older
1
2
3
// Kenneth Leiter
// Xdmf Smart Pointer Test

4
#include <hdf5.h>
5
6
#include <sstream>
#include "XdmfArray.hpp"
7
#include "XdmfHDF5Controller.hpp"
8
9
#include "XdmfHDF5Writer.hpp"

10
11
12
13
14
15
16
/**
 * PIMPL
 */
class XdmfHDF5Writer::XdmfHDF5WriterImpl {

public:

17
	XdmfHDF5WriterImpl(const std::string & hdf5FilePath) :
18
		mHDF5FilePath(hdf5FilePath),
19
		mLastWrittenDataSet("")
20
21
22
23
24
	{
	};
	~XdmfHDF5WriterImpl()
	{
	};
25
	std::string mHDF5FilePath;
26
	std::string mLastWrittenDataSet;
27
	static int mDataSetId;
28
29
};

30
31
int XdmfHDF5Writer::XdmfHDF5WriterImpl::mDataSetId = 0;

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class XdmfHDF5Writer::GetHDF5Type : public boost::static_visitor <hid_t> {
public:

	GetHDF5Type()
	{
	}

	hid_t getHDF5Type(const char * const) const
	{
		return H5T_NATIVE_CHAR;
	}

	hid_t getHDF5Type(const short * const) const
	{
		return H5T_NATIVE_SHORT;
	}

	hid_t getHDF5Type(const int * const) const
	{
		return H5T_NATIVE_INT;
	}

	hid_t getHDF5Type(const long * const) const
	{
		return H5T_NATIVE_LONG;
	}

	hid_t getHDF5Type(const float * const) const
	{
		return H5T_NATIVE_FLOAT;
	}

	hid_t getHDF5Type(const double * const) const
	{
		return H5T_NATIVE_DOUBLE;
	}

	hid_t getHDF5Type(const unsigned char * const) const
	{
		return H5T_NATIVE_UCHAR;
	}

	hid_t getHDF5Type(const unsigned short * const) const
	{
		return H5T_NATIVE_USHORT;
	}

	hid_t getHDF5Type(const unsigned int * const) const
	{
		return H5T_NATIVE_UINT;
	}

	template<typename T>
	hid_t operator()(const boost::shared_ptr<std::vector<T> > & array) const
	{
		return this->getHDF5Type(&(array.get()->operator[](0)));
	}

	template<typename T>
	hid_t operator()(const boost::shared_array<const T> & array) const
	{
		return this->getHDF5Type(array.get());
	}
};

97
XdmfHDF5Writer::XdmfHDF5Writer(const std::string & hdf5FilePath) :
98
	mImpl(new XdmfHDF5WriterImpl(hdf5FilePath))
99
100
101
102
103
104
{
	std::cout << "Created XdmfHDF5Writer " << this << std::endl;
}

XdmfHDF5Writer::~XdmfHDF5Writer()
{
105
	delete mImpl;
106
107
108
	std::cout << "Deleted XdmfHDF5Writer " << this << std::endl;
}

109
110
111
112
113
std::string XdmfHDF5Writer::getLastWrittenDataSet() const
{
	return mImpl->mLastWrittenDataSet;
}

114
void XdmfHDF5Writer::visit(XdmfArray & array, boost::shared_ptr<XdmfBaseVisitor> visitor)
115
{
116
	hid_t datatype = -1;
117
118
	mImpl->mLastWrittenDataSet = "";

119
	if(array.mHaveArray)
120
	{
121
		datatype = boost::apply_visitor(GetHDF5Type(), array.mArray);
122
	}
123
	else if(array.mHaveArrayPointer)
124
	{
125
		datatype = boost::apply_visitor(GetHDF5Type(), array.mArrayPointer);
126
	}
127
128
129
130
	else if(array.mHDF5Controller)
	{
		mImpl->mLastWrittenDataSet = array.mHDF5Controller->getDataSetPath();
	}
131

132
133
	if(datatype != -1)
	{
134
135
136
137
		std::stringstream dataSetName;
		dataSetName << "Data" << mImpl->mDataSetId;

		// Open a hdf5 dataset and write to it on disk.
138
139
		herr_t status;
		hsize_t size = array.getSize();
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
		hid_t hdf5Handle;

		// Save old error handler and turn off error handling for now
		H5E_auto_t old_func;
		void * old_client_data;
		H5Eget_auto(0, &old_func, &old_client_data);
		H5Eset_auto2(0, NULL, NULL);

		if(H5Fis_hdf5(mImpl->mHDF5FilePath.c_str()) > 0)
		{
			hdf5Handle = H5Fopen(mImpl->mHDF5FilePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
		}
		else
		{
			hdf5Handle = H5Fcreate(mImpl->mHDF5FilePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
		}
		hid_t dataset = H5Dopen(hdf5Handle, dataSetName.str().c_str(), H5P_DEFAULT);
		if(dataset < 0)
		{
			hid_t dataspace = H5Screate_simple(1, &size, NULL);
			dataset = H5Dcreate(hdf5Handle, dataSetName.str().c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
			status = H5Sclose(dataspace);
		}
163
164
		status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.getValuesPointer());
		status = H5Dclose(dataset);
165
		status = H5Fclose(hdf5Handle);
166

167
168
		// Restore previous error handler
		H5Eset_auto2(0, old_func, old_client_data);
169

170
171
		std::stringstream writtenDataSet;
		writtenDataSet << mImpl->mHDF5FilePath << ":" << dataSetName.str();
172

173
		mImpl->mLastWrittenDataSet = writtenDataSet.str();
174
		mImpl->mDataSetId++;
175
176
177
178

		boost::shared_ptr<XdmfHDF5Controller> newDataSetController = XdmfHDF5Controller::New(writtenDataSet.str(), array.getPrecision(),
				array.getSize(), array.getType());
		array.setHDF5Controller(newDataSetController);
179
	}
180
}