Files
geant4/source/externals/g4tools/include/toolx/hdf5/tools
T
2022-07-01 10:44:02 +02:00

1049 lines
25 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef toolx_hdf5_tools
#define toolx_hdf5_tools
#include "hdf5_h"
#include <cstdlib>
namespace toolx {
namespace hdf5 {
inline bool check_sizes(){
if(sizeof(bool)!=1) return false;
if(sizeof(char)!=1) return false;
if(sizeof(short)!=2) return false;
if(sizeof(int)!=4) return false;
if(sizeof(float)!=4) return false;
if(sizeof(double)!=8) return false;
return true;
}
inline int failure() {return -1;}
inline hid_t string_datatype(size_t aSize){
// aSize should include the trailing null char.
hid_t datatype = ::H5Tcopy(H5T_C_S1);
if(datatype<0) return failure();
if(::H5Tset_size(datatype,aSize)<0) {
::H5Tclose(datatype);
return failure();
}
if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
::H5Tclose(datatype);
return failure();
}
return datatype;
}
inline hid_t str_datatype() {
hid_t datatype = ::H5Tcopy(H5T_C_S1);
if(datatype<0) return failure();
if(::H5Tset_size(datatype,H5T_VARIABLE)<0) {
::H5Tclose(datatype);
return failure();
}
if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
::H5Tclose(datatype);
return failure();
}
return datatype;
}
inline hid_t basic_mem_type(hid_t a_file_type){
H5T_class_t mclass = H5Tget_class(a_file_type);
size_t msize = H5Tget_size(a_file_type);
if(mclass==H5T_INTEGER) {
H5T_sign_t msign = H5Tget_sign(a_file_type);
if(msize==1) {
if(msign==H5T_SGN_NONE) {
return H5Tcopy(H5T_NATIVE_UCHAR);
} else {
return H5Tcopy(H5T_NATIVE_CHAR);
}
} else if(msize==4) {
if(msign==H5T_SGN_NONE) {
return H5Tcopy(H5T_NATIVE_UINT);
} else {
return H5Tcopy(H5T_NATIVE_INT);
}
} else if(msize==8) { //for osc_file::header::fDate.
if(msign==H5T_SGN_NONE) {
return H5Tcopy(H5T_NATIVE_UINT64);
} else {
return H5Tcopy(H5T_NATIVE_INT64);
}
} else {
return failure();
}
} else if(mclass==H5T_FLOAT) {
if(msize==4) {
return H5Tcopy(H5T_NATIVE_FLOAT);
} else if(msize==8) {
return H5Tcopy(H5T_NATIVE_DOUBLE);
} else {
return failure();
}
} else if(mclass==H5T_STRING) {
return H5Tcopy(a_file_type);
}
return failure();
}
}}
#include <vector>
namespace toolx {
namespace hdf5 {
inline hid_t compound_mem_type(hid_t a_file_type){
// FIXME : In principle H5T_get_native_type should do the job but it crashes.
H5T_class_t t_class = H5Tget_class(a_file_type);
if(t_class!=H5T_COMPOUND) return failure();
size_t sz = H5Tget_size(a_file_type);
//printf("debug : compound_mem_type : sz %lu\n",sz);
hid_t mem_type = ::H5Tcreate(H5T_COMPOUND,sz);
if(mem_type<0) return failure();
//FIXME : WARNING : is order the booked order ?
int mn = H5Tget_nmembers(a_file_type);
std::vector<unsigned int> szs(mn);
//printf("debug : members : %d\n",mn);
for(int index=0;index<mn;index++) {
char* mname = H5Tget_member_name(a_file_type,index);
size_t moffset = H5Tget_member_offset(a_file_type,index);
hid_t mtype = H5Tget_member_type(a_file_type,index);
//printf("debug : members : %d (%d) : %s : begin\n",index,mn,mname);
{H5T_class_t mclass = H5Tget_class(mtype);
if( (mclass==H5T_INTEGER) ||
(mclass==H5T_STRING) ||
(mclass==H5T_FLOAT) ) {
hid_t mmem_type = basic_mem_type(mtype);
if(mmem_type<0) {
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
if(H5Tinsert(mem_type,mname,moffset,mmem_type)<0) {
::H5Tclose(mmem_type);
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
::H5Tclose(mmem_type);
} else if(mclass==H5T_ARRAY) {
int dimn = ::H5Tget_array_ndims(mtype); //Should be 1;
hsize_t* dims = new hsize_t[dimn];
int* perms = new int[dimn];
if(toolx_H5Tget_array_dims(mtype,dims,perms)<0) {
delete [] dims;
delete [] perms;
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
hid_t base_type = H5Tget_super(mtype);
if(base_type<0) {
delete [] dims;
delete [] perms;
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
hid_t mmem_type = basic_mem_type(base_type);
if(mmem_type<0) {
delete [] dims;
delete [] perms;
::H5Tclose(base_type);
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
::H5Tclose(base_type);
hid_t array_type = toolx_H5Tarray_create(mmem_type,dimn,dims,perms);
delete [] dims;
delete [] perms;
if(array_type<0) {
::H5Tclose(mmem_type);
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
::H5Tclose(mmem_type);
if(H5Tinsert(mem_type,mname,moffset,array_type)<0) {
::H5Tclose(array_type);
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
::H5Tclose(array_type);
} else if(mclass==H5T_COMPOUND) {
hid_t mmem_type = compound_mem_type(mtype);
if(mem_type<0) {
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
if(H5Tinsert(mem_type,mname,moffset,mmem_type)<0) {
::H5Tclose(mmem_type);
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}
::H5Tclose(mmem_type);
} else {
::H5Tclose(mtype);
if(mname) toolx_H5free_memory(mname);
::H5Tclose(mem_type);
return failure();
}}
::H5Tclose(mtype);
//printf("debug : compound_mem_type : %d (%d) : %s : end\n",index,mn,mname);
if(mname) toolx_H5free_memory(mname);
}
return mem_type;
}
}}
#include "atb"
#include <string>
namespace toolx {
namespace hdf5 {
inline bool read_atb(hid_t a_id,const std::string& a_name,std::string& a_data,unsigned int aSize = 100){
// From H5LT.c/H5LTget_attribute_string.
if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data.clear();return false;}
char* b = new char[aSize];
if(H5LT_get_attribute_disk(a_id,a_name.c_str(),b)<0) {
delete [] b;
a_data.clear();
return false;
}
a_data = std::string(b);
delete [] b;
return true;
}
inline bool read_atb(hid_t a_id,const std::string& a_name,unsigned int& a_data){
if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data=0;return false;}
if(H5LT_get_attribute_mem(a_id,a_name.c_str(),H5T_NATIVE_UINT,&a_data)<0) {a_data=0;return false;}
return true;
}
inline bool read_atb(hid_t a_id,const std::string& a_name,int& a_data){
if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data=0;return false;}
if(H5LT_get_attribute_mem(a_id,a_name.c_str(),H5T_NATIVE_INT,&a_data)<0) {a_data=0;return false;}
return true;
}
inline hid_t H5T_STD_U8XX() {return H5T_STD_U8LE;}
inline hid_t H5T_STD_U32XX() {return H5T_STD_U32LE;}
inline hid_t H5T_STD_U64XX() {return H5T_STD_U64LE;}
inline hid_t H5T_STD_I8XX() {return H5T_STD_I8LE;}
inline hid_t H5T_STD_I16XX() {return H5T_STD_I16LE;}
inline hid_t H5T_STD_I32XX() {return H5T_STD_I32LE;}
inline hid_t H5T_STD_I64XX() {return H5T_STD_I64LE;}
inline hid_t H5T_IEEE_F32XX() {return H5T_IEEE_F32LE;}
inline hid_t H5T_IEEE_F64XX() {return H5T_IEEE_F64LE;}
inline bool dataset_vec_size(hid_t a_loc,const std::string& a_name,hsize_t& a_size) {
hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
if(dataset<0) {
a_size = 0;
return false; // data set not found.
}
hid_t file_space = H5Dget_space(dataset);
if(file_space<0) {
::H5Dclose(dataset);
a_size = 0;
return false;
}
int dimn = H5Sget_simple_extent_ndims(file_space);
if(dimn<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_size = 0;
return false;
}
if(dimn!=1) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_size = 0;
return false;
}
//printf("debug : read dimn %d\n",dimn);
hsize_t dims[1];
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_size = 0;
return false;
}}
::H5Sclose(file_space);
::H5Dclose(dataset);
a_size = dims[0];
return true;
}
inline bool write_atb(hid_t a_id,const std::string& a_name,const std::string& a_data){
// From H5LT.c/H5LTset_attribute_string.
int has_attr = H5LT_find_attribute(a_id,a_name.c_str());
if(has_attr==1) {
if(H5Adelete(a_id,a_name.c_str())<0) return false;
}
hid_t datatype = string_datatype(a_data.size()+1);
if(datatype<0) return false;
hid_t scalar = ::H5Screate(H5S_SCALAR);
if(scalar<0) {
::H5Tclose(datatype);
return false;
}
hid_t aid = toolx_H5Acreate(a_id,a_name.c_str(),datatype,scalar,H5P_DEFAULT);
if(aid<0) {
::H5Sclose(scalar);
::H5Tclose(datatype);
return false;
}
if(H5Awrite(aid,datatype,a_data.c_str())<0) {
::H5Aclose(aid);
::H5Sclose(scalar);
::H5Tclose(datatype);
return false;
}
::H5Aclose(aid);
::H5Sclose(scalar);
::H5Tclose(datatype);
return true;
}
inline bool write_bool(hid_t a_loc,const std::string& a_name,bool a_data) {
hid_t scalar = ::H5Screate(H5S_SCALAR);
if(scalar<0) return false;
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
if(compact<0) {
::H5Sclose(scalar);
return false;
}
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
return false;
}
hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),H5T_STD_U8XX(),scalar,compact);
if(dataset<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
return false;
}
unsigned char data = a_data?1:0;
if(::H5Dwrite(dataset,H5T_NATIVE_UCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&data)<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
::H5Dclose(dataset);
return false;
}
::H5Pclose(compact);
::H5Sclose(scalar);
::H5Dclose(dataset);
return true;
}
inline bool write_string(hid_t a_loc,const std::string& a_name,const std::string& a_string) {
hid_t scalar = ::H5Screate(H5S_SCALAR);
if(scalar<0) return false;
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
if(compact<0) {
::H5Sclose(scalar);
return false;
}
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
return false;
}
// From H5LTmakge_dataset_string.
hid_t file_type = string_datatype(a_string.size()+1);
if(file_type<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
return false;
}
hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,scalar,compact);
if(dataset<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
::H5Tclose(file_type);
return false;
}
hid_t mem_type = file_type;
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_string.c_str())<0) {
::H5Pclose(compact);
::H5Sclose(scalar);
::H5Dclose(dataset);
::H5Tclose(file_type);
return false;
}
::H5Pclose(compact);
::H5Sclose(scalar);
::H5Dclose(dataset);
::H5Tclose(file_type);
return true;
}
inline bool write_string_dataset(hid_t a_loc,const std::string& a_name,
unsigned int a_chunked,unsigned int a_compress,
const std::string& a_string) {
hid_t cpt = -1;
if(a_compress || a_chunked) {
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
if(cpt<0) return false;
if(a_chunked) {
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
::H5Pclose(cpt);
return false;
}
hsize_t cdims[1];
cdims[0] = a_chunked;
if(H5Pset_chunk(cpt,1,cdims)<0) {
::H5Pclose(cpt);
return false;
}
} else {
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
::H5Pclose(cpt);
return false;
}
}
if(a_compress) {
if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
::H5Pclose(cpt);
return false;
}
}
} else {
cpt = H5P_DEFAULT;
}
hid_t file_type = str_datatype(); //first input => H5T_VARIABLE.
if(file_type<0) {
if(cpt>=0) ::H5Pclose(cpt);
return false;
}
hid_t file_space = -1;
{hsize_t dims[1];
dims[0] = 1;
if(a_chunked) {
hsize_t mx_dims[1];
mx_dims[0] = H5S_UNLIMITED; //extendable.
file_space = ::H5Screate_simple(1,dims,mx_dims);
} else {
file_space = ::H5Screate_simple(1,dims,NULL);
}
if(file_space<0) {if(cpt>=0) ::H5Pclose(cpt);::H5Tclose(file_type);return false;}}
hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,file_space,cpt);
if(cpt>=0) ::H5Pclose(cpt);
::H5Sclose(file_space);
if(dataset<0) {
::H5Tclose(file_type);
return false;
}
hid_t mem_type = file_type;
const char* wdata[1];
wdata[0] = a_string.c_str();
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata)<0) {
::H5Dclose(dataset);
::H5Tclose(file_type);
return false;
}
::H5Tclose(file_type);
::H5Dclose(dataset);
return true;
}
inline bool write_string_dataset(hid_t a_loc,const std::string& a_name,
const std::string& a_string,
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
return hdf5::write_string_dataset(a_loc,a_name,a_chunked,a_compress,a_string);
}
inline bool write_append_string_dataset(hid_t a_dataset,const std::string& a_string) {
hsize_t old_size = 0;
{hid_t dataspace = H5Dget_space(a_dataset);
if(dataspace<0) return false;
hsize_t dims[1];
if(H5Sget_simple_extent_dims(dataspace,dims,NULL)<0) {
::H5Sclose(dataspace);
return false;
}
old_size = dims[0];
::H5Sclose(dataspace);}
{hsize_t exts[1];
exts[0] = old_size+1;
// if(H5Dextend(dataset,exts)<0) {
if(H5Dset_extent(a_dataset,exts)<0) return false;}
hid_t file_space = H5Dget_space(a_dataset);
if(file_space<0) return false;
{hsize_t offset[1];
offset[0] = old_size;
hsize_t count[1];
count[0] = 1;
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
::H5Sclose(file_space);
return false;
}}
hsize_t dims[1];
dims[0] = 1;
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
if(mem_space<0) {
::H5Sclose(file_space);
return false;
}
hid_t mem_type = str_datatype();
if(mem_type<0) {
::H5Sclose(mem_space);
::H5Sclose(file_space);
return false;
}
const char* wdata[1];
wdata[0] = a_string.c_str();
if(H5Dwrite(a_dataset,mem_type,mem_space,file_space,H5P_DEFAULT,wdata)<0) {
::H5Tclose(mem_type);
::H5Sclose(mem_space);
::H5Sclose(file_space);
return false;
}
::H5Tclose(mem_type);
::H5Sclose(mem_space);
::H5Sclose(file_space);
return true;
}
}}
#include <tools/buf2lines>
namespace toolx {
namespace hdf5 {
inline bool write_array_string(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_array) {
hid_t scalar = ::H5Screate(H5S_SCALAR);
if(scalar<0) return false;
// From H5LTmake_dataset_string.
size_t sz;
char* buffer;
if(!tools::strings2buf(a_array,sz,buffer)) {
::H5Sclose(scalar);
return false;
}
hid_t file_type = string_datatype(sz);
if(file_type<0) {
delete [] buffer;
::H5Sclose(scalar);
return false;
}
hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,scalar,H5P_DEFAULT);
if(dataset<0) {
delete [] buffer;
::H5Tclose(file_type);
::H5Sclose(scalar);
return false;
}
hid_t mem_type = file_type;
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer)<0) {
delete [] buffer;
::H5Dclose(dataset);
::H5Tclose(file_type);
::H5Sclose(scalar);
return false;
}
delete [] buffer;
::H5Dclose(dataset);
::H5Tclose(file_type);
::H5Sclose(scalar);
return true;
}
inline bool write_object(hid_t a_loc,const std::string& a_name,hid_t a_file_type,char* a_data) {
unsigned int chunked = 0;
unsigned int compress = 0;
hid_t cpt = -1;
if(compress || chunked) {
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
if(cpt<0) return false;
if(chunked) {
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
::H5Pclose(cpt);
return false;
}
hsize_t cdims[1];
cdims[0] = chunked;
if(H5Pset_chunk(cpt,1,cdims)<0) {
::H5Pclose(cpt);
return false;
}
} else {
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
::H5Pclose(cpt);
return false;
}
}
if(compress) {
if(H5Pset_deflate(cpt,compress>9?9:compress)<0) {
::H5Pclose(cpt);
return false;
}
}
} else {
cpt = H5P_DEFAULT;
}
hsize_t dims[1];
dims[0] = 1;
hid_t simple = ::H5Screate_simple(1,dims,NULL);
if(simple<0) {
if(cpt>=0) ::H5Pclose(cpt);
return false;
}
hid_t mem_type = compound_mem_type(a_file_type);
if(mem_type<0) {
::H5Sclose(simple);
if(cpt>=0) ::H5Pclose(cpt);
return false;
}
hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),a_file_type,simple,cpt);
if(dataset<0) {
::H5Tclose(mem_type);
::H5Sclose(simple);
if(cpt>=0) ::H5Pclose(cpt);
return false;
}
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_data)<0) {
::H5Dclose(dataset);
::H5Tclose(mem_type);
::H5Sclose(simple);
if(cpt>=0) ::H5Pclose(cpt);
return false;
}
::H5Dclose(dataset);
::H5Tclose(mem_type);
::H5Sclose(simple);
if(cpt>=0) ::H5Pclose(cpt);
return true;
}
inline bool read_string(hid_t a_loc,const std::string& a_name,std::string& a_string) {
// From H5LTread_dataset_string.
hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
if(dataset<0) {
a_string.clear();
return false; // data set not found.
}
hid_t file_type = H5Dget_type(dataset);
if(file_type<0) {
::H5Dclose(dataset);
a_string.clear();
return false;
}
H5T_class_t t_class = H5Tget_class(file_type);
if(t_class!=H5T_STRING) {
::H5Tclose(file_type);
::H5Dclose(dataset);
a_string.clear();
return false;
}
size_t sz = H5Tget_size(file_type);
::H5Tclose(file_type);
if(!sz) {
::H5Dclose(dataset);
a_string.clear();
return false;
}
// We could have use file_type since, for string,
// file type is the same than memory type.
hid_t mem_type = string_datatype(sz);
if(mem_type<0) {
::H5Dclose(dataset);
a_string.clear();
return false;
}
char* buff = new char[sz];
herr_t stat = H5Dread(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buff);
::H5Tclose(mem_type);
::H5Dclose(dataset);
if(stat<0) {
delete [] buff;
a_string.clear();
return false;
}
size_t len = sz-1;
a_string.resize(len,0);
for(size_t index=0;index<len;index++) a_string[index] = buff[index];
delete [] buff;
return true;
}
inline bool read_sub_string(hid_t a_loc,const std::string& a_name,unsigned int a_offset,std::string& a_string) {
hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
if(dataset<0) {
a_string.clear();
return false; // data set not found.
}
hid_t file_space = H5Dget_space(dataset);
if(file_space<0) {
::H5Dclose(dataset);
a_string.clear();
return false;
}
{int dimn = H5Sget_simple_extent_ndims(file_space);
if(dimn<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
if(dimn!=1) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}}
hsize_t dims[1];
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}}
{unsigned int sz = (unsigned int)dims[0];
if(!sz) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false; //Is it ok ?
}
// abcdef
// 012345
int remain = sz-a_offset;
if(remain<=0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}}
{hsize_t offset[1];
offset[0] = a_offset;
hsize_t count[1];
count[0] = 1;
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}}
dims[0] = 1;
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
if(mem_space<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
hid_t file_type = H5Dget_type(dataset);
if(file_type<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
H5T_class_t t_class = H5Tget_class(file_type);
if(t_class!=H5T_STRING) {
::H5Tclose(file_type);
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
//size_t sz = H5Tget_size(file_type); //it gives the largest string size in the dataset.
//if(!sz) {
// ::H5Tclose(file_type);
// ::H5Sclose(file_space);
// ::H5Dclose(dataset);
// a_string.clear();
// return false;
//}
::H5Tclose(file_type);
hid_t mem_type = str_datatype();
if(mem_type<0) {
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
char* rdata[1];
herr_t stat = H5Dread(dataset,mem_type,mem_space,file_space,H5P_DEFAULT,rdata);
if(stat<0) {
::H5Dvlen_reclaim(mem_type,mem_space, H5P_DEFAULT,rdata);
::H5Tclose(mem_type);
::H5Sclose(mem_space);
::H5Sclose(file_space);
::H5Dclose(dataset);
a_string.clear();
return false;
}
char* buff = rdata[0];
size_t len = ::strlen(buff);
a_string.resize(len,0);
for(size_t index=0;index<len;index++) a_string[index] = buff[index];
::H5Dvlen_reclaim(mem_type,mem_space, H5P_DEFAULT,rdata);
::H5Tclose(mem_type);
::H5Sclose(mem_space);
::H5Sclose(file_space);
::H5Dclose(dataset);
return true;
}
inline bool read_object(hid_t a_loc,const std::string& a_name,size_t& a_size,char*& a_data) {
hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
if(dataset<0) {
a_size = 0;
a_data = 0;
return false;
}
hid_t file_type = H5Dget_type(dataset);
if(file_type<0) {
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
H5T_class_t t_class = H5Tget_class(file_type);
if(t_class!=H5T_COMPOUND) {
::H5Tclose(file_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
size_t sz = H5Tget_size(file_type);
if(!sz) {
::H5Tclose(file_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
hid_t mem_type = compound_mem_type(file_type);
if(mem_type<0) {
::H5Tclose(file_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
::H5Tclose(file_type);
hid_t dataspace = H5Dget_space(dataset);
if(dataspace<0) {
::H5Tclose(mem_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
hid_t scalar = ::H5Screate(H5S_SCALAR);
if(scalar<0) {
::H5Sclose(dataspace);
::H5Tclose(mem_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
char* buffer = new char[sz];
if(H5Dread(dataset,mem_type,scalar,dataspace,H5P_DEFAULT,buffer)<0) {
delete [] buffer;
::H5Sclose(scalar);
::H5Sclose(dataspace);
::H5Tclose(mem_type);
::H5Dclose(dataset);
a_size = 0;
a_data = 0;
return false;
}
::H5Sclose(scalar);
::H5Sclose(dataspace);
::H5Tclose(mem_type);
::H5Dclose(dataset);
a_size = sz;
a_data = buffer;
return true;
}
inline bool read_array_string(hid_t a_loc,const std::string& a_name,std::vector<std::string>& a_array) {
a_array.clear();
hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
if(dataset<0) return false;
hid_t file_type = H5Dget_type(dataset);
if(file_type<0) {
::H5Dclose(dataset);
return false;
}
H5T_class_t t_class = H5Tget_class(file_type);
if(t_class!=H5T_STRING) {
::H5Tclose(file_type);
::H5Dclose(dataset);
return false;
}
size_t sz = H5Tget_size(file_type);
::H5Tclose(file_type);
if(!sz) {
::H5Dclose(dataset);
return false;
}
// We could have use file_type since, for string,
// file type is the same than memory type.
hid_t mem_type = string_datatype(sz);
if(mem_type<0) {
::H5Dclose(dataset);
return false;
}
char* buffer = new char[sz];
herr_t stat = H5Dread(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
::H5Tclose(mem_type);
::H5Dclose(dataset);
if(stat<0) {
delete [] buffer;
return false;
}
if(!tools::buf2strings(sz,buffer,a_array)) {
delete [] buffer;
return false;
}
delete [] buffer;
return true;
}
}}
#endif