/* 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; }
unsigned int DataType::member_count() const { int res = H5Tget_nmembers(hid); if (res < 0) { throw H5Exception("DataType::member_count(): H5Tget_nmembers faild"); } return static_cast<unsigned int>(res); }
size_t getNestedSizeType(hid_t type_id) { hid_t member_type_id; H5T_class_t class_id; hsize_t i, nfields; size_t itemsize, offset; nfields = H5Tget_nmembers(type_id); offset = 0; // Iterate thru the members for (i=0; i < nfields; i++) { // Get the member type member_type_id = H5Tget_member_type(type_id, i); // Get the HDF5 class class_id = H5Tget_class(member_type_id); if (class_id == H5T_COMPOUND) { // Get the member size for compound type itemsize = getNestedSizeType(member_type_id); } else { // Get the atomic member size itemsize = H5Tget_size(member_type_id); } // Update the offset offset = offset + itemsize; } return(offset); }
/*------------------------------------------------------------------------- * 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::getNmembers ///\brief Returns the number of members in this compound datatype. ///\return Number of members ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- int CompType::getNmembers() const { int num_members = H5Tget_nmembers( id ); if( num_members < 0 ) { throw DataTypeIException("CompType::getNmembers", "H5Tget_nmembers returns negative number of members"); } return( num_members ); }
/** This method gets the length (i.e., number of fields in the case of * uniform records and number of bytes for non_uniform ones) of the * record. */ int miget_record_length(mihandle_t volume, int *length) { if (volume == NULL || length == NULL) { return (MI_ERROR); } if (volume->volume_class == MI_CLASS_UNIFORM_RECORD || volume->volume_class == MI_CLASS_NON_UNIFORM_RECORD) { *length = H5Tget_nmembers(volume->ftype_id); return (MI_NOERROR); } return (MI_ERROR); }
/* * Class: hdf_hdf5lib_H5 * Method: H5AreadVL * Signature: (JJJJJ[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL (JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { herr_t status = -1; htri_t isStr = 0; htri_t isVlenStr = 0; htri_t isComplex = 0; if (buf == NULL) { h5nullArgument(env, "H5AreadVL: buf is NULL"); } /* end if */ else { isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING); if (H5Tget_class((hid_t)mem_type_id) == H5T_COMPOUND) { unsigned i; int nm = H5Tget_nmembers(mem_type_id); for(i = 0; i <nm; i++) { hid_t nested_tid = H5Tget_member_type((hid_t)mem_type_id, i); isComplex = H5Tdetect_class((hid_t)nested_tid, H5T_COMPOUND) || H5Tdetect_class((hid_t)nested_tid, H5T_VLEN); H5Tclose(nested_tid); } } else if (H5Tget_class((hid_t)mem_type_id) == H5T_VLEN) { isVlenStr = 1; /* strings created by H5Tvlen_create(H5T_C_S1) */ } if (isStr == 0 || isComplex>0 || isVlenStr) { status = H5AreadVL_asstr(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); } else if (isStr > 0) { status = H5AreadVL_str(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); } } /* end else */ return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Aread_1VL */
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); } }
/*------------------------------------------------------------------------- * subroutine for test_text_dtype(): test_complicated_compound(). *------------------------------------------------------------------------- */ static int test_complicated_compound(void) { hid_t dtype; int nmembs; H5T_class_t type_class; char* line=NULL; FILE *fp; size_t size = 1024; char *srcdir = getenv("srcdir"); /* the source directory */ char filename[1024]=""; TESTING3(" text for complicated compound types"); /* compose the name of the file to open, using the srcdir, if appropriate */ if(srcdir) { strcpy(filename, srcdir); strcat(filename, "/"); } strcat(filename, INPUT_FILE); /* Open input file */ fp = fopen(filename, "r"); if(fp == NULL) { printf( "Could not find file %s. Try set $srcdir \n", filename); goto out; } /* This part reads in the input as a string in a slow manner. GNU C * Library has convenient function getline() but isn't available on * all machines. */ if((line = (char*)calloc(size, sizeof(char)))==NULL) goto out; if(fgets(line, (int)size, fp)==NULL) goto out; while(strlen(line)==size-1) { size *= 2; if(line) free(line); if((line = (char*)calloc(size, sizeof(char)))==NULL) goto out; if(fseek(fp, 0L, SEEK_SET)!=0) goto out; if(fgets(line, (int)size, fp)==NULL) goto out; } fclose(fp); if((dtype = H5LTtext_to_dtype(line, H5LT_DDL))<0) goto out; if((type_class = H5Tget_class(dtype))<0) goto out; if(type_class != H5T_COMPOUND) goto out; /* There should be 101 compound members */ if((nmembs = H5Tget_nmembers(dtype))<0) goto out; if(nmembs != 101) goto out; if(line) free(line); PASSED(); return 0; out: H5_FAILED(); return -1; }
size_t CompoundType::nMembers () const { return Exception::check ("H5Tget_nmembers", H5Tget_nmembers (handle ())); }
/* 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; }
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; }
/*------------------------------------------------------------------------- * Function: copy_attr * * Purpose: copy attributes located in LOC_IN, which is obtained either from * loc_id = H5Gopen2( fid, name); * loc_id = H5Dopen2( fid, name); * loc_id = H5Topen2( fid, name); * * Return: 0, ok, -1 no *------------------------------------------------------------------------- */ int copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options) { int ret_value = 0; hid_t attr_id = -1; /* attr ID */ hid_t attr_out = -1; /* attr ID */ hid_t space_id = -1; /* space ID */ hid_t ftype_id = -1; /* file type ID */ hid_t wtype_id = -1; /* read/write type ID */ size_t msize; /* size of type */ void *buf = NULL; /* data buffer */ hsize_t nelmts; /* number of elements in dataset */ int rank; /* rank of dataset */ htri_t is_named; /* Whether the datatype is named */ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */ char name[255]; H5O_info_t oinfo; /* object info */ int j; unsigned u; hbool_t is_ref = 0; H5T_class_t type_class = -1; if (H5Oget_info(loc_in, &oinfo) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Oget_info failed"); /*------------------------------------------------------------------------- * copy all attributes *------------------------------------------------------------------------- */ for (u = 0; u < (unsigned) oinfo.num_attrs; u++) { /* open attribute */ if ((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t) u, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aopen_by_idx failed"); /* get name */ if (H5Aget_name(attr_id, (size_t) 255, name) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed"); /* get the file datatype */ if ((ftype_id = H5Aget_type(attr_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_type failed"); /* Check if the datatype is committed */ if ((is_named = H5Tcommitted(ftype_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcommitted failed"); if (is_named && travt) { hid_t fidout = -1; /* Create out file id */ if ((fidout = H5Iget_file_id(loc_out)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Iget_file_id failed"); /* Copy named dt */ if ((wtype_id = copy_named_datatype(ftype_id, fidout, named_dt_head_p, travt, options)) < 0) { H5Fclose(fidout); HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_named_datatype failed"); } /* end if */ if (H5Fclose(fidout) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fclose failed"); } /* end if */ else { if (options->use_native == 1) wtype_id = H5Tget_native_type(ftype_id, H5T_DIR_DEFAULT); else wtype_id = H5Tcopy(ftype_id); } /* end else */ /* get the dataspace handle */ if ((space_id = H5Aget_space(attr_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_space failed"); /* get dimensions */ if ((rank = H5Sget_simple_extent_dims(space_id, dims, NULL)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); nelmts = 1; for (j = 0; j < rank; j++) nelmts *= dims[j]; if ((msize = H5Tget_size(wtype_id)) == 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); /*------------------------------------------------------------------------- * object references are a special case. We cannot just copy the buffers, * but instead we recreate the reference. * This is done on a second sweep of the file that just copies the referenced * objects at copy_refs_attr() *------------------------------------------------------------------------- */ type_class = H5Tget_class(wtype_id); is_ref = (type_class == H5T_REFERENCE); if (type_class == H5T_VLEN || type_class == H5T_ARRAY) { hid_t base_type = -1; base_type = H5Tget_super(ftype_id); is_ref = (is_ref || (H5Tget_class(base_type) == H5T_REFERENCE)); if (H5Tclose(base_type) < 0) H5TOOLS_INFO(H5E_tools_min_id_g, "H5Tclose base_type failed"); } if (type_class == H5T_COMPOUND) { int nmembers = H5Tget_nmembers(wtype_id); for (j = 0; j < nmembers; j++) { hid_t mtid = H5Tget_member_type(wtype_id, (unsigned)j); H5T_class_t mtclass = H5Tget_class(mtid); if (H5Tclose(mtid) < 0) H5TOOLS_INFO(H5E_tools_min_id_g, "H5Tclose mtid failed"); if (mtclass == H5T_REFERENCE) { is_ref = 1; break; } } /* for (j=0; i<nmembers; j++) */ } /* if (type_class == H5T_COMPOUND) */ if (!is_ref) { /*------------------------------------------------------------------------- * read to memory *------------------------------------------------------------------------- */ buf = (void *)HDmalloc((size_t)(nelmts * msize)); if (buf == NULL) { HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed"); } /* end if */ if (H5Aread(attr_id, wtype_id, buf) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed"); /*------------------------------------------------------------------------- * copy *------------------------------------------------------------------------- */ if ((attr_out = H5Acreate2(loc_out, name, wtype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Acreate2 failed on ,%s>", name); if (H5Awrite(attr_out, wtype_id, buf) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed"); /*close*/ if (H5Aclose(attr_out) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed"); /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); HDfree(buf); buf = NULL; } /*H5T_REFERENCE*/ if (options->verbose) printf(FORMAT_OBJ_ATTR, "attr", name); /*------------------------------------------------------------------------- * close *------------------------------------------------------------------------- */ if (H5Sclose(space_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed"); space_id = -1; if (H5Tclose(wtype_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); wtype_id = -1; if (H5Tclose(ftype_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); ftype_id = -1; if (H5Aclose(attr_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed"); attr_id = -1; } /* for u */ done: H5E_BEGIN_TRY { if (buf) { /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); /* Free buf */ HDfree(buf); } /* end if */ H5Aclose(attr_out); H5Sclose(space_id); H5Tclose(wtype_id); H5Tclose(ftype_id); H5Aclose(attr_id); } H5E_END_TRY; return ret_value; } /* end copy_attr() */
int diff_can_type( hid_t f_tid1, /* file data type */ hid_t f_tid2, /* file data type */ int rank1, int rank2, hsize_t *dims1, hsize_t *dims2, hsize_t *maxdim1, hsize_t *maxdim2, const char *obj1_name, const char *obj2_name, diff_opt_t *options, int is_compound) { H5T_class_t tclass1; H5T_class_t tclass2; int maxdim_diff=0; /* maximum dimensions are different */ int dim_diff=0; /* current dimensions are different */ int i; int can_compare = 1; /* return value */ /*------------------------------------------------------------------------- * check for the same class *------------------------------------------------------------------------- */ if ((tclass1=H5Tget_class(f_tid1)) < 0) return -1; if ((tclass2=H5Tget_class(f_tid2)) < 0) return -1; if ( tclass1 != tclass2 ) { if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { if ( is_compound ) { parallel_print("Not comparable: <%s> has a class %s and <%s> has a class %s\n", obj1_name, get_class(tclass1), obj2_name, get_class(tclass2) ); } else { parallel_print("Not comparable: <%s> is of class %s and <%s> is of class %s\n", obj1_name, get_class(tclass1), obj2_name, get_class(tclass2) ); } } can_compare = 0; options->not_cmp = 1; return can_compare; } /*------------------------------------------------------------------------- * check for non supported classes *------------------------------------------------------------------------- */ HDassert(tclass1==tclass2); switch (tclass1) { case H5T_INTEGER: case H5T_FLOAT: case H5T_COMPOUND: case H5T_STRING: case H5T_ARRAY: case H5T_BITFIELD: case H5T_OPAQUE: case H5T_ENUM: case H5T_VLEN: case H5T_REFERENCE: break; default: /*H5T_TIME */ if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { parallel_print("Not comparable: <%s> and <%s> are of class %s\n", obj1_name,obj2_name,get_class(tclass2) ); } can_compare = 0; options->not_cmp = 1; return can_compare; } /*------------------------------------------------------------------------- * check for equal file datatype; warning only *------------------------------------------------------------------------- */ if ( (H5Tequal(f_tid1, f_tid2)==0) && (options->m_verbose) && obj1_name && obj2_name) { H5T_class_t cl = H5Tget_class(f_tid1); parallel_print("Warning: different storage datatype\n"); if ( cl == H5T_INTEGER || cl == H5T_FLOAT ) { parallel_print("<%s> has file datatype ", obj1_name); print_type(f_tid1); parallel_print("\n"); parallel_print("<%s> has file datatype ", obj2_name); print_type(f_tid2); parallel_print("\n"); } } /*------------------------------------------------------------------------- * check for the same rank *------------------------------------------------------------------------- */ if ( rank1 != rank2 ) { if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { parallel_print("Not comparable: <%s> has rank %d, dimensions ", obj1_name, rank1); print_dimensions(rank1,dims1); parallel_print(", max dimensions "); print_dimensions(rank1,maxdim1); parallel_print("\n" ); parallel_print("and <%s> has rank %d, dimensions ", obj2_name, rank2); print_dimensions(rank2,dims2); parallel_print(", max dimensions "); print_dimensions(rank2,maxdim2); parallel_print("\n"); } can_compare = 0; options->not_cmp = 1; return can_compare; } /*------------------------------------------------------------------------- * check for different dimensions *------------------------------------------------------------------------- */ HDassert(rank1==rank2); for ( i=0; i<rank1; i++) { if (maxdim1 && maxdim2) { if ( maxdim1[i] != maxdim2[i] ) maxdim_diff=1; } if ( dims1[i] != dims2[i] ) dim_diff=1; } /*------------------------------------------------------------------------- * current dimensions *------------------------------------------------------------------------- */ if (dim_diff==1) { if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { parallel_print("Not comparable: <%s> has rank %d, dimensions ", obj1_name, rank1); print_dimensions(rank1,dims1); if (maxdim1 && maxdim2) { parallel_print(", max dimensions "); print_dimensions(rank1,maxdim1); parallel_print("\n" ); parallel_print("and <%s> has rank %d, dimensions ", obj2_name, rank2); print_dimensions(rank2,dims2); parallel_print(", max dimensions "); print_dimensions(rank2,maxdim2); parallel_print("\n"); } } can_compare = 0; options->not_cmp = 1; return can_compare; } /*------------------------------------------------------------------------- * maximum dimensions; just give a warning *------------------------------------------------------------------------- */ if (maxdim1 && maxdim2 && maxdim_diff==1 && obj1_name ) { if (options->m_verbose) { parallel_print( "Warning: different maximum dimensions\n"); parallel_print("<%s> has max dimensions ", obj1_name); print_dimensions(rank1,maxdim1); parallel_print("\n"); parallel_print("<%s> has max dimensions ", obj2_name); print_dimensions(rank2,maxdim2); parallel_print("\n"); } } if ( tclass1 == H5T_COMPOUND ) { int nmembs1; int nmembs2; int j; hid_t memb_type1; hid_t memb_type2; nmembs1 = H5Tget_nmembers(f_tid1); nmembs2 = H5Tget_nmembers(f_tid2); if ( nmembs1 != nmembs2 ) { if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { parallel_print("Not comparable: <%s> has %d members ", obj1_name, nmembs1); parallel_print("<%s> has %d members ", obj2_name, nmembs2); parallel_print("\n"); } can_compare = 0; options->not_cmp = 1; return can_compare; } for (j = 0; j < nmembs1; j++) { memb_type1 = H5Tget_member_type(f_tid1, (unsigned)j); memb_type2 = H5Tget_member_type(f_tid2, (unsigned)j); if (diff_can_type(memb_type1, memb_type2, rank1, rank2, dims1, dims2, maxdim1, maxdim2, obj1_name, obj2_name, options, 1)!=1) { can_compare = 0; options->not_cmp = 1; H5Tclose(memb_type1); H5Tclose(memb_type2); return can_compare; } H5Tclose(memb_type1); H5Tclose(memb_type2); } } return can_compare; }
GDALDataType HDF5Dataset::GetDataType(hid_t TypeID) { //Check for native types first if (H5Tget_class(TypeID) != H5T_COMPOUND) { if( H5Tequal(H5T_NATIVE_CHAR, TypeID) ) return GDT_Byte; else if( H5Tequal(H5T_NATIVE_SCHAR, TypeID) ) return GDT_Byte; else if( H5Tequal(H5T_NATIVE_UCHAR, TypeID) ) return GDT_Byte; else if( H5Tequal(H5T_NATIVE_SHORT, TypeID) ) return GDT_Int16; else if( H5Tequal(H5T_NATIVE_USHORT, TypeID) ) return GDT_UInt16; else if( H5Tequal(H5T_NATIVE_INT, TypeID) ) return GDT_Int32; else if( H5Tequal(H5T_NATIVE_UINT, TypeID) ) return GDT_UInt32; else if( H5Tequal(H5T_NATIVE_LONG, TypeID) ) { #if SIZEOF_UNSIGNED_LONG == 4 return GDT_Int32; #else return GDT_Unknown; #endif } else if( H5Tequal(H5T_NATIVE_ULONG, TypeID) ) { #if SIZEOF_UNSIGNED_LONG == 4 return GDT_UInt32; #else return GDT_Unknown; #endif } else if( H5Tequal(H5T_NATIVE_FLOAT, TypeID) ) return GDT_Float32; else if( H5Tequal(H5T_NATIVE_DOUBLE, TypeID) ) return GDT_Float64; else if( H5Tequal(H5T_NATIVE_LLONG, TypeID) ) return GDT_Unknown; else if( H5Tequal(H5T_NATIVE_ULLONG, TypeID) ) return GDT_Unknown; else if( H5Tequal(H5T_NATIVE_DOUBLE, TypeID) ) return GDT_Unknown; } else //Parse compound type to determine if data is complex { //For complex the compound type must contain 2 elements if ( H5Tget_nmembers(TypeID) != 2 ) return GDT_Unknown; //For complex the native types of both elements should be the same if ( H5Tequal( H5Tget_member_type(TypeID,0), H5Tget_member_type(TypeID,1)) <= 0 ) return GDT_Unknown; //Check the native types to determine CInt16, CFloat32 or CFloat64 hid_t ElemTypeID = H5Tget_member_type(TypeID, 0); GDALDataType eDataType = GDT_Unknown; if ( H5Tequal(H5T_NATIVE_SHORT, ElemTypeID) ) eDataType = GDT_CInt16; else if ( H5Tequal(H5T_NATIVE_INT, ElemTypeID) ) eDataType = GDT_CInt32; else if ( H5Tequal(H5T_NATIVE_LONG, ElemTypeID) ) { #if SIZEOF_UNSIGNED_LONG == 4 eDataType = GDT_CInt32; #else eDataType = GDT_Unknown; #endif } else if ( H5Tequal(H5T_NATIVE_FLOAT, ElemTypeID) ) eDataType = GDT_CFloat32; else if ( H5Tequal(H5T_NATIVE_DOUBLE, ElemTypeID) ) eDataType = GDT_CFloat64; //Close the data type H5Tclose(ElemTypeID); return eDataType; } return GDT_Unknown; }
/*------------------------------------------------------------------------- * 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; }
const char *HDF5Dataset::GetDataTypeName(hid_t TypeID) { //Check for native types first if (H5Tget_class(TypeID) != H5T_COMPOUND) { if( H5Tequal(H5T_NATIVE_CHAR, TypeID) ) return "8-bit character"; else if( H5Tequal(H5T_NATIVE_SCHAR, TypeID) ) return "8-bit signed character"; else if( H5Tequal(H5T_NATIVE_UCHAR, TypeID) ) return "8-bit unsigned character"; else if( H5Tequal(H5T_NATIVE_SHORT, TypeID) ) return "16-bit integer"; else if( H5Tequal(H5T_NATIVE_USHORT, TypeID) ) return "16-bit unsigned integer"; else if( H5Tequal(H5T_NATIVE_INT, TypeID) ) return "32-bit integer"; else if( H5Tequal(H5T_NATIVE_UINT, TypeID) ) return "32-bit unsigned integer"; else if( H5Tequal(H5T_NATIVE_LONG, TypeID) ) return "32/64-bit integer"; else if( H5Tequal(H5T_NATIVE_ULONG, TypeID) ) return "32/64-bit unsigned integer"; else if( H5Tequal(H5T_NATIVE_FLOAT, TypeID) ) return "32-bit floating-point"; else if( H5Tequal(H5T_NATIVE_DOUBLE, TypeID) ) return "64-bit floating-point"; else if( H5Tequal(H5T_NATIVE_LLONG, TypeID) ) return "64-bit integer"; else if( H5Tequal(H5T_NATIVE_ULLONG, TypeID) ) return "64-bit unsigned integer"; else if( H5Tequal(H5T_NATIVE_DOUBLE, TypeID) ) return "64-bit floating-point"; } else { //For complex the compound type must contain 2 elements if ( H5Tget_nmembers(TypeID) != 2 ) return "Unknown"; //For complex the native types of both elements should be the same if ( H5Tequal( H5Tget_member_type(TypeID,0), H5Tget_member_type(TypeID,1)) <= 0 ) return "Unknown"; //Check the native types to determine CInt16, CFloat32 or CFloat64 hid_t ElemTypeID = H5Tget_member_type(TypeID, 0); if ( H5Tequal(H5T_NATIVE_SHORT, ElemTypeID) ) { H5Tclose(ElemTypeID); return "complex, 16-bit integer"; } else if ( H5Tequal(H5T_NATIVE_INT, ElemTypeID) ) { H5Tclose(ElemTypeID); return "complex, 32-bit integer"; } else if ( H5Tequal(H5T_NATIVE_LONG, ElemTypeID) ) { H5Tclose(ElemTypeID); return "complex, 32/64-bit integer"; } else if ( H5Tequal(H5T_NATIVE_FLOAT, ElemTypeID) ) { H5Tclose(ElemTypeID); return "complex, 32-bit floating-point"; } else if ( H5Tequal(H5T_NATIVE_DOUBLE, ElemTypeID) ) { H5Tclose(ElemTypeID); return "complex, 64-bit floating-point"; } } return "Unknown"; }