Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/toolx/hdf5/tools

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef toolx_hdf5_tools
  5 #define toolx_hdf5_tools
  6 
  7 #include "hdf5_h"
  8 
  9 #include <cstdlib>
 10 
 11 namespace toolx {
 12 namespace hdf5 {
 13 
 14 inline bool check_sizes(){
 15   if(sizeof(bool)!=1) return false;
 16   if(sizeof(char)!=1) return false;
 17   if(sizeof(short)!=2) return false;
 18   if(sizeof(int)!=4) return false;
 19   if(sizeof(float)!=4) return false;
 20   if(sizeof(double)!=8) return false;
 21   return true;
 22 }
 23 
 24 inline int failure() {return -1;}
 25 
 26 inline hid_t string_datatype(size_t aSize){
 27   // aSize should include the trailing null char.
 28   hid_t datatype = ::H5Tcopy(H5T_C_S1);
 29   if(datatype<0) return failure();
 30 
 31   if(::H5Tset_size(datatype,aSize)<0) {
 32     ::H5Tclose(datatype);
 33     return failure();
 34   }
 35 
 36   if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
 37     ::H5Tclose(datatype);
 38     return failure();
 39   }
 40 
 41   return datatype;
 42 }
 43 
 44 inline hid_t str_datatype() {
 45   hid_t datatype = ::H5Tcopy(H5T_C_S1);
 46   if(datatype<0) return failure();
 47   if(::H5Tset_size(datatype,H5T_VARIABLE)<0) {
 48     ::H5Tclose(datatype);
 49     return failure();
 50   }
 51   if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
 52     ::H5Tclose(datatype);
 53     return failure();
 54   }
 55   return datatype;
 56 }
 57 
 58 inline hid_t basic_mem_type(hid_t a_file_type){
 59   H5T_class_t mclass = H5Tget_class(a_file_type);
 60   size_t msize = H5Tget_size(a_file_type);
 61   if(mclass==H5T_INTEGER) {
 62     H5T_sign_t msign = H5Tget_sign(a_file_type);
 63     if(msize==1) {
 64       if(msign==H5T_SGN_NONE) {
 65         return H5Tcopy(H5T_NATIVE_UCHAR);
 66       } else {
 67         return H5Tcopy(H5T_NATIVE_CHAR);
 68       }
 69     } else if(msize==4) {
 70       if(msign==H5T_SGN_NONE) {
 71         return H5Tcopy(H5T_NATIVE_UINT);
 72       } else {
 73         return H5Tcopy(H5T_NATIVE_INT);
 74       }
 75     } else if(msize==8) { //for osc_file::header::fDate.
 76       if(msign==H5T_SGN_NONE) {
 77         return H5Tcopy(H5T_NATIVE_UINT64);
 78       } else {
 79         return H5Tcopy(H5T_NATIVE_INT64);
 80       }
 81     } else {
 82       return failure();
 83     }
 84   } else if(mclass==H5T_FLOAT) {
 85     if(msize==4) {
 86       return H5Tcopy(H5T_NATIVE_FLOAT);
 87     } else if(msize==8) {
 88       return H5Tcopy(H5T_NATIVE_DOUBLE);
 89     } else {
 90       return failure();
 91     }
 92   } else if(mclass==H5T_STRING) {
 93     return H5Tcopy(a_file_type);
 94   }
 95 
 96   return failure();
 97 }
 98 
 99 }}
100 
101 #include <vector>
102 
103 namespace toolx {
104 namespace hdf5 {
105 
106 inline hid_t compound_mem_type(hid_t a_file_type){
107   // FIXME : In principle H5T_get_native_type should do the job but it crashes.
108 
109   H5T_class_t t_class = H5Tget_class(a_file_type);
110   if(t_class!=H5T_COMPOUND) return failure();
111 
112   size_t sz = H5Tget_size(a_file_type);
113   //printf("debug : compound_mem_type : sz %lu\n",sz);
114 
115   hid_t mem_type = ::H5Tcreate(H5T_COMPOUND,sz);
116   if(mem_type<0) return failure();
117 
118   //FIXME : WARNING : is order the booked order ?
119 
120   int mn = H5Tget_nmembers(a_file_type);
121   std::vector<unsigned int> szs(mn);
122   //printf("debug : members : %d\n",mn);
123   for(int index=0;index<mn;index++) {
124     char* mname = H5Tget_member_name(a_file_type,index);
125     size_t moffset = H5Tget_member_offset(a_file_type,index);
126     hid_t mtype = H5Tget_member_type(a_file_type,index);
127     //printf("debug : members :   %d (%d) : %s : begin\n",index,mn,mname);
128 
129    {H5T_class_t mclass = H5Tget_class(mtype);
130     if( (mclass==H5T_INTEGER) ||
131         (mclass==H5T_STRING)  ||
132         (mclass==H5T_FLOAT)   ) {
133       hid_t mmem_type = basic_mem_type(mtype);
134       if(mmem_type<0) {
135         ::H5Tclose(mtype);
136         if(mname) toolx_H5free_memory(mname);
137         ::H5Tclose(mem_type);
138         return failure();
139       }
140       if(H5Tinsert(mem_type,mname,moffset,mmem_type)<0) {
141         ::H5Tclose(mmem_type);
142         ::H5Tclose(mtype);
143         if(mname) toolx_H5free_memory(mname);
144         ::H5Tclose(mem_type);
145         return failure();
146       }
147       ::H5Tclose(mmem_type);
148 
149     } else if(mclass==H5T_ARRAY) {
150       int dimn = ::H5Tget_array_ndims(mtype); //Should be 1;
151       hsize_t* dims = new hsize_t[dimn];
152       int* perms = new int[dimn];
153       if(toolx_H5Tget_array_dims(mtype,dims,perms)<0) {
154         delete [] dims;
155         delete [] perms;
156         ::H5Tclose(mtype);
157         if(mname) toolx_H5free_memory(mname);
158         ::H5Tclose(mem_type);
159         return failure();
160       }
161       hid_t base_type = H5Tget_super(mtype);
162       if(base_type<0) {
163         delete [] dims;
164         delete [] perms;
165         ::H5Tclose(mtype);
166         if(mname) toolx_H5free_memory(mname);
167         ::H5Tclose(mem_type);
168         return failure();
169       }
170       hid_t mmem_type = basic_mem_type(base_type);
171       if(mmem_type<0) {
172         delete [] dims;
173         delete [] perms;
174         ::H5Tclose(base_type);
175         ::H5Tclose(mtype);
176         if(mname) toolx_H5free_memory(mname);
177         ::H5Tclose(mem_type);
178         return failure();
179       }
180       ::H5Tclose(base_type);
181       hid_t array_type = toolx_H5Tarray_create(mmem_type,dimn,dims,perms);
182       delete [] dims;
183       delete [] perms;
184       if(array_type<0) {
185         ::H5Tclose(mmem_type);
186         ::H5Tclose(mtype);
187         if(mname) toolx_H5free_memory(mname);
188         ::H5Tclose(mem_type);
189         return failure();
190       }
191       ::H5Tclose(mmem_type);
192 
193       if(H5Tinsert(mem_type,mname,moffset,array_type)<0) {
194         ::H5Tclose(array_type);
195         ::H5Tclose(mtype);
196         if(mname) toolx_H5free_memory(mname);
197         ::H5Tclose(mem_type);
198         return failure();
199       }
200       ::H5Tclose(array_type);
201 
202     } else if(mclass==H5T_COMPOUND) {
203       hid_t mmem_type = compound_mem_type(mtype);
204       if(mem_type<0) {
205         ::H5Tclose(mtype);
206         if(mname) toolx_H5free_memory(mname);
207         ::H5Tclose(mem_type);
208         return failure();
209       }
210       if(H5Tinsert(mem_type,mname,moffset,mmem_type)<0) {
211         ::H5Tclose(mmem_type);
212         ::H5Tclose(mtype);
213         if(mname) toolx_H5free_memory(mname);
214         ::H5Tclose(mem_type);
215         return failure();
216       }
217       ::H5Tclose(mmem_type);
218     } else {
219       ::H5Tclose(mtype);
220       if(mname) toolx_H5free_memory(mname);
221       ::H5Tclose(mem_type);
222       return failure();
223     }}
224     ::H5Tclose(mtype);
225     //printf("debug : compound_mem_type :   %d (%d) : %s : end\n",index,mn,mname);
226     if(mname) toolx_H5free_memory(mname);
227   }
228 
229   return mem_type;
230 }
231 
232 }}
233 
234 #include "atb"
235 #include <string>
236 
237 namespace toolx {
238 namespace hdf5 {
239 
240 inline bool read_atb(hid_t a_id,const std::string& a_name,std::string& a_data,unsigned int aSize = 100){
241   // From H5LT.c/H5LTget_attribute_string.
242   if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data.clear();return false;}
243   char* b = new char[aSize];
244   if(H5LT_get_attribute_disk(a_id,a_name.c_str(),b)<0) {
245     delete [] b;
246     a_data.clear();
247     return false;
248   }
249   a_data = std::string(b);
250   delete [] b;
251   return true;
252 }
253 
254 inline bool read_atb(hid_t a_id,const std::string& a_name,unsigned int& a_data){
255   if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data=0;return false;}
256   if(H5LT_get_attribute_mem(a_id,a_name.c_str(),H5T_NATIVE_UINT,&a_data)<0) {a_data=0;return false;}
257   return true;
258 }
259 
260 inline bool read_atb(hid_t a_id,const std::string& a_name,int& a_data){
261   if(!H5LT_find_attribute(a_id,a_name.c_str())) {a_data=0;return false;}
262   if(H5LT_get_attribute_mem(a_id,a_name.c_str(),H5T_NATIVE_INT,&a_data)<0) {a_data=0;return false;}
263   return true;
264 }
265 
266 inline hid_t H5T_STD_U8XX() {return H5T_STD_U8LE;}
267 inline hid_t H5T_STD_U32XX() {return H5T_STD_U32LE;}
268 inline hid_t H5T_STD_U64XX() {return H5T_STD_U64LE;}
269 inline hid_t H5T_STD_I8XX() {return H5T_STD_I8LE;}
270 inline hid_t H5T_STD_I16XX() {return H5T_STD_I16LE;}
271 inline hid_t H5T_STD_I32XX() {return H5T_STD_I32LE;}
272 inline hid_t H5T_STD_I64XX() {return H5T_STD_I64LE;}
273 inline hid_t H5T_IEEE_F32XX() {return H5T_IEEE_F32LE;}
274 inline hid_t H5T_IEEE_F64XX() {return H5T_IEEE_F64LE;}
275 
276 inline bool dataset_vec_size(hid_t a_loc,const std::string& a_name,hsize_t& a_size) {
277   hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
278   if(dataset<0) {
279     a_size = 0;
280     return false; // data set not found.
281   }
282 
283   hid_t file_space = H5Dget_space(dataset);
284   if(file_space<0) {
285     ::H5Dclose(dataset);
286     a_size = 0;
287     return false;
288   }
289 
290   int dimn = H5Sget_simple_extent_ndims(file_space);
291   if(dimn<0) {
292     ::H5Sclose(file_space);
293     ::H5Dclose(dataset);
294     a_size = 0;
295     return false;
296   }
297   if(dimn!=1) {
298     ::H5Sclose(file_space);
299     ::H5Dclose(dataset);
300     a_size = 0;
301     return false;
302   }
303   //printf("debug : read dimn %d\n",dimn);
304 
305   hsize_t dims[1];
306  {if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
307     ::H5Sclose(file_space);
308     ::H5Dclose(dataset);
309     a_size = 0;
310     return false;
311   }}
312 
313   ::H5Sclose(file_space);
314   ::H5Dclose(dataset);
315 
316   a_size = dims[0];
317   return true;
318 }
319 
320 inline bool write_atb(hid_t a_id,const std::string& a_name,const std::string& a_data){
321   // From H5LT.c/H5LTset_attribute_string.
322   int has_attr = H5LT_find_attribute(a_id,a_name.c_str());
323   if(has_attr==1)  {
324     if(H5Adelete(a_id,a_name.c_str())<0) return false;
325   }
326 
327   hid_t datatype = string_datatype(a_data.size()+1);
328   if(datatype<0) return false;
329 
330   hid_t scalar = ::H5Screate(H5S_SCALAR);
331   if(scalar<0) {
332     ::H5Tclose(datatype);
333     return false;
334   }
335 
336   hid_t aid = toolx_H5Acreate(a_id,a_name.c_str(),datatype,scalar,H5P_DEFAULT);
337   if(aid<0) {
338     ::H5Sclose(scalar);
339     ::H5Tclose(datatype);
340     return false;
341   }
342 
343   if(H5Awrite(aid,datatype,a_data.c_str())<0) {
344     ::H5Aclose(aid);
345     ::H5Sclose(scalar);
346     ::H5Tclose(datatype);
347     return false;
348   }
349 
350   ::H5Aclose(aid);
351   ::H5Sclose(scalar);
352   ::H5Tclose(datatype);
353 
354   return true;
355 }
356 
357 inline bool write_bool(hid_t a_loc,const std::string& a_name,bool a_data) {
358   hid_t scalar = ::H5Screate(H5S_SCALAR);
359   if(scalar<0) return false;
360 
361   hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
362   if(compact<0) {
363     ::H5Sclose(scalar);
364     return false;
365   }
366   if(H5Pset_layout(compact,H5D_COMPACT)<0) {
367     ::H5Pclose(compact);
368     ::H5Sclose(scalar);
369     return false;
370   }
371 
372   hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),H5T_STD_U8XX(),scalar,compact);
373   if(dataset<0) {
374     ::H5Pclose(compact);
375     ::H5Sclose(scalar);
376     return false;
377   }
378 
379   unsigned char data = a_data?1:0;
380   if(::H5Dwrite(dataset,H5T_NATIVE_UCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&data)<0) {
381     ::H5Pclose(compact);
382     ::H5Sclose(scalar);
383     ::H5Dclose(dataset);
384     return false;
385   }
386 
387   ::H5Pclose(compact);
388   ::H5Sclose(scalar);
389   ::H5Dclose(dataset);
390   return true;
391 }
392 
393 inline bool write_string(hid_t a_loc,const std::string& a_name,const std::string& a_string) {
394   hid_t scalar = ::H5Screate(H5S_SCALAR);
395   if(scalar<0) return false;
396 
397   hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
398   if(compact<0) {
399     ::H5Sclose(scalar);
400     return false;
401   }
402 
403   if(H5Pset_layout(compact,H5D_COMPACT)<0) {
404     ::H5Pclose(compact);
405     ::H5Sclose(scalar);
406     return false;
407   }
408 
409   // From H5LTmakge_dataset_string.
410   hid_t file_type = string_datatype(a_string.size()+1);
411   if(file_type<0) {
412     ::H5Pclose(compact);
413     ::H5Sclose(scalar);
414     return false;
415   }
416 
417   hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,scalar,compact);
418   if(dataset<0) {
419     ::H5Pclose(compact);
420     ::H5Sclose(scalar);
421     ::H5Tclose(file_type);
422     return false;
423   }
424 
425   hid_t mem_type = file_type;
426   if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_string.c_str())<0) {
427     ::H5Pclose(compact);
428     ::H5Sclose(scalar);
429     ::H5Dclose(dataset);
430     ::H5Tclose(file_type);
431     return false;
432   }
433 
434   ::H5Pclose(compact);
435   ::H5Sclose(scalar);
436   ::H5Dclose(dataset);
437   ::H5Tclose(file_type);
438 
439   return true;
440 }
441 
442 inline bool write_string_dataset(hid_t a_loc,const std::string& a_name,
443                                  unsigned int a_chunked,unsigned int a_compress,
444                                  const std::string& a_string) {
445   hid_t cpt = -1;
446   if(a_compress || a_chunked) {
447     cpt = ::H5Pcreate(H5P_DATASET_CREATE);
448     if(cpt<0) return false;
449     if(a_chunked) {
450       if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
451         ::H5Pclose(cpt);
452         return false;
453       }
454       hsize_t cdims[1];
455       cdims[0] = a_chunked;
456       if(H5Pset_chunk(cpt,1,cdims)<0) {
457         ::H5Pclose(cpt);
458         return false;
459       }
460     } else {
461       if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
462         ::H5Pclose(cpt);
463         return false;
464       }
465     }
466     if(a_compress) {
467       if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
468         ::H5Pclose(cpt);
469         return false;
470       }
471     }
472   } else {
473     cpt = H5P_DEFAULT;
474   }
475 
476   hid_t file_type = str_datatype(); //first input => H5T_VARIABLE.
477   if(file_type<0) {
478     if(cpt>=0) ::H5Pclose(cpt);
479     return false;
480   }
481 
482   hid_t file_space = -1;
483  {hsize_t dims[1];
484   dims[0] = 1;
485   if(a_chunked) {
486     hsize_t mx_dims[1];
487     mx_dims[0] = H5S_UNLIMITED; //extendable.
488     file_space = ::H5Screate_simple(1,dims,mx_dims);
489   } else {
490     file_space = ::H5Screate_simple(1,dims,NULL);
491   }
492   if(file_space<0) {if(cpt>=0) ::H5Pclose(cpt);::H5Tclose(file_type);return false;}}
493 
494   hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,file_space,cpt);
495   if(cpt>=0) ::H5Pclose(cpt);
496   ::H5Sclose(file_space);
497   if(dataset<0) {
498     ::H5Tclose(file_type);
499     return false;
500   }
501 
502   hid_t mem_type = file_type;
503 
504   const char* wdata[1];
505   wdata[0] = a_string.c_str();
506 
507   if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata)<0) {
508     ::H5Dclose(dataset);
509     ::H5Tclose(file_type);
510     return false;
511   }
512 
513   ::H5Tclose(file_type);
514   ::H5Dclose(dataset);
515 
516   return true;
517 }
518 
519 inline bool write_string_dataset(hid_t a_loc,const std::string& a_name,
520                                  const std::string& a_string,
521                                  unsigned int a_chunked = 0,unsigned int a_compress = 0) {
522   return hdf5::write_string_dataset(a_loc,a_name,a_chunked,a_compress,a_string);
523 }
524 
525 inline bool write_append_string_dataset(hid_t a_dataset,const std::string& a_string) {
526   hsize_t old_size = 0;
527 
528  {hid_t dataspace = H5Dget_space(a_dataset);
529   if(dataspace<0) return false;
530   hsize_t dims[1];
531   if(H5Sget_simple_extent_dims(dataspace,dims,NULL)<0) {
532     ::H5Sclose(dataspace);
533     return false;
534   }
535   old_size = dims[0];
536   ::H5Sclose(dataspace);}
537 
538  {hsize_t exts[1];
539   exts[0] = old_size+1;
540 //  if(H5Dextend(dataset,exts)<0) {
541   if(H5Dset_extent(a_dataset,exts)<0) return false;}
542 
543   hid_t file_space = H5Dget_space(a_dataset);
544   if(file_space<0) return false;
545 
546  {hsize_t offset[1];
547   offset[0] = old_size;
548   hsize_t count[1];
549   count[0] = 1;
550   if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
551     ::H5Sclose(file_space);
552     return false;
553   }}
554 
555   hsize_t dims[1];
556   dims[0] = 1;
557   hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
558   if(mem_space<0) {
559     ::H5Sclose(file_space);
560     return false;
561   }
562 
563   hid_t mem_type = str_datatype();
564   if(mem_type<0) {
565     ::H5Sclose(mem_space);
566     ::H5Sclose(file_space);
567     return false;
568   }
569 
570   const char* wdata[1];
571   wdata[0] = a_string.c_str();
572 
573   if(H5Dwrite(a_dataset,mem_type,mem_space,file_space,H5P_DEFAULT,wdata)<0) {
574     ::H5Tclose(mem_type);
575     ::H5Sclose(mem_space);
576     ::H5Sclose(file_space);
577     return false;
578   }
579 
580   ::H5Tclose(mem_type);
581   ::H5Sclose(mem_space);
582   ::H5Sclose(file_space);
583 
584   return true;
585 }
586 
587 }}
588 
589 #include <tools/buf2lines>
590 
591 namespace toolx {
592 namespace hdf5 {
593 
594 inline bool write_array_string(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_array) {
595   hid_t scalar = ::H5Screate(H5S_SCALAR);
596   if(scalar<0) return false;
597 
598   // From H5LTmake_dataset_string.
599   size_t sz;
600   char* buffer;
601   if(!tools::strings2buf(a_array,sz,buffer)) {
602     ::H5Sclose(scalar);
603     return false;
604   }
605 
606   hid_t file_type = string_datatype(sz);
607   if(file_type<0) {
608     delete [] buffer;
609     ::H5Sclose(scalar);
610     return false;
611   }
612 
613   hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),file_type,scalar,H5P_DEFAULT);
614   if(dataset<0) {
615     delete [] buffer;
616     ::H5Tclose(file_type);
617     ::H5Sclose(scalar);
618     return false;
619   }
620 
621   hid_t mem_type = file_type;
622   if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer)<0) {
623     delete [] buffer;
624     ::H5Dclose(dataset);
625     ::H5Tclose(file_type);
626     ::H5Sclose(scalar);
627     return false;
628   }
629 
630   delete [] buffer;
631 
632   ::H5Dclose(dataset);
633   ::H5Tclose(file_type);
634   ::H5Sclose(scalar);
635   return true;
636 }
637 
638 inline bool write_object(hid_t a_loc,const std::string& a_name,hid_t a_file_type,char* a_data) {
639   unsigned int chunked = 0;
640   unsigned int compress = 0;
641 
642   hid_t cpt = -1;
643   if(compress || chunked) {
644     cpt = ::H5Pcreate(H5P_DATASET_CREATE);
645     if(cpt<0) return false;
646     if(chunked) {
647       if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
648         ::H5Pclose(cpt);
649         return false;
650       }
651       hsize_t cdims[1];
652       cdims[0] = chunked;
653       if(H5Pset_chunk(cpt,1,cdims)<0) {
654         ::H5Pclose(cpt);
655         return false;
656       }
657     } else {
658       if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
659         ::H5Pclose(cpt);
660         return false;
661       }
662     }
663     if(compress) {
664       if(H5Pset_deflate(cpt,compress>9?9:compress)<0) {
665         ::H5Pclose(cpt);
666         return false;
667       }
668     }
669   } else {
670     cpt = H5P_DEFAULT;
671   }
672 
673   hsize_t dims[1];
674   dims[0] = 1;
675   hid_t simple = ::H5Screate_simple(1,dims,NULL);
676   if(simple<0) {
677     if(cpt>=0) ::H5Pclose(cpt);
678     return false;
679   }
680 
681   hid_t mem_type = compound_mem_type(a_file_type);
682   if(mem_type<0) {
683     ::H5Sclose(simple);
684     if(cpt>=0) ::H5Pclose(cpt);
685     return false;
686   }
687 
688   hid_t dataset = toolx_H5Dcreate(a_loc,a_name.c_str(),a_file_type,simple,cpt);
689   if(dataset<0) {
690     ::H5Tclose(mem_type);
691     ::H5Sclose(simple);
692     if(cpt>=0) ::H5Pclose(cpt);
693     return false;
694   }
695 
696   if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_data)<0) {
697     ::H5Dclose(dataset);
698     ::H5Tclose(mem_type);
699     ::H5Sclose(simple);
700     if(cpt>=0) ::H5Pclose(cpt);
701     return false;
702   }
703 
704   ::H5Dclose(dataset);
705   ::H5Tclose(mem_type);
706   ::H5Sclose(simple);
707   if(cpt>=0) ::H5Pclose(cpt);
708 
709   return true;
710 }
711 
712 inline bool read_string(hid_t a_loc,const std::string& a_name,std::string& a_string) {
713   // From H5LTread_dataset_string.
714   hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
715   if(dataset<0) {
716     a_string.clear();
717     return false; // data set not found.
718   }
719 
720   hid_t file_type = H5Dget_type(dataset);
721   if(file_type<0) {
722     ::H5Dclose(dataset);
723     a_string.clear();
724     return false;
725   }
726 
727   H5T_class_t t_class = H5Tget_class(file_type);
728   if(t_class!=H5T_STRING) {
729     ::H5Tclose(file_type);
730     ::H5Dclose(dataset);
731     a_string.clear();
732     return false;
733   }
734 
735   size_t sz = H5Tget_size(file_type);
736   ::H5Tclose(file_type);
737   if(!sz) {
738     ::H5Dclose(dataset);
739     a_string.clear();
740     return false;
741   }
742 
743   // We could have use file_type since, for string,
744   // file type is the same than memory type.
745   hid_t mem_type = string_datatype(sz);
746   if(mem_type<0) {
747     ::H5Dclose(dataset);
748     a_string.clear();
749     return false;
750   }
751 
752   char* buff = new char[sz];
753   herr_t stat = H5Dread(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buff);
754   ::H5Tclose(mem_type);
755   ::H5Dclose(dataset);
756   if(stat<0) {
757     delete [] buff;
758     a_string.clear();
759     return false;
760   }
761 
762   size_t len = sz-1;
763   a_string.resize(len,0);
764   for(size_t index=0;index<len;index++) a_string[index] = buff[index];
765 
766   delete [] buff;
767 
768   return true;
769 }
770 
771 inline bool read_sub_string(hid_t a_loc,const std::string& a_name,unsigned int a_offset,std::string& a_string) {
772   hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
773   if(dataset<0) {
774     a_string.clear();
775     return false; // data set not found.
776   }
777 
778   hid_t file_space = H5Dget_space(dataset);
779   if(file_space<0) {
780     ::H5Dclose(dataset);
781     a_string.clear();
782     return false;
783   }
784 
785  {int dimn = H5Sget_simple_extent_ndims(file_space);
786   if(dimn<0) {
787     ::H5Sclose(file_space);
788     ::H5Dclose(dataset);
789     a_string.clear();
790     return false;
791   }
792   if(dimn!=1) {
793     ::H5Sclose(file_space);
794     ::H5Dclose(dataset);
795     a_string.clear();
796     return false;
797   }}
798 
799   hsize_t dims[1];
800  {if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
801     ::H5Sclose(file_space);
802     ::H5Dclose(dataset);
803     a_string.clear();
804     return false;
805   }}
806 
807  {unsigned int sz = (unsigned int)dims[0];
808   if(!sz) {
809     ::H5Sclose(file_space);
810     ::H5Dclose(dataset);
811     a_string.clear();
812     return false; //Is it ok ?
813   }
814 
815   //  abcdef
816   //  012345
817   int remain = sz-a_offset;
818   if(remain<=0) {
819     ::H5Sclose(file_space);
820     ::H5Dclose(dataset);
821     a_string.clear();
822     return false;
823   }}
824 
825  {hsize_t offset[1];
826   offset[0] = a_offset;
827   hsize_t count[1];
828   count[0] = 1;
829   if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
830     ::H5Sclose(file_space);
831     ::H5Dclose(dataset);
832     a_string.clear();
833     return false;
834   }}
835 
836   dims[0] = 1;
837   hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
838   if(mem_space<0) {
839     ::H5Sclose(file_space);
840     ::H5Dclose(dataset);
841     a_string.clear();
842     return false;
843   }
844 
845   hid_t file_type = H5Dget_type(dataset);
846   if(file_type<0) {
847     ::H5Sclose(file_space);
848     ::H5Dclose(dataset);
849     a_string.clear();
850     return false;
851   }
852 
853   H5T_class_t t_class = H5Tget_class(file_type);
854   if(t_class!=H5T_STRING) {
855     ::H5Tclose(file_type);
856     ::H5Sclose(file_space);
857     ::H5Dclose(dataset);
858     a_string.clear();
859     return false;
860   }
861 
862 //size_t sz = H5Tget_size(file_type); //it gives the largest string size in the dataset.
863 //if(!sz) {
864 //  ::H5Tclose(file_type);
865 //  ::H5Sclose(file_space);
866 //  ::H5Dclose(dataset);
867 //  a_string.clear();
868 //  return false;
869 //}
870 
871   ::H5Tclose(file_type);
872 
873   hid_t mem_type = str_datatype();
874   if(mem_type<0) {
875     ::H5Sclose(file_space);
876     ::H5Dclose(dataset);
877     a_string.clear();
878     return false;
879   }
880 
881   char* rdata[1];
882   herr_t stat = H5Dread(dataset,mem_type,mem_space,file_space,H5P_DEFAULT,rdata);
883   if(stat<0) {
884     ::H5Dvlen_reclaim(mem_type,mem_space, H5P_DEFAULT,rdata);
885     ::H5Tclose(mem_type);
886     ::H5Sclose(mem_space);
887     ::H5Sclose(file_space);
888     ::H5Dclose(dataset);
889     a_string.clear();
890     return false;
891   }
892 
893   char* buff = rdata[0];
894 
895   size_t len = ::strlen(buff);
896   a_string.resize(len,0);
897   for(size_t index=0;index<len;index++) a_string[index] = buff[index];
898 
899   ::H5Dvlen_reclaim(mem_type,mem_space, H5P_DEFAULT,rdata);
900 
901   ::H5Tclose(mem_type);
902   ::H5Sclose(mem_space);
903   ::H5Sclose(file_space);
904   ::H5Dclose(dataset);
905 
906   return true;
907 }
908 
909 inline bool read_object(hid_t a_loc,const std::string& a_name,size_t& a_size,char*& a_data) {
910   hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
911   if(dataset<0) {
912     a_size = 0;
913     a_data = 0;
914     return false;
915   }
916 
917   hid_t file_type = H5Dget_type(dataset);
918   if(file_type<0) {
919     ::H5Dclose(dataset);
920     a_size = 0;
921     a_data = 0;
922     return false;
923   }
924 
925   H5T_class_t t_class = H5Tget_class(file_type);
926   if(t_class!=H5T_COMPOUND) {
927     ::H5Tclose(file_type);
928     ::H5Dclose(dataset);
929     a_size = 0;
930     a_data = 0;
931     return false;
932   }
933 
934   size_t sz = H5Tget_size(file_type);
935   if(!sz) {
936     ::H5Tclose(file_type);
937     ::H5Dclose(dataset);
938     a_size = 0;
939     a_data = 0;
940     return false;
941   }
942 
943   hid_t mem_type = compound_mem_type(file_type);
944   if(mem_type<0) {
945     ::H5Tclose(file_type);
946     ::H5Dclose(dataset);
947     a_size = 0;
948     a_data = 0;
949     return false;
950   }
951 
952   ::H5Tclose(file_type);
953 
954   hid_t dataspace = H5Dget_space(dataset);
955   if(dataspace<0) {
956     ::H5Tclose(mem_type);
957     ::H5Dclose(dataset);
958     a_size = 0;
959     a_data = 0;
960     return false;
961   }
962 
963   hid_t scalar = ::H5Screate(H5S_SCALAR);
964   if(scalar<0) {
965     ::H5Sclose(dataspace);
966     ::H5Tclose(mem_type);
967     ::H5Dclose(dataset);
968     a_size = 0;
969     a_data = 0;
970     return false;
971   }
972 
973   char* buffer = new char[sz];
974   if(H5Dread(dataset,mem_type,scalar,dataspace,H5P_DEFAULT,buffer)<0) {
975     delete [] buffer;
976     ::H5Sclose(scalar);
977     ::H5Sclose(dataspace);
978     ::H5Tclose(mem_type);
979     ::H5Dclose(dataset);
980     a_size = 0;
981     a_data = 0;
982     return false;
983   }
984 
985   ::H5Sclose(scalar);
986   ::H5Sclose(dataspace);
987   ::H5Tclose(mem_type);
988   ::H5Dclose(dataset);
989 
990   a_size = sz;
991   a_data = buffer;
992   return true;
993 }
994 
995 inline bool read_array_string(hid_t a_loc,const std::string& a_name,std::vector<std::string>& a_array) {
996   a_array.clear();
997   hid_t dataset = toolx_H5Dopen(a_loc,a_name.c_str());
998   if(dataset<0) return false;
999 
1000   hid_t file_type = H5Dget_type(dataset);
1001   if(file_type<0) {
1002     ::H5Dclose(dataset);
1003     return false;
1004   }
1005 
1006   H5T_class_t t_class = H5Tget_class(file_type);
1007   if(t_class!=H5T_STRING) {
1008     ::H5Tclose(file_type);
1009     ::H5Dclose(dataset);
1010     return false;
1011   }
1012 
1013   size_t sz = H5Tget_size(file_type);
1014   ::H5Tclose(file_type);
1015   if(!sz) {
1016     ::H5Dclose(dataset);
1017     return false;
1018   }
1019 
1020   // We could have use file_type since, for string,
1021   // file type is the same than memory type.
1022   hid_t mem_type = string_datatype(sz);
1023   if(mem_type<0) {
1024     ::H5Dclose(dataset);
1025     return false;
1026   }
1027 
1028   char* buffer = new char[sz];
1029   herr_t stat = H5Dread(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
1030   ::H5Tclose(mem_type);
1031   ::H5Dclose(dataset);
1032   if(stat<0) {
1033     delete [] buffer;
1034     return false;
1035   }
1036 
1037   if(!tools::buf2strings(sz,buffer,a_array)) {
1038     delete [] buffer;
1039     return false;
1040   }
1041 
1042   delete [] buffer;
1043   return true;
1044 }
1045 
1046 }}
1047 
1048 #endif