size_t CompoundType::memberOffset (size_t i) const { ASSERT (i <= std::numeric_limits<unsigned>::max ()); unsigned i2 = static_cast<unsigned> (i); size_t result = H5Tget_member_offset (handle (), i2); if (result == 0) { // Check for errors, H5Tget_member_offset fails only if H5Tget_member_name also fails // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetMemberOffset memberName (i); } return result; }
/*------------------------------------------------------------------------- * Function: H5LD_construct_info() * * Purpose: Get the remaining info for a field: * 1) Get the type id of the last member in the field * 2) Get the total offset of all the members in the field * 3) Get the type size of the last member in the field * * Return: Success: 0 * Failure: negative * * Programmer: Vailin Choi; Aug 2010 * *------------------------------------------------------------------------- */ static herr_t H5LD_construct_info(H5LD_memb_t *memb, hid_t par_tid) { hid_t tmp_tid = -1; /* Dataset type id */ unsigned i; /* Local index variable */ herr_t ret_value = FAIL; /* Return value */ /* Make a copy of the incoming datatype */ tmp_tid = H5Tcopy(par_tid); /* Validate all the members in a field */ for(i = 0; memb->names[i] != NULL; i++) { hid_t memb_tid; /* Type id for a member in a field */ int idx; /* Index # of a member in a compound datatype */ /* Get the member index and member type id */ if((idx = H5Tget_member_index(tmp_tid, memb->names[i])) < 0) goto done; if((memb_tid = H5Tget_member_type(tmp_tid, (unsigned)idx)) < 0) goto done; /* Sum up the offset of all the members in the field */ memb->tot_offset += H5Tget_member_offset(tmp_tid, (unsigned)idx); if(H5Tclose(tmp_tid) < 0) goto done; tmp_tid = memb_tid; } /* end for */ /* Get the type size of the last member in the field */ memb->last_tsize = H5Tget_size(tmp_tid); /* Save the type id of the last member in the field */ memb->last_tid = H5Tcopy(tmp_tid); /* Indicate success */ ret_value = SUCCEED; done: H5E_BEGIN_TRY H5Tclose(tmp_tid); H5E_END_TRY return(ret_value); } /* H5LD_construct_info() */
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; }
size_t DataType::member_offset(unsigned int index) const { return H5Tget_member_offset(hid, index); }
//-------------------------------------------------------------------------- // Function: CompType::getMemberOffset ///\brief Returns the byte offset of the beginning of a member with /// respect to the beginning of the compound data type datum. ///\param member_num - IN: Zero-based index of the member ///\return Byte offset ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 // Description /// Members are stored in no particular order with numbers 0 /// through N-1, where N is the value returned by the member /// function \c CompType::getNmembers. // // Note that byte offset being returned as 0 doesn't indicate // a failure. (According to Quincey) //-------------------------------------------------------------------------- size_t CompType::getMemberOffset( unsigned member_num ) const { size_t offset = H5Tget_member_offset( id, member_num ); return( offset ); }