/* This may be ultimately confused with nested types with 2 components called 'r' and 'i' and being floats, but in that case, the user most probably wanted to keep a complex type, so getting a complex instead of a nested type should not be a big issue (I hope!) :-/ F. Alted 2005-05-23 */ int is_complex(hid_t type_id) { hid_t class_id, base_type_id; hid_t class1, class2; char *colname1, *colname2; int result = 0; hsize_t nfields; class_id = H5Tget_class(type_id); if (class_id == H5T_COMPOUND) { nfields = H5Tget_nmembers(type_id); if (nfields == 2) { colname1 = H5Tget_member_name(type_id, 0); colname2 = H5Tget_member_name(type_id, 1); if ((strcmp(colname1, "r") == 0) && (strcmp(colname2, "i") == 0)) { class1 = H5Tget_member_class(type_id, 0); class2 = H5Tget_member_class(type_id, 1); if (class1 == H5T_FLOAT && class2 == H5T_FLOAT) result = 1; } free(colname1); free(colname2); } } /* Is an Array of Complex? */ else if (class_id == H5T_ARRAY) { /* Get the array base component */ base_type_id = H5Tget_super(type_id); /* Call is_complex again */ result = is_complex(base_type_id); H5Tclose(base_type_id); } return result; }
/*------------------------------------------------------------------------- * subroutine for test_text_dtype(): test_compounds(). *------------------------------------------------------------------------- */ static int test_compounds(void) { hid_t dtype; int nmembs; char *memb_name = NULL; H5T_class_t memb_class; H5T_class_t type_class; char* dt_str; size_t str_len; TESTING3(" text for compound types"); if((dtype = H5LTtext_to_dtype("H5T_COMPOUND { H5T_STD_I16BE \"one_field\" : 2; H5T_STD_U8LE \"two_field\" : 6; }", H5LT_DDL))<0) goto out; if((type_class = H5Tget_class(dtype))<0) goto out; if(type_class != H5T_COMPOUND) goto out; if((nmembs = H5Tget_nmembers(dtype))<0) goto out; if(nmembs != 2) goto out; if(H5LTdtype_to_text(dtype, NULL, H5LT_DDL, &str_len)<0) goto out; dt_str = (char*)calloc(str_len, sizeof(char)); if(H5LTdtype_to_text(dtype, dt_str, H5LT_DDL, &str_len)<0) goto out; if(strcmp(dt_str, "H5T_COMPOUND {\n H5T_STD_I16BE \"one_field\" : 2;\n H5T_STD_U8LE \"two_field\" : 6;\n }")) { printf("dt=\n%s\n", dt_str); goto out; } free(dt_str); if(H5Tclose(dtype)<0) goto out; if((dtype = H5LTtext_to_dtype("H5T_COMPOUND { H5T_STD_I32BE \"i32_field\"; H5T_STD_I16BE \"i16_field\"; H5T_COMPOUND { H5T_STD_I16BE \"sec_field\"; H5T_COMPOUND { H5T_STD_I32BE \"thd_field\"; } \"grandchild\"; } \"child_compound\"; H5T_STD_I8BE \"i8_field\"; }", H5LT_DDL))<0) goto out; if((memb_name = H5Tget_member_name(dtype, 1)) == NULL) goto out; if(strcmp(memb_name, "i16_field")) goto out; free(memb_name); if((memb_class = H5Tget_member_class(dtype, 2))<0) goto out; if(memb_class != H5T_COMPOUND) goto out; PASSED(); return 0; out: H5_FAILED(); return -1; }
//-------------------------------------------------------------------------- // Function: CompType::getMemberName ///\brief Returns the name of a member in this compound datatype. ///\param member_num - IN: Zero-based index of the member ///\return Name of member ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5std_string CompType::getMemberName( unsigned member_num ) const { char* member_name_C = H5Tget_member_name( id, member_num ); if( member_name_C == NULL ) // NULL means failure { throw DataTypeIException("CompType::getMemberName", "H5Tget_member_name returns NULL for member name"); } H5std_string member_name = H5std_string(member_name_C); // convert C string to string H5free_memory(member_name_C); // free the C string return( member_name ); // return the member name string }
/** This method returns the field name for the given field index. Memory * for returned string is allocated on the heap and should be released using * mifree_name(). */ int miget_record_field_name(mihandle_t volume, int index, char **name) { if (volume == NULL || name == NULL) { return (MI_ERROR); } /* Get the field name. The H5Tget_member_name() function allocates * the memory for the string using malloc(), so we can return the * pointer directly without any further manipulations. */ *name = H5Tget_member_name(volume->ftype_id, index); if (*name == NULL) { return (MI_ERROR); } return (MI_NOERROR); }
H5CompoundData::H5CompoundData(H5Object & _parent, const hsize_t _totalSize, const hsize_t _dataSize, const hsize_t _ndims, const hsize_t * _dims, char * _data, hid_t compoundType, const hsize_t _stride, const size_t _offset, const bool _dataOwner) : H5BasicData<char>(_parent, _totalSize, _dataSize, _ndims, _dims, _data, _stride, _offset, _dataOwner), type(compoundType), cumprod(H5Object::getCumProd(_ndims, dims)) { nfields = (unsigned int)H5Tget_nmembers(compoundType); infos = new std::map<std::string, FieldInfo *>(); fieldinfos = new FieldInfo *[nfields]; for (unsigned int i = 0; i < nfields; i++) { hid_t mtype = H5Tget_member_type(compoundType, i); hsize_t size = H5Tget_size(mtype); char * mname = H5Tget_member_name(compoundType, i); size_t offs = H5Tget_member_offset(compoundType, i); FieldInfo * info = 0; if (H5Tget_class(type) == H5T_STRING && !H5Tis_variable_str(type)) { // We have a C-string so it is null terminated size++; } info = new FieldInfo(mtype, size, offs, std::string(mname)); (*infos)[std::string(mname)] = info; fieldinfos[i] = info; free(mname); } }
int main(void) { hid_t fil,spc,set; hid_t cs6, cmp, fix; hid_t cmp1, cmp2, cmp3; hid_t plist; hid_t array_dt; hsize_t dim[2]; hsize_t cdim[4]; char string5[5]; float fok[2] = {1234., 2341.}; float fnok[2] = {5678., 6785.}; float *fptr; char *data; char *mname; int result = 0; printf("%-70s", "Testing alignment in compound datatypes"); strcpy(string5, "Hi!"); HDunlink(fname); fil = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if (fil < 0) { puts("*FAILED*"); return 1; } H5E_BEGIN_TRY { H5Ldelete(fil, setname, H5P_DEFAULT); } H5E_END_TRY; cs6 = H5Tcopy(H5T_C_S1); H5Tset_size(cs6, sizeof(string5)); H5Tset_strpad(cs6, H5T_STR_NULLPAD); cmp = H5Tcreate(H5T_COMPOUND, sizeof(fok) + sizeof(string5) + sizeof(fnok)); H5Tinsert(cmp, "Awkward length", 0, cs6); cdim[0] = sizeof(fok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp, "Ok", sizeof(string5), array_dt); H5Tclose(array_dt); cdim[0] = sizeof(fnok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp, "Not Ok", sizeof(fok) + sizeof(string5), array_dt); H5Tclose(array_dt); fix=h5tools_get_native_type(cmp); cmp1 = H5Tcreate(H5T_COMPOUND, sizeof(fok)); cdim[0] = sizeof(fok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp1, "Ok", 0, array_dt); H5Tclose(array_dt); cmp2 = H5Tcreate(H5T_COMPOUND, sizeof(string5)); H5Tinsert(cmp2, "Awkward length", 0, cs6); cmp3 = H5Tcreate(H5T_COMPOUND, sizeof(fnok)); cdim[0] = sizeof(fnok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp3, "Not Ok", 0, array_dt); H5Tclose(array_dt); plist = H5Pcreate(H5P_DATASET_XFER); H5Pset_preserve(plist, 1); /* * Create a small dataset, and write data into it we write each field * in turn so that we are avoid alignment issues at this point */ dim[0] = 1; spc = H5Screate_simple(1, dim, NULL); set = H5Dcreate2(fil, setname, cmp, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); H5Dwrite(set, cmp1, spc, H5S_ALL, plist, fok); H5Dwrite(set, cmp2, spc, H5S_ALL, plist, string5); H5Dwrite(set, cmp3, spc, H5S_ALL, plist, fnok); H5Dclose(set); /* Now open the set, and read it back in */ data = malloc(H5Tget_size(fix)); if(!data) { perror("malloc() failed"); abort(); } set = H5Dopen2(fil, setname, H5P_DEFAULT); H5Dread(set, fix, spc, H5S_ALL, H5P_DEFAULT, data); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); if(fok[0] != fptr[0] || fok[1] != fptr[1] || fnok[0] != fptr[2] || fnok[1] != fptr[3]) { result = 1; printf("%14s (%2d) %6s = %s\n", mname = H5Tget_member_name(fix, 0), (int)H5Tget_member_offset(fix,0), string5, (char *)(data + H5Tget_member_offset(fix, 0))); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); printf("Data comparison:\n" "%14s (%2d) %6f = %f\n" " %6f = %f\n", mname = H5Tget_member_name(fix, 1), (int)H5Tget_member_offset(fix,1), fok[0], fptr[0], fok[1], fptr[1]); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 2)); printf("%14s (%2d) %6f = %f\n" " %6f = %6f\n", mname = H5Tget_member_name(fix, 2), (int)H5Tget_member_offset(fix,2), fnok[0], fptr[0], fnok[1], fptr[1]); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); printf("\n" "Short circuit\n" " %6f = %f\n" " %6f = %f\n" " %6f = %f\n" " %6f = %f\n", fok[0], fptr[0], fok[1], fptr[1], fnok[0], fptr[2], fnok[1], fptr[3]); puts("*FAILED*"); } else { puts(" PASSED"); } free(data); H5Sclose(spc); H5Tclose(cmp); H5Tclose(cmp1); H5Tclose(cmp2); H5Tclose(cmp3); H5Pclose(plist); H5Fclose(fil); HDunlink(fname); fflush(stdout); return result; }
/* Purpose: retrieve datatype and dataspace information from file * Parameters: H5Dataset *d -- The dataset to be initialized * Return: Returns a non-negative value if successful; otherwise returns a negative value. */ int H5Dataset_init(H5Dataset *d) { int ret_value=0, i=0; hsize_t dims[H5S_MAX_RANK]; hid_t did=-1, sid=-1, tid=-1, ftid=-1; unsigned int npoints; assert (d); H5Eclear(); if (d->space.rank > 0) goto done; /* already called */ if ( (did = H5Dopen(d->fid, d->fullpath)) < 0) THROW_H5LIBRARY_ERROR(d->error,ret_value, done); ftid = H5Dget_type(did); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); if ( ftid > 0) H5Tclose(ftid); d->tclass = d->type.tclass = (H5Datatype_class_t)H5Tget_class(tid); d->type.size = H5Tget_size(tid); if ( d->type.tclass == H5DATATYPE_INTEGER || d->type.tclass == H5DATATYPE_FLOAT || d->type.tclass == H5DATATYPE_BITFIELD || d->type.tclass == H5DATATYPE_REFERENCE || d->type.tclass == H5DATATYPE_ENUM ) { d->type.order = (H5Datatype_order_t)H5Tget_order(tid); if (d->type.tclass == H5DATATYPE_INTEGER) { d->type.sign = (H5Datatype_sign_t)H5Tget_sign(tid); /* check palette for image */ H5Dataset_readPalette(d, did); H5Dataset_check_image(d, did); } } else if (d->type.tclass == H5DATATYPE_COMPOUND) { d->type.nmembers = H5Tget_nmembers(tid ); d->type.mnames = (char **)malloc(d->type.nmembers*sizeof(char*)); d->type.mtypes = (int *)malloc(d->type.nmembers*sizeof(int)); for (i=0; i<d->type.nmembers; i++) { hid_t mtid = -1; int mtype = 0, mclass, msign, msize; d->type.mnames[i] = H5Tget_member_name(tid, i); mtid = H5Tget_member_type(tid, i); mclass = H5Tget_class(mtid); msign = H5Tget_sign(mtid); msize = H5Tget_size(mtid); mtype = mclass<<28 | msign<<24 | msize; d->type.mtypes[i] = mtype; H5Tclose(mtid); } } sid = H5Dget_space(did); d->space.rank = H5Sget_simple_extent_ndims(sid); if ( H5Sget_simple_extent_dims(sid, dims, NULL) < 0 ) THROW_H5LIBRARY_ERROR(d->error,ret_value, done); if (d->space.rank<=0) { d->space.rank = 1; dims[0] = 1; } npoints = 1; for (i=0; i<d->space.rank; i++) { d->space.dims[i] = dims[i]; d->space.start[i] = 0; d->space.stride[i] = 1; d->space.count[i] = dims[i]; npoints *= dims[i]; } d->space.npoints = npoints; done: if (sid > 0 ) H5Sclose(sid); if (tid > 0 ) H5Tclose(tid); if (did > 0 ) H5Dclose(did); return ret_value; }
std::string DataType::member_name(unsigned int index) const { char *data = H5Tget_member_name(hid, index); std::string res(data); std::free(data); return res; }
/* * test_compound * Test that compound datatypes can have UTF-8 field names. */ void test_compound(hid_t fid, const char * string) { /* Define two compound structures, s1_t and s2_t. * s2_t is a subset of s1_t, with two out of three * fields. * This is stolen from the h5_compound example. */ typedef struct s1_t { int a; double c; float b; } s1_t; typedef struct s2_t { double c; int a; } s2_t; /* Actual variable declarations */ s1_t s1; s2_t s2; hid_t s1_tid, s2_tid; hid_t space_id, dset_id; hsize_t dim = 1; char *readbuf; herr_t ret; /* Initialize compound data */ HDmemset(&s1, 0, sizeof(s1_t)); /* To make purify happy */ s1.a = COMP_INT_VAL; s1.c = COMP_DOUBLE_VAL; s1.b = COMP_FLOAT_VAL; /* Create compound datatypes using UTF-8 field name */ s1_tid = H5Tcreate (H5T_COMPOUND, sizeof(s1_t)); CHECK(s1_tid, FAIL, "H5Tcreate"); ret = H5Tinsert(s1_tid, string, HOFFSET(s1_t, a), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); /* Check that the field name was stored correctly */ readbuf = H5Tget_member_name(s1_tid, 0); ret = HDstrcmp(readbuf, string); VERIFY(ret, 0, "strcmp"); H5free_memory(readbuf); /* Add the other fields to the datatype */ ret = H5Tinsert(s1_tid, "c_name", HOFFSET(s1_t, c), H5T_NATIVE_DOUBLE); CHECK(ret, FAIL, "H5Tinsert"); ret = H5Tinsert(s1_tid, "b_name", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT); CHECK(ret, FAIL, "H5Tinsert"); /* Create second datatype, with only two fields. */ s2_tid = H5Tcreate (H5T_COMPOUND, sizeof(s2_t)); CHECK(s2_tid, FAIL, "H5Tcreate"); ret = H5Tinsert(s2_tid, "c_name", HOFFSET(s2_t, c), H5T_NATIVE_DOUBLE); CHECK(ret, FAIL, "H5Tinsert"); ret = H5Tinsert(s2_tid, string, HOFFSET(s2_t, a), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); /* Create the dataspace and dataset. */ space_id = H5Screate_simple(1, &dim, NULL); CHECK(space_id, FAIL, "H5Screate_simple"); dset_id = H5Dcreate2(fid, DSET4_NAME, s1_tid, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dset_id, FAIL, "H5Dcreate2"); /* Write data to the dataset. */ ret = H5Dwrite(dset_id, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &s1); CHECK(ret, FAIL, "H5Dwrite"); /* Ensure that data can be read back by field name into s2 struct */ ret = H5Dread(dset_id, s2_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &s2); CHECK(ret, FAIL, "H5Dread"); VERIFY(s2.a, COMP_INT_VAL, "H5Dread"); VERIFY(s2.c, COMP_DOUBLE_VAL, "H5Dread"); /* Clean up */ ret = H5Tclose(s1_tid); CHECK(ret, FAIL, "H5Tclose"); ret = H5Tclose(s2_tid); CHECK(ret, FAIL, "H5Tclose"); ret = H5Sclose(space_id); CHECK(ret, FAIL, "H5Sclose"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); }
int H5Attribute_init(H5Attribute *a, hid_t aid) { int ret_value=0, i=0; hsize_t dims[H5S_MAX_RANK]; hid_t sid=-1, tid=-1, ftid=-1; unsigned int npoints; if (NULL == a || aid < 0) { ret_value = -1; goto done; } if (a->space.rank > 0) goto done; /* already called */ ftid = H5Aget_type(aid); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); if (ftid > 0) H5Tclose(ftid); a->name = (char *)malloc(MAX_NAME_LEN); H5Aget_name(aid, MAX_NAME_LEN, a->name); a->tclass = a->type.tclass = (H5Datatype_class_t)H5Tget_class(tid); a->type.size = H5Tget_size(tid); if ( a->type.tclass == H5DATATYPE_INTEGER || a->type.tclass == H5DATATYPE_FLOAT || a->type.tclass == H5DATATYPE_BITFIELD || a->type.tclass == H5DATATYPE_REFERENCE || a->type.tclass == H5DATATYPE_ENUM ) { a->type.order = (H5Datatype_order_t)H5Tget_order(tid); if (a->type.tclass == H5DATATYPE_INTEGER) { a->type.sign = (H5Datatype_sign_t)H5Tget_sign(tid); } } else if (a->type.tclass == H5DATATYPE_COMPOUND) { a->type.nmembers = H5Tget_nmembers(tid ); a->type.mnames = (char **)malloc(a->type.nmembers*sizeof(char*)); a->type.mtypes = (int *)malloc(a->type.nmembers*sizeof(int)); for (i=0; i<a->type.nmembers; i++) { a->type.mnames[i] = H5Tget_member_name(tid, i); a->type.mtypes[i] = H5Tget_class(H5Tget_member_type(tid, i)); } } sid = H5Aget_space(aid); a->space.rank = H5Sget_simple_extent_ndims(sid); if ( H5Sget_simple_extent_dims(sid, dims, NULL) < 0 ) THROW_H5LIBRARY_ERROR(a->error,ret_value, done); if (a->space.rank<=0) { a->space.rank = 1; dims[0] = 1; } npoints = 1; for (i=0; i<a->space.rank; i++) { a->space.dims[i] = dims[i]; a->space.start[i] = 0; a->space.stride[i] = 1; a->space.count[i] = dims[i]; npoints *= dims[i]; } a->space.npoints = npoints; done: if (sid > 0 ) H5Sclose(sid); if (tid > 0 ) H5Tclose(tid); return ret_value; }
std::string CompoundType::memberName (size_t i) const { ASSERT (i <= std::numeric_limits<unsigned>::max ()); unsigned i2 = static_cast<unsigned> (i); Core::MallocRefHolder<char> result (HDF5::Exception::check ("H5Tget_member_name", H5Tget_member_name (handle (), i2))); return result.p; }
/*------------------------------------------------------------------------- * subroutine for test_text_dtype(): test_compound_bug(). Test case for * issue 7701. *------------------------------------------------------------------------- */ static int test_compound_bug(void) { hid_t dtype; H5T_class_t type_class; int nmembs; char* memb_name = NULL; char* dt_str; size_t str_len; char text[] = "H5T_COMPOUND { H5T_STD_I32LE \"state_________________________________________________________________________________\"; H5T_STD_I32LE \"desc_________________________________________________________________________________________\"; H5T_VLEN { H5T_COMPOUND { H5T_ENUM { H5T_STD_I16LE; \"ZERO\" 0; \"ONE\" 1; \"TWO\" 2; \"THREE\" 3; } \"type____\"; H5T_STD_I32LE \"sub_______________________________________________________________________________________________________________\"; H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_STR_SPACEPAD; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1; } \"sub_desc\"; H5T_STD_I32LE \"final___________________________________________________________________________________________________\"; } } \"sub\"; }"; char text2[] = "H5T_COMPOUND {\n" " H5T_STD_I16LE \"state___________________________" "__________________________________________________" "____\" : 0;\n" " H5T_STD_I16LE \"desc____________________________" "__________________________________________________" "___________\" : 2;\n" " H5T_VLEN { H5T_COMPOUND {\n" " H5T_ENUM { H5T_STD_I16LE; \"ZERO\" 0; \"ONE\" " "1; \"TWO\" 2; \"THREE\" 3; } \"type____\" : 0;\n" " H5T_STD_I32LE \"sub___________________________" "__________________________________________________" "__________________________________1\" : 4;\n" " H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_" "STR_SPACEPAD; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1;" " } \"sub_desc\" : 8;\n" " H5T_STD_I32LE \"final_________________________" "__________________________________________________" "________________________\" : 16;\n" " } } \"sub\" : 8;\n" "}\n"; TESTING3(" text for compound type of bug fix"); if((dtype = H5LTtext_to_dtype(text, H5LT_DDL))<0) goto out; if((type_class = H5Tget_class(dtype))<0) goto out; if(type_class != H5T_COMPOUND) goto out; if((memb_name = H5Tget_member_name(dtype, 2)) == NULL) goto out; if(strcmp(memb_name, "sub")) goto out; free(memb_name); if(H5LTdtype_to_text(dtype, NULL, H5LT_DDL, &str_len)<0) goto out; dt_str = (char*)calloc(str_len, sizeof(char)); if(H5LTdtype_to_text(dtype, dt_str, H5LT_DDL, &str_len)<0) goto out; free(dt_str); if(H5Tclose(dtype)<0) goto out; /* Test similar datatype in another format */ if((dtype = H5LTtext_to_dtype(text2, H5LT_DDL))<0) goto out; if((type_class = H5Tget_class(dtype))<0) goto out; if(type_class != H5T_COMPOUND) goto out; if((nmembs = H5Tget_nmembers(dtype))<0) goto out; if(nmembs != 3) goto out; if((memb_name = H5Tget_member_name(dtype, 1)) == NULL) goto out; if(strcmp(memb_name, "desc_________________________________________________________________________________________")) goto out; free(memb_name); if(H5LTdtype_to_text(dtype, NULL, H5LT_DDL, &str_len)<0) goto out; dt_str = (char*)calloc(str_len, sizeof(char)); if(H5LTdtype_to_text(dtype, dt_str, H5LT_DDL, &str_len)<0) goto out; free(dt_str); if(H5Tclose(dtype)<0) goto out; PASSED(); return 0; out: H5_FAILED(); return -1; }