00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <shogun/lib/config.h>
00012 #ifdef HAVE_HDF5
00013
00014 #include <shogun/io/SerializableHdf5File.h>
00015 #include <shogun/io/SerializableHdf5Reader00.h>
00016
00017 #define NOT_OPEN ((hid_t) -1)
00018
00019 #define STR_KEY_FILETYPE "filetype"
00020 #define STR_FILETYPE_00 \
00021 "_SHOGUN_SERIALIZABLE_HDF5_FILE_V_00_"
00022
00023 using namespace shogun;
00024
00025 CSerializableHdf5File::type_item_t::type_item_t(const char* name_)
00026 {
00027 rank = 0;
00028 dims[0] = dims[1] = 0;
00029 dspace = dtype = dset = NOT_OPEN;
00030 vltype = NULL;
00031 y = x = sub_y = 0;
00032 sparse_ptr = NULL;
00033 name = name_;
00034 }
00035
00036 CSerializableHdf5File::type_item_t::~type_item_t(void)
00037 {
00038 if (dset >= 0) H5Dclose(dset);
00039 if (dtype >= 0) H5Tclose(dtype);
00040 if (dspace >= 0) H5Sclose(dspace);
00041 if (vltype != NULL) SG_FREE(vltype);
00042
00043 }
00044
00045 hid_t
00046 CSerializableHdf5File::sizeof_sparsetype(void) {
00047 return H5Tget_size(TYPE_INDEX) + H5Tget_size(H5T_STD_REF_OBJ);
00048 }
00049 hid_t
00050 CSerializableHdf5File::new_sparsetype(void)
00051 {
00052 hid_t result = H5Tcreate(H5T_COMPOUND, sizeof_sparsetype());
00053
00054 if (H5Tinsert(result, STR_SPARSE_VINDEX, 0, TYPE_INDEX) < 0)
00055 return NOT_OPEN;
00056 if (H5Tinsert(result, STR_SPARSE_FPTR, H5Tget_size(TYPE_INDEX),
00057 H5T_STD_REF_OBJ) < 0)
00058 return NOT_OPEN;
00059
00060 return result;
00061 }
00062 hobj_ref_t*
00063 CSerializableHdf5File::get_ref_sparstype(void* sparse_buf) {
00064 return (hobj_ref_t*)
00065 ((char*) sparse_buf + H5Tget_size(TYPE_INDEX));
00066 }
00067
00068 hid_t
00069 CSerializableHdf5File::new_sparseentrytype(EPrimitiveType ptype)
00070 {
00071 hid_t result = H5Tcreate(H5T_COMPOUND,
00072 TSGDataType::sizeof_sparseentry(ptype));
00073 if (result < 0) return NOT_OPEN;
00074
00075 if (H5Tinsert(result, STR_SPARSEENTRY_FINDEX,
00076 HOFFSET(SGSparseVectorEntry<char>, feat_index), TYPE_INDEX)
00077 < 0) return NOT_OPEN;
00078 if (H5Tinsert(result, STR_SPARSEENTRY_ENTRY, TSGDataType
00079 ::offset_sparseentry(ptype),
00080 ptype2hdf5(ptype)) < 0) return NOT_OPEN;
00081
00082 return result;
00083 }
00084
00085 hid_t
00086 CSerializableHdf5File::ptype2hdf5(EPrimitiveType ptype)
00087 {
00088 switch (ptype) {
00089 case PT_BOOL:
00090 switch (sizeof (bool)) {
00091 case 1: return H5T_NATIVE_UINT8;
00092 case 2: return H5T_NATIVE_UINT16;
00093 case 4: return H5T_NATIVE_UINT32;
00094 case 8: return H5T_NATIVE_UINT64;
00095 default: break;
00096 }
00097 break;
00098 case PT_CHAR: return H5T_NATIVE_CHAR; break;
00099 case PT_INT8: return H5T_NATIVE_INT8; break;
00100 case PT_UINT8: return H5T_NATIVE_UINT8; break;
00101 case PT_INT16: return H5T_NATIVE_INT16; break;
00102 case PT_UINT16: return H5T_NATIVE_UINT16; break;
00103 case PT_INT32: return H5T_NATIVE_INT32; break;
00104 case PT_UINT32: return H5T_NATIVE_UINT32; break;
00105 case PT_INT64: return H5T_NATIVE_INT64; break;
00106 case PT_UINT64: return H5T_NATIVE_UINT64; break;
00107 case PT_FLOAT32: return H5T_NATIVE_FLOAT; break;
00108 case PT_FLOAT64: return H5T_NATIVE_DOUBLE; break;
00109 case PT_FLOATMAX: return H5T_NATIVE_LDOUBLE; break;
00110 case PT_SGOBJECT: return NOT_OPEN; break;
00111 }
00112
00113 return NOT_OPEN;
00114 }
00115
00116 hid_t
00117 CSerializableHdf5File::new_stype2hdf5(EStructType stype,
00118 EPrimitiveType ptype)
00119 {
00120 hid_t result = ptype2hdf5(ptype);
00121
00122 switch (stype) {
00123 case ST_NONE: result = H5Tcopy(result); break;
00124 case ST_STRING: result = H5Tvlen_create(result); break;
00125 case ST_SPARSE: result = new_sparsetype(); break;
00126 default: break;
00127 }
00128
00129 return result;
00130 }
00131
00132 bool
00133 CSerializableHdf5File::index2string(
00134 char* dest, size_t n, EContainerType ctype, index_t y, index_t x)
00135 {
00136 switch (ctype) {
00137 case CT_NDARRAY: SG_SNOTIMPLEMENTED;
00138 case CT_SCALAR: return false;
00139 case CT_VECTOR: case CT_SGVECTOR: snprintf(dest, n, "y%u", y); break;
00140 case CT_MATRIX: case CT_SGMATRIX: snprintf(dest, n, "y%u_x%u", y, x); break;
00141 default: return false;
00142 }
00143
00144 return true;
00145 }
00146
00147 bool
00148 CSerializableHdf5File::isequal_stype2hdf5(EStructType stype,
00149 EPrimitiveType ptype,
00150 hid_t htype)
00151 {
00152 hid_t pbuf = ptype2hdf5(ptype), pbuf2 = NOT_OPEN;
00153
00154 bool to_close = false;
00155 switch (stype) {
00156 case ST_NONE: break;
00157 case ST_STRING:
00158 to_close = true; pbuf = H5Tvlen_create(pbuf); break;
00159 case ST_SPARSE:
00160 to_close = true; pbuf = new_sparsetype();
00161 pbuf2 = new_sparseentrytype(ptype); break;
00162 }
00163
00164 bool result = (H5Tequal(htype, pbuf) > 0)
00165 || (pbuf2 >= 0 && H5Tequal(htype, pbuf2) > 0);
00166
00167 if (pbuf2 >= 0 && H5Tclose(pbuf2) < 0) return false;
00168 if (to_close && H5Tclose(pbuf) < 0) return false;
00169 return result;
00170 }
00171
00172 bool
00173 CSerializableHdf5File::dspace_select(EContainerType ctype, index_t y,
00174 index_t x)
00175 {
00176 type_item_t* m = m_stack_type.back();
00177
00178 if (H5Sselect_none(m->dspace) < 0) return false;
00179
00180 hsize_t coord[2];
00181 switch (ctype) {
00182 case CT_NDARRAY: SG_NOTIMPLEMENTED;
00183 case CT_SCALAR: return false;
00184 case CT_MATRIX: case CT_SGMATRIX: coord[1] = x;
00185 case CT_VECTOR: case CT_SGVECTOR: coord[0] = y; break;
00186 default: return false;
00187 }
00188 if (H5Sselect_elements(m->dspace, H5S_SELECT_SET, 1, coord) < 0)
00189 return false;
00190
00191 return true;
00192 }
00193
00194 bool
00195 CSerializableHdf5File::attr_write_scalar(
00196 hid_t datatype, const char* name, const void* val)
00197 {
00198 hid_t dspace;
00199 if ((dspace = H5Screate_simple(0, NULL, NULL)) < 0) return false;
00200 hid_t dtype;
00201 if ((dtype = H5Tcopy(datatype)) < 0) return false;
00202 hid_t attr;
00203 if ((attr = H5Acreate2(
00204 m_stack_h5stream.back(), name, dtype, dspace,
00205 H5P_DEFAULT, H5P_DEFAULT)) < 0) return false;
00206
00207 if (H5Awrite(attr, datatype, val) < 0) return false;
00208
00209 if (H5Aclose(attr) < 0) return false;
00210 if (H5Tclose(dtype) < 0) return false;
00211 if (H5Sclose(dspace) < 0) return false;
00212
00213 return true;
00214 }
00215
00216 bool
00217 CSerializableHdf5File::attr_write_string(
00218 const char* name, const char* val)
00219 {
00220 hid_t dtype;
00221 if ((dtype = H5Tcopy(H5T_C_S1)) < 0) return false;
00222 if (H5Tset_size(dtype, strlen(val)+1) < 0) return false;
00223
00224 if (!attr_write_scalar(dtype, name, val)) return false;
00225
00226 if (H5Tclose(dtype) < 0) return false;
00227
00228 return true;
00229 }
00230
00231 bool
00232 CSerializableHdf5File::attr_exists(const char* name)
00233 {
00234 return H5Aexists(m_stack_h5stream.back(), name) > 0;
00235 }
00236
00237 size_t
00238 CSerializableHdf5File::attr_get_size(const char* name)
00239 {
00240 if (!attr_exists(name)) return 0;
00241
00242 hid_t attr;
00243 if ((attr = H5Aopen(m_stack_h5stream.back(), name, H5P_DEFAULT))
00244 < 0) return 0;
00245
00246 hid_t dtype;
00247 if ((dtype = H5Aget_type(attr)) < 0) return 0;
00248
00249 size_t result = H5Tget_size(dtype);
00250
00251 if (H5Tclose(dtype) < 0) return 0;
00252 if (H5Aclose(attr) < 0) return 0;
00253
00254 return result;
00255 }
00256
00257 bool
00258 CSerializableHdf5File::attr_read_scalar(
00259 hid_t datatype, const char* name, void* val)
00260 {
00261 if (!attr_exists(name)) return false;
00262
00263 hid_t attr;
00264 if ((attr = H5Aopen(m_stack_h5stream.back(), name, H5P_DEFAULT))
00265 < 0) return false;
00266
00267 hid_t dspace;
00268 if ((dspace = H5Aget_space(attr)) < 0) return false;
00269 if (H5Sget_simple_extent_type(dspace) != H5S_SCALAR) return false;
00270
00271 hid_t dtype;
00272 if ((dtype = H5Aget_type(attr)) < 0) return false;
00273 if (H5Tequal(datatype, dtype) <= 0) return false;
00274
00275 if (H5Aread(attr, datatype, val) < 0) return false;
00276
00277 if (H5Tclose(dtype) < 0) return false;
00278 if (H5Sclose(dspace) < 0) return false;
00279 if (H5Aclose(attr) < 0) return false;
00280
00281 return true;
00282 }
00283
00284 bool
00285 CSerializableHdf5File::attr_read_string(
00286 const char* name, char* val, size_t n)
00287 {
00288 size_t size = attr_get_size(name);
00289 if (size == 0 || size > n) return false;
00290
00291 hid_t dtype;
00292 if ((dtype = H5Tcopy(H5T_C_S1)) < 0) return false;
00293 if (H5Tset_size(dtype, size) < 0) return false;
00294
00295 if (!attr_read_scalar(dtype, name, val)) return false;
00296
00297 if (H5Tclose(dtype) < 0) return false;
00298
00299 return true;
00300 }
00301
00302 bool
00303 CSerializableHdf5File::group_create(const char* name,
00304 const char* prefix)
00305 {
00306 hid_t ngroup;
00307 string_t gname;
00308
00309 snprintf(gname, STRING_LEN, "%s%s", prefix, name);
00310
00311 m_stack_h5stream.push_back(
00312 ngroup = H5Gcreate2(m_stack_h5stream.back(), gname, H5P_DEFAULT,
00313 H5P_DEFAULT, H5P_DEFAULT));
00314 if (ngroup < 0) return false;
00315
00316 return true;
00317 }
00318
00319 bool
00320 CSerializableHdf5File::group_open(const char* name,
00321 const char* prefix)
00322 {
00323 hid_t group;
00324 string_t gname;
00325
00326 snprintf(gname, STRING_LEN, "%s%s", prefix, name);
00327
00328 m_stack_h5stream.push_back(
00329 group = H5Gopen2(m_stack_h5stream.back(), gname, H5P_DEFAULT));
00330 if (group < 0) return false;
00331
00332 return true;
00333 }
00334
00335 bool
00336 CSerializableHdf5File::group_close(void)
00337 {
00338 if (H5Gclose(m_stack_h5stream.back()) < 0) return false;
00339 m_stack_h5stream.pop_back();
00340
00341 return true;
00342 }
00343
00344 CSerializableHdf5File::CSerializableHdf5File(void)
00345 :CSerializableFile() { init(""); }
00346
00347 CSerializableHdf5File::CSerializableHdf5File(const char* fname, char rw)
00348 :CSerializableFile()
00349 {
00350 CSerializableFile::init(NULL, rw, fname);
00351 init(fname);
00352 }
00353
00354 CSerializableHdf5File::~CSerializableHdf5File()
00355 {
00356 while (m_stack_type.get_num_elements() > 0) {
00357 delete m_stack_type.back(); m_stack_type.pop_back();
00358 }
00359
00360 close();
00361 }
00362
00363 CSerializableFile::TSerializableReader*
00364 CSerializableHdf5File::new_reader(char* dest_version, size_t n)
00365 {
00366 if (!attr_read_string(STR_KEY_FILETYPE, dest_version, n))
00367 return NULL;
00368
00369 if (strcmp(STR_FILETYPE_00, dest_version) == 0)
00370 return new SerializableHdf5Reader00(this);
00371
00372 return NULL;
00373 }
00374
00375 void
00376 CSerializableHdf5File::init(const char* fname)
00377 {
00378 if (m_filename == NULL || *m_filename == '\0') {
00379 SG_WARNING("Filename not given for opening file!\n");
00380 close(); return;
00381 }
00382
00383 hid_t h5stream = NOT_OPEN;
00384 switch (m_task) {
00385 case 'w':
00386 h5stream = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT,
00387 H5P_DEFAULT);
00388 break;
00389 case 'r':
00390 h5stream = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
00391 break;
00392 default:
00393 SG_WARNING("Could not open file `%s', unknown mode!\n",
00394 m_filename);
00395 close(); return;
00396 }
00397
00398 if (h5stream < 0) {
00399 SG_WARNING("Could not open file `%s'!\n", m_filename);
00400 close(); return;
00401 }
00402
00403 m_stack_h5stream.push_back(h5stream);
00404 switch (m_task) {
00405 case 'w':
00406 if (!attr_write_string(STR_KEY_FILETYPE, STR_FILETYPE_00)) {
00407 SG_WARNING("%s: Could not open file for writing during "
00408 "writing filetype!\n", fname);
00409 close(); return;
00410 }
00411 break;
00412 case 'r': break;
00413 default: break;
00414 }
00415 }
00416
00417 void
00418 CSerializableHdf5File::close(void)
00419 {
00420 while (m_stack_h5stream.get_num_elements() > 1) {
00421 if (m_stack_h5stream.back() >= 0)
00422 H5Gclose(m_stack_h5stream.back());
00423 m_stack_h5stream.pop_back();
00424 }
00425
00426 if (m_stack_h5stream.get_num_elements() == 1) {
00427 if (m_stack_h5stream.back() >= 0)
00428 H5Fclose(m_stack_h5stream.back());
00429 m_stack_h5stream.pop_back();
00430 }
00431 }
00432
00433 bool
00434 CSerializableHdf5File::is_opened(void)
00435 {
00436 return m_stack_h5stream.get_num_elements() > 0;
00437 }
00438
00439 bool
00440 CSerializableHdf5File::write_scalar_wrapped(
00441 const TSGDataType* type, const void* param)
00442 {
00443 type_item_t* m = m_stack_type.back();
00444
00445 switch (type->m_stype) {
00446 case ST_NONE:
00447 if (m->y != 0 || m->x != 0) return true;
00448 break;
00449 case ST_STRING:
00450 if (m->sub_y == 0)
00451 m->vltype[m->x*m->dims[1] + m->y].p = (void*) param;
00452
00453 if ((m->sub_y
00454 < (index_t) m->vltype[m->x*m->dims[1] + m->y].len-1)
00455 || ((type->m_ctype == CT_VECTOR || type->m_ctype == CT_SGVECTOR) && m->y
00456 < (index_t) m->dims[0]-1)
00457 || ((type->m_ctype == CT_MATRIX || type->m_ctype==CT_SGMATRIX)
00458 && (m->x < (index_t) m->dims[0]-1
00459 || m->y < (index_t) m->dims[1]-1)))
00460 return true;
00461 break;
00462 case ST_SPARSE:
00463 if (m->sub_y != 0) return true;
00464 break;
00465 default: return false;
00466 }
00467
00468 hid_t mem_type_id;
00469 if ((mem_type_id = new_stype2hdf5(type->m_stype, type->m_ptype)
00470 ) < 0) return false;
00471
00472 switch (type->m_stype) {
00473 case ST_NONE:
00474 if (H5Dwrite(m->dset, mem_type_id, H5S_ALL, H5S_ALL,
00475 H5P_DEFAULT, param) < 0) return false;
00476 break;
00477 case ST_STRING:
00478 if (H5Dwrite(m->dset, mem_type_id, H5S_ALL, H5S_ALL,
00479 H5P_DEFAULT, m->vltype) < 0) return false;
00480 break;
00481 case ST_SPARSE:
00482 if (H5Dwrite(m->dset, m->dtype, H5S_ALL, H5S_ALL,
00483 H5P_DEFAULT, m->sparse_ptr) < 0) return false;
00484 break;
00485 default: return false;
00486 }
00487
00488 if (H5Tclose(mem_type_id) < 0) return false;
00489
00490 return true;
00491 }
00492
00493 bool
00494 CSerializableHdf5File::write_cont_begin_wrapped(
00495 const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00496 {
00497 hbool_t bool_buf = true;
00498
00499 if (type->m_ptype != PT_SGOBJECT) return true;
00500
00501 if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_CONT, &bool_buf))
00502 return false;
00503
00504 string_t ctype_buf;
00505 type->to_string(ctype_buf, STRING_LEN);
00506 if (!attr_write_string(STR_CTYPE_NAME, ctype_buf)) return false;
00507
00508 switch (type->m_ctype) {
00509 case CT_NDARRAY:
00510 SG_NOTIMPLEMENTED;
00511 case CT_SCALAR:
00512 SG_ERROR("write_cont_begin_wrapped(): Implementation error "
00513 "during writing Hdf5File!");
00514 return false;
00515 case CT_MATRIX: case CT_SGMATRIX:
00516 if (!attr_write_scalar(TYPE_INDEX, STR_LENGTH_X, &len_real_x))
00517 return false;
00518
00519 case CT_VECTOR: case CT_SGVECTOR:
00520 if (!attr_write_scalar(TYPE_INDEX, STR_LENGTH_Y, &len_real_y))
00521 return false;
00522 break;
00523 default: return false;
00524 }
00525
00526 return true;
00527 }
00528
00529 bool
00530 CSerializableHdf5File::write_cont_end_wrapped(
00531 const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00532 {
00533 return true;
00534 }
00535
00536 bool
00537 CSerializableHdf5File::write_string_begin_wrapped(
00538 const TSGDataType* type, index_t length)
00539 {
00540 type_item_t* m = m_stack_type.back();
00541
00542 m->vltype[m->x*m->dims[1] + m->y].len = length;
00543
00544 return true;
00545 }
00546
00547 bool
00548 CSerializableHdf5File::write_string_end_wrapped(
00549 const TSGDataType* type, index_t length)
00550 {
00551 return true;
00552 }
00553
00554 bool
00555 CSerializableHdf5File::write_stringentry_begin_wrapped(
00556 const TSGDataType* type, index_t y)
00557 {
00558 type_item_t* m = m_stack_type.back();
00559
00560 m->sub_y = y;
00561
00562 return true;
00563 }
00564
00565 bool
00566 CSerializableHdf5File::write_stringentry_end_wrapped(
00567 const TSGDataType* type, index_t y)
00568 {
00569 return true;
00570 }
00571
00572 bool
00573 CSerializableHdf5File::write_sparse_begin_wrapped(
00574 const TSGDataType* type, index_t vec_index,
00575 index_t length)
00576 {
00577 type_item_t* m_prev = m_stack_type.back();
00578
00579 if(!dspace_select(type->m_ctype, m_prev->y, m_prev->x))
00580 return false;
00581
00582 type_item_t* m = new type_item_t(m_stack_type.back()->name);
00583 m_stack_type.push_back(m);
00584
00585
00586
00587 if (m_prev->y == 0 && m_prev->x == 0) {
00588 hbool_t bool_buf = true;
00589 if (!group_create(m->name, STR_GROUP_PREFIX)) return false;
00590
00591 if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_SPARSE,
00592 &bool_buf)) return false;
00593 } else {
00594 if (!group_open(m->name, STR_GROUP_PREFIX)) return false;
00595 if (!attr_exists(STR_IS_SPARSE)) return false;
00596 }
00597
00598 m->rank = 1; m->dims[0] = length;
00599 if (m->dims[0] == 0) m->dspace = H5Screate(H5S_NULL);
00600
00601 if (m->dspace < 0 && (m->dspace = H5Screate_simple(
00602 m->rank, m->dims, NULL)) < 0)
00603 return false;
00604 if ((m->dtype = new_sparseentrytype(type->m_ptype)) < 0)
00605 return false;
00606
00607 string_t name;
00608 index2string(name, STRING_LEN, type->m_ctype, m_prev->y,
00609 m_prev->x);
00610 if ((m->dset = H5Dcreate2(
00611 m_stack_h5stream.back(), name, m->dtype, m->dspace,
00612 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
00613 return false;
00614
00615
00616
00617 char* buf = SG_MALLOC(char, sizeof_sparsetype());
00618
00619 *(index_t*) buf = vec_index;
00620
00621 hid_t mem_type_id;
00622 if ((mem_type_id = new_sparsetype()) < 0) return false;
00623
00624 hid_t mem_space_id;
00625 if ((mem_space_id = H5Screate_simple(0, NULL, NULL)) < 0)
00626 return false;
00627
00628 hobj_ref_t* sparse_ref = get_ref_sparstype(buf);
00629 if (H5Rcreate(sparse_ref, m_stack_h5stream.back(), name,
00630 H5R_OBJECT, -1) < 0) return false;
00631
00632 if (H5Dwrite(m_prev->dset, mem_type_id, mem_space_id,
00633 m_prev->dspace, H5P_DEFAULT, buf) < 0) return false;
00634
00635 if (H5Sclose(mem_space_id) < 0) return false;
00636 if (H5Tclose(mem_type_id) < 0) return false;
00637
00638 delete buf;
00639
00640 return true;
00641 }
00642
00643 bool
00644 CSerializableHdf5File::write_sparse_end_wrapped(
00645 const TSGDataType* type, index_t vec_index,
00646 index_t length)
00647 {
00648 if (!group_close()) return false;
00649 delete m_stack_type.back(); m_stack_type.pop_back();
00650
00651 return true;
00652 }
00653
00654 bool
00655 CSerializableHdf5File::write_sparseentry_begin_wrapped(
00656 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00657 index_t feat_index, index_t y)
00658 {
00659 type_item_t* m = m_stack_type.back();
00660
00661 m->sparse_ptr = (SGSparseVectorEntry<char>*) first_entry;
00662 m->sub_y = y;
00663
00664 return true;
00665 }
00666
00667 bool
00668 CSerializableHdf5File::write_sparseentry_end_wrapped(
00669 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00670 index_t feat_index, index_t y)
00671 {
00672 return true;
00673 }
00674
00675 bool
00676 CSerializableHdf5File::write_item_begin_wrapped(
00677 const TSGDataType* type, index_t y, index_t x)
00678 {
00679 type_item_t* m = m_stack_type.back();
00680 m->y = y; m->x = x;
00681
00682 if (type->m_ptype != PT_SGOBJECT) return true;
00683
00684 string_t name;
00685 if (!index2string(name, STRING_LEN, type->m_ctype, y, x))
00686 return false;
00687 if (!group_create(name, "")) return false;
00688
00689 return true;
00690 }
00691
00692 bool
00693 CSerializableHdf5File::write_item_end_wrapped(
00694 const TSGDataType* type, index_t y, index_t x)
00695 {
00696 if (type->m_ptype == PT_SGOBJECT)
00697 if (!group_close()) return false;
00698
00699 return true;
00700 }
00701
00702 bool
00703 CSerializableHdf5File::write_sgserializable_begin_wrapped(
00704 const TSGDataType* type, const char* sgserializable_name,
00705 EPrimitiveType generic)
00706 {
00707 hbool_t bool_buf = true;
00708
00709 if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_SGSERIALIZABLE,
00710 &bool_buf)) return false;
00711
00712 if (*sgserializable_name == '\0') {
00713 if (!attr_write_scalar(H5T_NATIVE_HBOOL, STR_IS_NULL,
00714 &bool_buf))
00715 return false;
00716 return true;
00717 }
00718
00719 if (!attr_write_string(STR_INSTANCE_NAME, sgserializable_name))
00720 return false;
00721
00722 if (generic != PT_NOT_GENERIC) {
00723 string_t buf;
00724 TSGDataType::ptype_to_string(buf, generic, STRING_LEN);
00725 if (!attr_write_string(STR_GENERIC_NAME, buf)) return false;
00726 }
00727
00728 return true;
00729 }
00730
00731 bool
00732 CSerializableHdf5File::write_sgserializable_end_wrapped(
00733 const TSGDataType* type, const char* sgserializable_name,
00734 EPrimitiveType generic)
00735 {
00736 return true;
00737 }
00738
00739 bool
00740 CSerializableHdf5File::write_type_begin_wrapped(
00741 const TSGDataType* type, const char* name, const char* prefix)
00742 {
00743 type_item_t* m = new type_item_t(name); m_stack_type.push_back(m);
00744
00745 if (type->m_ptype == PT_SGOBJECT) {
00746 if (!group_create(name, "")) return false;
00747 return true;
00748 }
00749
00750 switch (type->m_ctype) {
00751 case CT_NDARRAY:
00752 SG_NOTIMPLEMENTED;
00753 case CT_SCALAR:
00754 m->rank = 0;
00755 if (type->m_stype == ST_STRING) m->vltype = SG_MALLOC(hvl_t, 1);
00756 break;
00757 case CT_VECTOR: case CT_SGVECTOR:
00758 m->rank = 1; m->dims[0] = *type->m_length_y;
00759 if (m->dims[0] == 0) m->dspace = H5Screate(H5S_NULL);
00760 if (type->m_stype == ST_STRING)
00761 m->vltype = SG_MALLOC(hvl_t, m->dims[0]);
00762 break;
00763 case CT_MATRIX: case CT_SGMATRIX:
00764 m->rank = 2;
00765 m->dims[0] = *type->m_length_x; m->dims[1] = *type->m_length_y;
00766 if (m->dims[0] *m->dims[1] == 0)
00767 m->dspace = H5Screate(H5S_NULL);
00768 if (type->m_stype == ST_STRING)
00769 m->vltype = SG_MALLOC(hvl_t, m->dims[0] *m->dims[1]);
00770 break;
00771 default: return false;
00772 }
00773
00774 if (m->dspace < 0 && (m->dspace = H5Screate_simple(
00775 m->rank, m->dims, NULL)) < 0)
00776 return false;
00777 if ((m->dtype = new_stype2hdf5(type->m_stype, type->m_ptype)) < 0)
00778 return false;
00779
00780 if ((m->dset = H5Dcreate2(
00781 m_stack_h5stream.back(), name, m->dtype, m->dspace,
00782 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
00783 return false;
00784
00785 return true;
00786 }
00787
00788 bool
00789 CSerializableHdf5File::write_type_end_wrapped(
00790 const TSGDataType* type, const char* name, const char* prefix)
00791 {
00792 if (type->m_ptype == PT_SGOBJECT)
00793 if (!group_close()) return false;
00794
00795 delete m_stack_type.back(); m_stack_type.pop_back();
00796 return true;
00797 }
00798
00799 #endif