SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SerializableHdf5File.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Soeren Sonnenburg
8  * Copyright (C) 2010 Berlin Institute of Technology
9  */
10 
11 #include <shogun/lib/config.h>
12 #ifdef HAVE_HDF5
13 
16 
17 #define NOT_OPEN ((hid_t) -1)
18 
19 #define STR_KEY_FILETYPE "filetype"
20 #define STR_FILETYPE_00 \
21  "_SHOGUN_SERIALIZABLE_HDF5_FILE_V_00_"
22 
23 using namespace shogun;
24 
25 CSerializableHdf5File::type_item_t::type_item_t(const char* name_)
26 {
27  rank = 0;
28  dims[0] = dims[1] = 0;
29  dspace = dtype = dset = NOT_OPEN;
30  vltype = NULL;
31  y = x = sub_y = 0;
32  sparse_ptr = NULL;
33  name = name_;
34 }
35 
36 CSerializableHdf5File::type_item_t::~type_item_t()
37 {
38  if (dset >= 0) H5Dclose(dset);
39  if (dtype >= 0) H5Tclose(dtype);
40  if (dspace >= 0) H5Sclose(dspace);
41  if (vltype != NULL) SG_FREE(vltype);
42  /* Do not delete SPARSE_PTR */
43 }
44 
45 hid_t
46 CSerializableHdf5File::sizeof_sparsetype() {
47  return H5Tget_size(TYPE_INDEX) + H5Tget_size(H5T_STD_REF_OBJ);
48 }
49 hid_t
50 CSerializableHdf5File::new_sparsetype()
51 {
52  hid_t result = H5Tcreate(H5T_COMPOUND, sizeof_sparsetype());
53 
54  if (H5Tinsert(result, STR_SPARSE_FPTR, H5Tget_size(TYPE_INDEX),
55  H5T_STD_REF_OBJ) < 0)
56  return NOT_OPEN;
57 
58  return result;
59 }
60 hobj_ref_t*
61 CSerializableHdf5File::get_ref_sparstype(void* sparse_buf) {
62  return (hobj_ref_t*)
63  ((char*) sparse_buf + H5Tget_size(TYPE_INDEX));
64 }
65 
66 hid_t
67 CSerializableHdf5File::new_sparseentrytype(EPrimitiveType ptype)
68 {
69  hid_t result = H5Tcreate(H5T_COMPOUND,
71  if (result < 0) return NOT_OPEN;
72 
73  if (H5Tinsert(result, STR_SPARSEENTRY_FINDEX,
74  HOFFSET(SGSparseVectorEntry<char>, feat_index), TYPE_INDEX)
75  < 0) return NOT_OPEN;
76  if (H5Tinsert(result, STR_SPARSEENTRY_ENTRY, TSGDataType
77  ::offset_sparseentry(ptype),
78  ptype2hdf5(ptype)) < 0) return NOT_OPEN;
79 
80  return result;
81 }
82 
83 hid_t
84 CSerializableHdf5File::ptype2hdf5(EPrimitiveType ptype)
85 {
86  switch (ptype) {
87  case PT_BOOL:
88  switch (sizeof (bool)) {
89  case 1: return H5T_NATIVE_UINT8;
90  case 2: return H5T_NATIVE_UINT16;
91  case 4: return H5T_NATIVE_UINT32;
92  case 8: return H5T_NATIVE_UINT64;
93  default: break;
94  }
95  break;
96  case PT_CHAR: return H5T_NATIVE_CHAR; break;
97  case PT_INT8: return H5T_NATIVE_INT8; break;
98  case PT_UINT8: return H5T_NATIVE_UINT8; break;
99  case PT_INT16: return H5T_NATIVE_INT16; break;
100  case PT_UINT16: return H5T_NATIVE_UINT16; break;
101  case PT_INT32: return H5T_NATIVE_INT32; break;
102  case PT_UINT32: return H5T_NATIVE_UINT32; break;
103  case PT_INT64: return H5T_NATIVE_INT64; break;
104  case PT_UINT64: return H5T_NATIVE_UINT64; break;
105  case PT_FLOAT32: return H5T_NATIVE_FLOAT; break;
106  case PT_FLOAT64: return H5T_NATIVE_DOUBLE; break;
107  case PT_FLOATMAX: return H5T_NATIVE_LDOUBLE; break;
108  case PT_COMPLEX128: return NOT_OPEN; break;
109  case PT_SGOBJECT: return NOT_OPEN; break;
110  }
111 
112  return NOT_OPEN;
113 }
114 
115 hid_t
116 CSerializableHdf5File::new_stype2hdf5(EStructType stype,
117  EPrimitiveType ptype)
118 {
119  hid_t result = ptype2hdf5(ptype);
120 
121  switch (stype) {
122  case ST_NONE: result = H5Tcopy(result); break;
123  case ST_STRING: result = H5Tvlen_create(result); break;
124  case ST_SPARSE: result = new_sparsetype(); break;
125  default: break;
126  }
127 
128  return result;
129 }
130 
131 bool
132 CSerializableHdf5File::index2string(
133  char* dest, size_t n, EContainerType ctype, index_t y, index_t x)
134 {
135  switch (ctype) {
136  case CT_NDARRAY: SG_SNOTIMPLEMENTED
137  case CT_SCALAR: return false;
138  case CT_VECTOR: case CT_SGVECTOR: snprintf(dest, n, "y%u", y); break;
139  case CT_MATRIX: case CT_SGMATRIX: snprintf(dest, n, "y%u_x%u", y, x); break;
140  default: return false;
141  }
142 
143  return true;
144 }
145 
146 bool
147 CSerializableHdf5File::isequal_stype2hdf5(EStructType stype,
148  EPrimitiveType ptype,
149  hid_t htype)
150 {
151  hid_t pbuf = ptype2hdf5(ptype), pbuf2 = NOT_OPEN;
152 
153  bool to_close = false;
154  switch (stype) {
155  case ST_NONE: break;
156  case ST_STRING:
157  to_close = true; pbuf = H5Tvlen_create(pbuf); break;
158  case ST_SPARSE:
159  to_close = true; pbuf = new_sparsetype();
160  pbuf2 = new_sparseentrytype(ptype); break;
161  }
162 
163  bool result = (H5Tequal(htype, pbuf) > 0)
164  || (pbuf2 >= 0 && H5Tequal(htype, pbuf2) > 0);
165 
166  if (pbuf2 >= 0 && H5Tclose(pbuf2) < 0) return false;
167  if (to_close && H5Tclose(pbuf) < 0) return false;
168  return result;
169 }
170 
171 bool
172 CSerializableHdf5File::dspace_select(EContainerType ctype, index_t y,
173  index_t x)
174 {
175  type_item_t* m = m_stack_type.back();
176 
177  if (H5Sselect_none(m->dspace) < 0) return false;
178 
179  hsize_t coord[2];
180  switch (ctype) {
181  case CT_NDARRAY: SG_NOTIMPLEMENTED
182  case CT_SCALAR: return false;
183  case CT_MATRIX: case CT_SGMATRIX: coord[1] = x; /* break; */
184  case CT_VECTOR: case CT_SGVECTOR: coord[0] = y; break;
185  default: return false;
186  }
187  if (H5Sselect_elements(m->dspace, H5S_SELECT_SET, 1, coord) < 0)
188  return false;
189 
190  return true;
191 }
192 
193 bool
194 CSerializableHdf5File::attr_write_scalar(
195  hid_t datatype, const char* name, const void* val)
196 {
197  hid_t dspace;
198  if ((dspace = H5Screate_simple(0, NULL, NULL)) < 0) return false;
199  hid_t dtype;
200  if ((dtype = H5Tcopy(datatype)) < 0) return false;
201  hid_t attr;
202  if ((attr = H5Acreate2(
203  m_stack_h5stream.back(), name, dtype, dspace,
204  H5P_DEFAULT, H5P_DEFAULT)) < 0) return false;
205 
206  if (H5Awrite(attr, datatype, val) < 0) return false;
207 
208  if (H5Aclose(attr) < 0) return false;
209  if (H5Tclose(dtype) < 0) return false;
210  if (H5Sclose(dspace) < 0) return false;
211 
212  return true;
213 }
214 
215 bool
216 CSerializableHdf5File::attr_write_string(
217  const char* name, const char* val)
218 {
219  hid_t dtype;
220  if ((dtype = H5Tcopy(H5T_C_S1)) < 0) return false;
221  if (H5Tset_size(dtype, strlen(val)+1) < 0) return false;
222 
223  if (!attr_write_scalar(dtype, name, val)) return false;
224 
225  if (H5Tclose(dtype) < 0) return false;
226 
227  return true;
228 }
229 
230 bool
231 CSerializableHdf5File::attr_exists(const char* name)
232 {
233  return H5Aexists(m_stack_h5stream.back(), name) > 0;
234 }
235 
236 size_t
237 CSerializableHdf5File::attr_get_size(const char* name)
238 {
239  if (!attr_exists(name)) return 0;
240 
241  hid_t attr;
242  if ((attr = H5Aopen(m_stack_h5stream.back(), name, H5P_DEFAULT))
243  < 0) return 0;
244 
245  hid_t dtype;
246  if ((dtype = H5Aget_type(attr)) < 0) return 0;
247 
248  size_t result = H5Tget_size(dtype);
249 
250  if (H5Tclose(dtype) < 0) return 0;
251  if (H5Aclose(attr) < 0) return 0;
252 
253  return result;
254 }
255 
256 bool
257 CSerializableHdf5File::attr_read_scalar(
258  hid_t datatype, const char* name, void* val)
259 {
260  if (!attr_exists(name)) return false;
261 
262  hid_t attr;
263  if ((attr = H5Aopen(m_stack_h5stream.back(), name, H5P_DEFAULT))
264  < 0) return false;
265 
266  hid_t dspace;
267  if ((dspace = H5Aget_space(attr)) < 0) return false;
268  if (H5Sget_simple_extent_type(dspace) != H5S_SCALAR) return false;
269 
270  hid_t dtype;
271  if ((dtype = H5Aget_type(attr)) < 0) return false;
272  if (H5Tequal(datatype, dtype) <= 0) return false;
273 
274  if (H5Aread(attr, datatype, val) < 0) return false;
275 
276  if (H5Tclose(dtype) < 0) return false;
277  if (H5Sclose(dspace) < 0) return false;
278  if (H5Aclose(attr) < 0) return false;
279 
280  return true;
281 }
282 
283 bool
284 CSerializableHdf5File::attr_read_string(
285  const char* name, char* val, size_t n)
286 {
287  size_t size = attr_get_size(name);
288  if (size == 0 || size > n) return false;
289 
290  hid_t dtype;
291  if ((dtype = H5Tcopy(H5T_C_S1)) < 0) return false;
292  if (H5Tset_size(dtype, size) < 0) return false;
293 
294  if (!attr_read_scalar(dtype, name, val)) return false;
295 
296  if (H5Tclose(dtype) < 0) return false;
297 
298  return true;
299 }
300 
301 bool
302 CSerializableHdf5File::group_create(const char* name,
303  const char* prefix)
304 {
305  hid_t ngroup;
306  string_t gname;
307 
308  snprintf(gname, STRING_LEN, "%s%s", prefix, name);
309 
310  m_stack_h5stream.push_back(
311  ngroup = H5Gcreate2(m_stack_h5stream.back(), gname, H5P_DEFAULT,
312  H5P_DEFAULT, H5P_DEFAULT));
313  if (ngroup < 0) return false;
314 
315  return true;
316 }
317 
318 bool
319 CSerializableHdf5File::group_open(const char* name,
320  const char* prefix)
321 {
322  hid_t group;
323  string_t gname;
324 
325  snprintf(gname, STRING_LEN, "%s%s", prefix, name);
326 
327  m_stack_h5stream.push_back(
328  group = H5Gopen2(m_stack_h5stream.back(), gname, H5P_DEFAULT));
329  if (group < 0) return false;
330 
331  return true;
332 }
333 
334 bool
335 CSerializableHdf5File::group_close()
336 {
337  if (H5Gclose(m_stack_h5stream.back()) < 0) return false;
338  m_stack_h5stream.pop_back();
339 
340  return true;
341 }
342 
343 CSerializableHdf5File::CSerializableHdf5File()
344  :CSerializableFile() { init(""); }
345 
346 CSerializableHdf5File::CSerializableHdf5File(const char* fname, char rw)
348 {
349  CSerializableFile::init(NULL, rw, fname);
350  init(fname);
351 }
352 
353 CSerializableHdf5File::~CSerializableHdf5File()
354 {
355  while (m_stack_type.get_num_elements() > 0) {
356  delete m_stack_type.back(); m_stack_type.pop_back();
357  }
358 
359  close();
360 }
361 
363 CSerializableHdf5File::new_reader(char* dest_version, size_t n)
364 {
365  if (!attr_read_string(STR_KEY_FILETYPE, dest_version, n))
366  return NULL;
367 
368  if (strcmp(STR_FILETYPE_00, dest_version) == 0)
369  return new SerializableHdf5Reader00(this);
370 
371  return NULL;
372 }
373 
374 void
375 CSerializableHdf5File::init(const char* fname)
376 {
377  if (m_filename == NULL || *m_filename == '\0') {
378  SG_WARNING("Filename not given for opening file!\n")
379  close(); return;
380  }
381 
382  hid_t h5stream = NOT_OPEN;
383  switch (m_task) {
384  case 'w':
385  h5stream = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT,
386  H5P_DEFAULT);
387  break;
388  case 'r':
389  h5stream = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
390  break;
391  default:
392  SG_WARNING("Could not open file `%s', unknown mode!\n",
393  m_filename);
394  close(); return;
395  }
396 
397  if (h5stream < 0) {
398  SG_WARNING("Could not open file `%s'!\n", m_filename)
399  close(); return;
400  }
401 
402  m_stack_h5stream.push_back(h5stream);
403  switch (m_task) {
404  case 'w':
405  if (!attr_write_string(STR_KEY_FILETYPE, STR_FILETYPE_00)) {
406  SG_WARNING("%s: Could not open file for writing during "
407  "writing filetype!\n", fname);
408  close(); return;
409  }
410  break;
411  case 'r': break;
412  default: break;
413  }
414 }
415 
416 void
417 CSerializableHdf5File::close()
418 {
419  while (m_stack_h5stream.get_num_elements() > 1) {
420  if (m_stack_h5stream.back() >= 0)
421  H5Gclose(m_stack_h5stream.back());
422  m_stack_h5stream.pop_back();
423  }
424 
425  if (m_stack_h5stream.get_num_elements() == 1) {
426  if (m_stack_h5stream.back() >= 0)
427  H5Fclose(m_stack_h5stream.back());
428  m_stack_h5stream.pop_back();
429  }
430 }
431 
432 bool
433 CSerializableHdf5File::is_opened()
434 {
435  return m_stack_h5stream.get_num_elements() > 0;
436 }
437 
438 bool
439 CSerializableHdf5File::write_scalar_wrapped(
440  const TSGDataType* type, const void* param)
441 {
442  type_item_t* m = m_stack_type.back();
443 
444  switch (type->m_stype) {
445  case ST_NONE:
446  if (m->y != 0 || m->x != 0) return true;
447  break;
448  case ST_STRING:
449  if (m->sub_y == 0)
450  m->vltype[m->x*m->dims[1] + m->y].p = (void*) param;
451 
452  if ((m->sub_y
453  < (index_t) m->vltype[m->x*m->dims[1] + m->y].len-1)
454  || ((type->m_ctype == CT_VECTOR || type->m_ctype == CT_SGVECTOR) && m->y
455  < (index_t) m->dims[0]-1)
456  || ((type->m_ctype == CT_MATRIX || type->m_ctype==CT_SGMATRIX)
457  && (m->x < (index_t) m->dims[0]-1
458  || m->y < (index_t) m->dims[1]-1)))
459  return true;
460  break;
461  case ST_SPARSE:
462  if (m->sub_y != 0) return true;
463  break;
464  default: return false;
465  }
466 
467  hid_t mem_type_id;
468  if ((mem_type_id = new_stype2hdf5(type->m_stype, type->m_ptype)
469  ) < 0) return false;
470 
471  switch (type->m_stype) {
472  case ST_NONE:
473  if (H5Dwrite(m->dset, mem_type_id, H5S_ALL, H5S_ALL,
474  H5P_DEFAULT, param) < 0) return false;
475  break;
476  case ST_STRING:
477  if (H5Dwrite(m->dset, mem_type_id, H5S_ALL, H5S_ALL,
478  H5P_DEFAULT, m->vltype) < 0) return false;
479  break;
480  case ST_SPARSE:
481  if (H5Dwrite(m->dset, m->dtype, H5S_ALL, H5S_ALL,
482  H5P_DEFAULT, m->sparse_ptr) < 0) return false;
483  break;
484  default: return false;
485  }
486 
487  if (H5Tclose(mem_type_id) < 0) return false;
488 
489  return true;
490 }
491 
492 bool
493 CSerializableHdf5File::write_cont_begin_wrapped(
494  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
495 {
496  hbool_t bool_buf = true;
497 
498  if (type->m_ptype != PT_SGOBJECT) return true;
499 
500  if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_CONT, &bool_buf))
501  return false;
502 
503  string_t ctype_buf;
504  type->to_string(ctype_buf, STRING_LEN);
505  if (!attr_write_string(STR_CTYPE_NAME, ctype_buf)) return false;
506 
507  switch (type->m_ctype) {
508  case CT_NDARRAY:
510  case CT_SCALAR:
511  SG_ERROR("write_cont_begin_wrapped(): Implementation error "
512  "during writing Hdf5File!");
513  return false;
514  case CT_MATRIX: case CT_SGMATRIX:
515  if (!attr_write_scalar(TYPE_INDEX, STR_LENGTH_X, &len_real_x))
516  return false;
517  /* break; */
518  case CT_VECTOR: case CT_SGVECTOR:
519  if (!attr_write_scalar(TYPE_INDEX, STR_LENGTH_Y, &len_real_y))
520  return false;
521  break;
522  default: return false;
523  }
524 
525  return true;
526 }
527 
528 bool
529 CSerializableHdf5File::write_cont_end_wrapped(
530  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
531 {
532  return true;
533 }
534 
535 bool
536 CSerializableHdf5File::write_string_begin_wrapped(
537  const TSGDataType* type, index_t length)
538 {
539  type_item_t* m = m_stack_type.back();
540 
541  m->vltype[m->x*m->dims[1] + m->y].len = length;
542 
543  return true;
544 }
545 
546 bool
547 CSerializableHdf5File::write_string_end_wrapped(
548  const TSGDataType* type, index_t length)
549 {
550  return true;
551 }
552 
553 bool
554 CSerializableHdf5File::write_stringentry_begin_wrapped(
555  const TSGDataType* type, index_t y)
556 {
557  type_item_t* m = m_stack_type.back();
558 
559  m->sub_y = y;
560 
561  return true;
562 }
563 
564 bool
565 CSerializableHdf5File::write_stringentry_end_wrapped(
566  const TSGDataType* type, index_t y)
567 {
568  return true;
569 }
570 
571 bool
572 CSerializableHdf5File::write_sparse_begin_wrapped(
573  const TSGDataType* type, index_t length)
574 {
575  type_item_t* m_prev = m_stack_type.back();
576 
577  if(!dspace_select(type->m_ctype, m_prev->y, m_prev->x))
578  return false;
579 
580  type_item_t* m = new type_item_t(m_stack_type.back()->name);
581  m_stack_type.push_back(m);
582 
583  /* ************************************************************ */
584 
585  if (m_prev->y == 0 && m_prev->x == 0) {
586  hbool_t bool_buf = true;
587  if (!group_create(m->name, STR_GROUP_PREFIX)) return false;
588 
589  if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_SPARSE,
590  &bool_buf)) return false;
591  } else {
592  if (!group_open(m->name, STR_GROUP_PREFIX)) return false;
593  if (!attr_exists(STR_IS_SPARSE)) return false;
594  }
595 
596  m->rank = 1; m->dims[0] = length;
597  if (m->dims[0] == 0) m->dspace = H5Screate(H5S_NULL);
598 
599  if (m->dspace < 0 && (m->dspace = H5Screate_simple(
600  m->rank, m->dims, NULL)) < 0)
601  return false;
602  if ((m->dtype = new_sparseentrytype(type->m_ptype)) < 0)
603  return false;
604 
605  string_t name;
606  index2string(name, STRING_LEN, type->m_ctype, m_prev->y,
607  m_prev->x);
608  if ((m->dset = H5Dcreate2(
609  m_stack_h5stream.back(), name, m->dtype, m->dspace,
610  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
611  return false;
612 
613  /* ************************************************************ */
614 
615  char* buf = SG_MALLOC(char, sizeof_sparsetype());
616 
617  hid_t mem_type_id;
618  if ((mem_type_id = new_sparsetype()) < 0) return false;
619 
620  hid_t mem_space_id;
621  if ((mem_space_id = H5Screate_simple(0, NULL, NULL)) < 0)
622  return false;
623 
624  hobj_ref_t* sparse_ref = get_ref_sparstype(buf);
625  if (H5Rcreate(sparse_ref, m_stack_h5stream.back(), name,
626  H5R_OBJECT, -1) < 0) return false;
627 
628  if (H5Dwrite(m_prev->dset, mem_type_id, mem_space_id,
629  m_prev->dspace, H5P_DEFAULT, buf) < 0) return false;
630 
631  if (H5Sclose(mem_space_id) < 0) return false;
632  if (H5Tclose(mem_type_id) < 0) return false;
633 
634  delete buf;
635 
636  return true;
637 }
638 
639 bool
640 CSerializableHdf5File::write_sparse_end_wrapped(
641  const TSGDataType* type, index_t length)
642 {
643  if (!group_close()) return false;
644  delete m_stack_type.back(); m_stack_type.pop_back();
645 
646  return true;
647 }
648 
649 bool
650 CSerializableHdf5File::write_sparseentry_begin_wrapped(
651  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
652  index_t feat_index, index_t y)
653 {
654  type_item_t* m = m_stack_type.back();
655 
656  m->sparse_ptr = (SGSparseVectorEntry<char>*) first_entry;
657  m->sub_y = y;
658 
659  return true;
660 }
661 
662 bool
663 CSerializableHdf5File::write_sparseentry_end_wrapped(
664  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
665  index_t feat_index, index_t y)
666 {
667  return true;
668 }
669 
670 bool
671 CSerializableHdf5File::write_item_begin_wrapped(
672  const TSGDataType* type, index_t y, index_t x)
673 {
674  type_item_t* m = m_stack_type.back();
675  m->y = y; m->x = x;
676 
677  if (type->m_ptype != PT_SGOBJECT) return true;
678 
679  string_t name;
680  if (!index2string(name, STRING_LEN, type->m_ctype, y, x))
681  return false;
682  if (!group_create(name, "")) return false;
683 
684  return true;
685 }
686 
687 bool
688 CSerializableHdf5File::write_item_end_wrapped(
689  const TSGDataType* type, index_t y, index_t x)
690 {
691  if (type->m_ptype == PT_SGOBJECT)
692  if (!group_close()) return false;
693 
694  return true;
695 }
696 
697 bool
698 CSerializableHdf5File::write_sgserializable_begin_wrapped(
699  const TSGDataType* type, const char* sgserializable_name,
700  EPrimitiveType generic)
701 {
702  hbool_t bool_buf = true;
703 
704  if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_SGSERIALIZABLE,
705  &bool_buf)) return false;
706 
707  if (*sgserializable_name == '\0') {
708  if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_NULL,
709  &bool_buf))
710  return false;
711  return true;
712  }
713 
714  if (!attr_write_string(STR_INSTANCE_NAME, sgserializable_name))
715  return false;
716 
717  if (generic != PT_NOT_GENERIC) {
718  string_t buf;
720  if (!attr_write_string(STR_GENERIC_NAME, buf)) return false;
721  }
722 
723  return true;
724 }
725 
726 bool
727 CSerializableHdf5File::write_sgserializable_end_wrapped(
728  const TSGDataType* type, const char* sgserializable_name,
729  EPrimitiveType generic)
730 {
731  return true;
732 }
733 
734 bool
735 CSerializableHdf5File::write_type_begin_wrapped(
736  const TSGDataType* type, const char* name, const char* prefix)
737 {
738  type_item_t* m = new type_item_t(name); m_stack_type.push_back(m);
739 
740  if (type->m_ptype == PT_SGOBJECT) {
741  if (!group_create(name, "")) return false;
742  return true;
743  }
744 
745  switch (type->m_ctype) {
746  case CT_NDARRAY:
748  case CT_SCALAR:
749  m->rank = 0;
750  if (type->m_stype == ST_STRING) m->vltype = SG_MALLOC(hvl_t, 1);
751  break;
752  case CT_VECTOR: case CT_SGVECTOR:
753  m->rank = 1; m->dims[0] = *type->m_length_y;
754  if (m->dims[0] == 0) m->dspace = H5Screate(H5S_NULL);
755  if (type->m_stype == ST_STRING)
756  m->vltype = SG_MALLOC(hvl_t, m->dims[0]);
757  break;
758  case CT_MATRIX: case CT_SGMATRIX:
759  m->rank = 2;
760  m->dims[0] = *type->m_length_x; m->dims[1] = *type->m_length_y;
761  if (m->dims[0] *m->dims[1] == 0)
762  m->dspace = H5Screate(H5S_NULL);
763  if (type->m_stype == ST_STRING)
764  m->vltype = SG_MALLOC(hvl_t, m->dims[0] *m->dims[1]);
765  break;
766  default: return false;
767  }
768 
769  if (m->dspace < 0 && (m->dspace = H5Screate_simple(
770  m->rank, m->dims, NULL)) < 0)
771  return false;
772  if ((m->dtype = new_stype2hdf5(type->m_stype, type->m_ptype)) < 0)
773  return false;
774 
775  if ((m->dset = H5Dcreate2(
776  m_stack_h5stream.back(), name, m->dtype, m->dspace,
777  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
778  return false;
779 
780  return true;
781 }
782 
783 bool
784 CSerializableHdf5File::write_type_end_wrapped(
785  const TSGDataType* type, const char* name, const char* prefix)
786 {
787  if (type->m_ptype == PT_SGOBJECT)
788  if (!group_close()) return false;
789 
790  delete m_stack_type.back(); m_stack_type.pop_back();
791  return true;
792 }
793 
794 #endif /* HAVE_HDF5 */

SHOGUN Machine Learning Toolbox - Documentation