22 #ifndef _HDF5SERIE_STRUCTSERIE_H_
23 #define _HDF5SERIE_STRUCTSERIE_H_
25 #include <fmatvec/atom.h>
29 #include <hdf5serie/simpleattribute.h>
66 DataSpace memDataSpace;
69 std::vector<int> structOffset;
77 #ifdef PARSED_BY_DOXYGEN
100 void registerMember(
const S& s,
const CTYPE& e,
const std::string name);
108 void registerMember(
const S& s,
const std::vector<CTYPE>& e,
unsigned int N,
const std::string name);
111 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
112 void registerMember(const S& s, const CTYPE& e, const std::string name);
113 # include "hdf5serie/knowntypes.def"
114 # undef FOREACHKNOWNTYPE
116 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
117 void registerMember(const S& s, const std::vector<CTYPE>& e, unsigned int N, const std::string name);
118 # include "hdf5serie/knowntypes.def"
119 # undef FOREACHKNOWNTYPE
131 void create(
const CommonFG& parent,
const std::string& name,
int compression=FileSerie::getDefaultCompression(),
int chunkSize=FileSerie::getDefaultChunkSize());
140 void open(
const CommonFG& parent,
const std::string& name);
159 void append(
const S& data);
180 void extend(
const hsize_t* size);
188 hsize_t memDims[]={1};
189 memDataSpace=DataSpace(1, memDims);
192 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
194 void StructSerie<S>::registerMember(const S& s, const CTYPE& e, const std::string name) { \
196 if(!firstCall) size=memDataType.getSize(); else size=0; \
197 CompType oldMemDataType(memDataType); \
198 memDataType=CompType(size+toH5Type(e).getSize()); \
199 for(int i=0; i<(firstCall?0:oldMemDataType.getNmembers()); i++) \
200 memDataType.insertMember(oldMemDataType.getMemberName(i), oldMemDataType.getMemberOffset(i), oldMemDataType.getMemberDataType(i)); \
201 memDataType.insertMember(name, size, toH5Type(e)); \
202 structOffset.push_back((char*)&e-(char*)&s); \
205 # include "hdf5serie/knowntypes.def"
206 # undef FOREACHKNOWNTYPE
208 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
210 void StructSerie<S>::registerMember(const S& s, const std::vector<CTYPE>& e, unsigned int N, const std::string name) { \
211 if(e.size()!=0 && e.size()!=N) throw Exception(getPath(), "wrong dimension"); \
213 if(!firstCall) size=memDataType.getSize(); else size=0; \
215 hsize_t dims[]={N}; \
216 CompType oldMemDataType(memDataType); \
217 memDataType=CompType(size+ArrayType(toH5Type(dummy), 1, dims).getSize()); \
218 for(int i=0; i<(firstCall?0:oldMemDataType.getNmembers()); i++) \
219 memDataType.insertMember(oldMemDataType.getMemberName(i), oldMemDataType.getMemberOffset(i), oldMemDataType.getMemberDataType(i)); \
220 memDataType.insertMember(name, size, ArrayType(toH5Type(dummy), 1, dims)); \
221 structOffset.push_back((char*)&e-(char*)&s); \
224 # include "hdf5serie/knowntypes.def"
225 # undef FOREACHKNOWNTYPE
229 if(firstCall)
throw Exception(getPath(),
"wrong call sequence");
231 hsize_t maxDims[]={H5S_UNLIMITED};
232 DataSpace fileDataSpace(1, dims, maxDims);
233 DSetCreatPropList prop;
234 hsize_t chunkDims[]={
static_cast<hsize_t
>(chunkSize)};
235 prop.setChunk(1, chunkDims);
236 if(compression>0) prop.setDeflate(compression);
237 DataSet dataSet=parent.createDataSet(name, memDataType, fileDataSpace, prop);
238 setId(dataSet.getId());
240 <<
"Created object with name = "<<name<<
", id = "<<getId()<<
" at parent with id = "<<((
Group*)&parent)->getId()<<
"."<<std::endl;
245 if(firstCall)
throw Exception(getPath(),
"wrong call sequence");
246 DataSet dataSet=parent.openDataSet(name);
247 setId(dataSet.getId());
249 DataSpace fileDataSpace=getSpace();
251 assert(fileDataSpace.getSimpleExtentNdims()==1);
253 fileDataSpace.getSimpleExtentDims(dims, maxDims);
254 assert(maxDims[0]==H5S_UNLIMITED);
256 assert(dataSet.getDataType().getClass()==H5T_COMPOUND);
257 assert((
int)structOffset.size()==getCompType().getNmembers());
258 for(
unsigned int i=0; i<structOffset.size(); i++) {
259 assert(getCompType().getMemberName(i)==memDataType.getMemberName(i));
260 assert(getCompType().getMemberOffset(i)==memDataType.getMemberOffset(i));
261 assert(getCompType().getMemberDataType(i).getClass()==memDataType.getMemberDataType(i).getClass());
264 <<
"Opened object with name = "<<name<<
", id = "<<getId()<<
" at parent with id = "<<((
Group*)&parent)->getId()<<
"."<<std::endl;
269 SimpleAttribute<std::string> desc(*
this,
"Description", description);
277 Exception::getAutoPrint(func, &client_data);
278 Exception::dontPrint();
282 ret=SimpleAttribute<std::string>::getData(*
this,
"Description");
284 catch(AttributeIException e) {
288 Exception::setAutoPrint(func, client_data);
295 DataSet::extend(dims);
297 hsize_t start[]={dims[0]-1};
299 DataSpace fileDataSpace=getSpace();
300 fileDataSpace.selectHyperslab(H5S_SELECT_SET, count, start);
302 std::vector<char> buf(memDataType.getSize());
303 std::list<std::vector<char> > charptr;
304 for(
int i=0; i<memDataType.getNmembers(); i++) {
305 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
306 if(memDataType.getMemberDataType(i)==H5TYPE) \
307 *(CTYPE*)(&buf[0]+memDataType.getMemberOffset(i))=*(CTYPE*)((char*)&data+structOffset[i]);
308 # include "knownpodtypes.def"
309 # undef FOREACHKNOWNTYPE
310 if(memDataType.getMemberDataType(i)==StrType(PredType::C_S1, H5T_VARIABLE)) {
311 charptr.push_back(std::vector<char>(((std::string*)((
char*)&data+structOffset[i]))->size()+1));
312 char* str=&(*--charptr.end())[0];
313 strcpy(str, ((std::string*)((
char*)&data+structOffset[i]))->c_str());
314 *(
char**)(&buf[0]+memDataType.getMemberOffset(i))=str;
316 if(memDataType.getMemberDataType(i).getClass()==H5T_ARRAY) {
318 memDataType.getMemberArrayType(i).getArrayDims(dims);
319 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
320 if(memDataType.getMemberDataType(i)==ArrayType(H5TYPE,1,dims)) { \
321 std::vector<CTYPE>* vec=(std::vector<CTYPE>*)((char*)&data+structOffset[i]); \
322 if(vec->size()!=dims[0]) throw Exception(getPath(), "the dimension does not match"); \
323 memcpy(&buf[0]+memDataType.getMemberOffset(i), &((*vec)[0]), dims[0]*sizeof(CTYPE)); \
325 # include "knownpodtypes.def"
326 # undef FOREACHKNOWNTYPE
327 if(memDataType.getMemberDataType(i)==ArrayType(StrType(PredType::C_S1, H5T_VARIABLE),1,dims))
328 for(
unsigned int j=0; j<dims[0]; j++) {
329 std::vector<std::string>* vec=(std::vector<std::string>*)((
char*)&data+structOffset[i]);
330 if(vec->size()!=dims[0])
throw Exception(getPath(),
"the dimension does not match");
331 charptr.push_back(std::vector<char>((*vec)[j].size()+1));
332 char* str=&(*--charptr.end())[0];
333 strcpy(str, (*vec)[j].c_str());
334 *(
char**)(&buf[0]+memDataType.getMemberOffset(i)+j*
sizeof(
char*))=str;
338 write(&buf[0], memDataType, memDataSpace, fileDataSpace);
344 DataSpace fileDataSpace=getSpace();
345 fileDataSpace.getSimpleExtentDims(dims);
352 return memDataType.getNmembers();
358 if(row<0 || row>=(
int)dims[0]) {
360 <<
"Requested struct number is out of range, returning a dummy struct."<<std::endl;
364 hsize_t start[]={
static_cast<hsize_t
>(row)};
366 DataSpace fileDataSpace=getSpace();
367 fileDataSpace.selectHyperslab(H5S_SELECT_SET, count, start);
369 std::vector<char> buf(memDataType.getSize());
370 read(&buf[0], memDataType, memDataSpace, fileDataSpace);
371 for(
int i=0; i<memDataType.getNmembers(); i++) {
372 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
373 if(memDataType.getMemberDataType(i)==H5TYPE) \
374 *(CTYPE*)((char*)&data+structOffset[i])=*(CTYPE*)(&buf[0]+memDataType.getMemberOffset(i));
375 # include "knownpodtypes.def"
376 # undef FOREACHKNOWNTYPE
377 if(memDataType.getMemberDataType(i)==StrType(PredType::C_S1, H5T_VARIABLE)) {
378 char* str=*(
char**)(&buf[0]+memDataType.getMemberOffset(i));
379 *((std::string*)((
char*)&data+structOffset[i]))=str;
382 if(memDataType.getMemberDataType(i).getClass()==H5T_ARRAY) {
384 memDataType.getMemberArrayType(i).getArrayDims(dims);
385 # define FOREACHKNOWNTYPE(CTYPE, H5TYPE) \
386 if(memDataType.getMemberDataType(i)==ArrayType(H5TYPE,1,dims)) { \
387 std::vector<CTYPE>* vec=(std::vector<CTYPE>*)((char*)&data+structOffset[i]); \
388 vec->resize(dims[0]); \
389 memcpy(&((*vec)[0]), &buf[0]+memDataType.getMemberOffset(i), dims[0]*sizeof(CTYPE)); \
391 # include "knownpodtypes.def"
392 # undef FOREACHKNOWNTYPE
393 if(memDataType.getMemberDataType(i)==ArrayType(StrType(PredType::C_S1, H5T_VARIABLE),1,dims)) {
394 std::vector<std::string>* vec=(std::vector<std::string>*)((
char*)&data+structOffset[i]);
395 vec->resize(dims[0]);
396 for(
unsigned int j=0; j<dims[0]; j++) {
397 char* str=*(
char**)(&buf[0]+memDataType.getMemberOffset(i)+j*
sizeof(
char*));
409 std::vector<std::string> ret;
410 for(
int i=0; i<memDataType.getNmembers(); i++)
411 ret.push_back(memDataType.getMemberName(i));
422 #endif // _TIMESERIE_H_
Definition: interface.h:58
std::string getDescription()
Return the description for the dataset.
Definition: structserie.h:273
unsigned int getMembers()
Returns the number of members in the struct.
Definition: structserie.h:351
void setDescription(const std::string &desc)
Sets a description for the dataset.
Definition: structserie.h:268
int getRows()
Returns the number of elements in the dataset.
Definition: structserie.h:342
std::ostream & msg(MsgType type)
S getRow(const int row)
Returns the data struct at element row.
Definition: structserie.h:356
void create(const CommonFG &parent, const std::string &name, int compression=FileSerie::getDefaultCompression(), int chunkSize=FileSerie::getDefaultChunkSize())
Creating a dataset.
Definition: structserie.h:228
void append(const S &data)
Append a data struct.
Definition: structserie.h:293
StructSerie()
A stub constructor.
Definition: structserie.h:186
std::vector< std::string > getMemberLabel()
Returns the member labels.
Definition: structserie.h:408
void open(const CommonFG &parent, const std::string &name)
Open a dataset.
Definition: structserie.h:244
Serie of structs (compount datas).
Definition: structserie.h:63