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

SHOGUN Machine Learning Toolbox - Documentation