diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2003-06-10 21:04:58 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2003-06-10 21:04:58 (GMT) |
commit | 67449f5c65efa0b1b2d17288a2387259ccd651d2 (patch) | |
tree | 3a92ecb1e88510650275f8d47e5c2283b75a4ca3 | |
parent | b6f348df6ea4bd829f8f2bf249d8fad5a6691bf0 (diff) | |
download | hdf5-67449f5c65efa0b1b2d17288a2387259ccd651d2.zip hdf5-67449f5c65efa0b1b2d17288a2387259ccd651d2.tar.gz hdf5-67449f5c65efa0b1b2d17288a2387259ccd651d2.tar.bz2 |
[svn-r7021] Purpose: bug fix
Description: H5Tget_native_type fails for multiple kinds of datatype on Cray; it fails
fix-length string type, too.
Platforms tested: Cray, h5committest
-rw-r--r-- | src/H5Tconv.c | 21 | ||||
-rw-r--r-- | src/H5Tnative.c | 41 | ||||
-rw-r--r-- | test/dtypes.c | 88 | ||||
-rw-r--r-- | test/ntypes.c | 311 | ||||
-rw-r--r-- | tools/h5ls/h5ls.c | 6 |
5 files changed, 400 insertions, 67 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 13a6737..92f6fa3 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1885,12 +1885,12 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) H5MM_xfree(priv->src2dst); priv->src2dst = map; HGOTO_DONE(SUCCEED); - } else { - /* Sort source type by value and adjust src2dst[] appropriately */ - H5T_sort_value(src, priv->src2dst); } } + /* Sort source type by value and adjust src2dst[] appropriately */ + H5T_sort_value(src, priv->src2dst); + done: if (ret_value<0 && priv) { H5MM_xfree(priv->src2dst); @@ -1976,15 +1976,12 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, assert (H5T_ENUM==src->type); assert (H5T_ENUM==dst->type); - if (priv->length) { - /* Use O(1) lookup */ - H5T_sort_name(src, NULL); - H5T_sort_name(dst, NULL); - } else { - /* Use O(log N) lookup */ - H5T_sort_value(src, NULL); /*yes, by value*/ - H5T_sort_name(dst, NULL); /*yes, by name*/ - } + /* priv->src2dst map was computed for certain sort keys. Make sure those same + * sort keys are used here during conversion. See H5T_conv_enum_init(). But + * we actually don't care about the source type's order when doing the O(1) + * conversion algorithm, which is turned on by non-zero priv->length */ + H5T_sort_name(dst, NULL); + if (!priv->length) H5T_sort_value(src, NULL); /* * Direction of conversion. diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 3cd6789..4516ddd 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -22,6 +22,7 @@ #include "H5private.h" /*generic functions */ #include "H5Eprivate.h" /*error handling */ #include "H5Iprivate.h" /*ID functions */ +#include "H5Pprivate.h" /*property list */ #include "H5MMprivate.h" /*memory management */ #include "H5Tpkg.h" /*data-type functions */ @@ -212,9 +213,7 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); } else { - /*size_t char_size;*/ - - if(NULL==(dt=H5I_object(H5T_NATIVE_UCHAR))) + if(NULL==(dt=H5I_object(H5T_C_S1))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); @@ -346,8 +345,9 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig case H5T_ENUM: { char *memb_name; /* Enum's member name */ - void *memb_value; /* Enum's member value */ - + void *memb_value, *tmp_memb_value; /* Enum's member value */ + hid_t super_type_id, nat_super_type_id; + /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer. */ /* Retrieve base type for enumarate type */ @@ -356,14 +356,17 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed"); + if((super_type_id=H5I_register(H5I_DATATYPE, super_type))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype"); + if((nat_super_type_id=H5I_register(H5I_DATATYPE, nat_super_type))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype"); + /* Allocate room for the enum values */ - if((memb_value = H5MM_malloc(H5T_get_size(super_type)))==NULL) + if((tmp_memb_value = H5MM_calloc(H5T_get_size(super_type)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + if((memb_value = H5MM_calloc(H5T_get_size(nat_super_type)))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - /* Close super type */ - if(H5T_close(super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - /* Construct new enum type based on native type */ if((new_type=H5T_enum_create(nat_super_type))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type"); @@ -374,18 +377,27 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig for(i=0; i<nmemb; i++) { if((memb_name=H5T_get_member_name(dtype, i))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name"); - if(H5T_get_member_value(dtype, i, memb_value)<0) + if(H5T_get_member_value(dtype, i, tmp_memb_value)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value"); + HDmemcpy(memb_value, tmp_memb_value, H5T_get_size(super_type)); + + if(H5Tconvert(super_type_id, nat_super_type_id, 1, memb_value, NULL, H5P_DEFAULT)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value"); + if(H5T_enum_insert(new_type, memb_name, memb_value)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member"); H5MM_xfree(memb_name); } H5MM_xfree(memb_value); + H5MM_xfree(tmp_memb_value); /* Close base type */ - if(H5T_close(nat_super_type)<0) + if(H5Tclose(nat_super_type_id)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - + /* Close super type */ + if(H5Tclose(super_type_id)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + ret_value = new_type; } break; @@ -584,9 +596,8 @@ H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t direction, case H5T_NATIVE_INT_MATCH_SHORT: if(sign==H5T_SGN_2) tid = H5T_NATIVE_SHORT; - else + else tid = H5T_NATIVE_USHORT; - align = H5T_NATIVE_SHORT_COMP_ALIGN_g; break; diff --git a/test/dtypes.c b/test/dtypes.c index 8693422..f312909 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -2048,6 +2048,93 @@ test_conv_enum_1(void) /*------------------------------------------------------------------------- + * Function: test_conv_enum_2 + * + * Purpose: Tests enumeration conversions where source isn't a native type. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Robb Matzke, LLNL, 2003-06-09 + * + * Modifications: + *------------------------------------------------------------------------- + */ +static int +test_conv_enum_2(void) +{ + hid_t srctype=-1, dsttype=-1, oddsize=-1; + int *data=NULL, i, nerrors=0; + const char *mname[] = { "RED", + "GREEN", + "BLUE", + "YELLOW", + "PINK", + "PURPLE", + "ORANGE", + "WHITE" }; + + TESTING("non-native enumeration type conversion"); + + /* Source enum type */ + oddsize = H5Tcopy(H5T_STD_I32BE); + H5Tset_size(oddsize, 3); /*reduce to 24 bits, not corresponding to any native size*/ + srctype = H5Tenum_create(oddsize); + for (i=7; i>=0; --i) { + char pattern[3]; + pattern[2] = i; + pattern[0] = pattern[1] = 0; + H5Tenum_insert(srctype, mname[i], pattern); + } + + /* Destination enum type */ + dsttype = H5Tenum_create(H5T_NATIVE_INT); + assert(H5Tget_size(dsttype)>H5Tget_size(srctype)); + for (i=0; i<8; i++) + H5Tenum_insert(dsttype, mname[i], &i); + + /* Source data */ + data = malloc(NTESTELEM*sizeof(int)); + for (i=0; i<NTESTELEM; i++) { + ((char*)data)[i*3+2] = i % 8; + ((char*)data)[i*3+0] = 0; + ((char*)data)[i*3+1] = 0; + } + + /* Convert to destination type */ + H5Tconvert(srctype, dsttype, (hsize_t)NTESTELEM, data, NULL, H5P_DEFAULT); + + /* Check results */ + for (i=0; i<NTESTELEM; i++) { + if (data[i] != i%8) { + if (!nerrors++) { + H5_FAILED(); + printf("element %d is %d but should have been %d\n", + i, data[i], i%8); + } + } + } + + /* Cleanup */ + free(data); + H5Tclose(srctype); + H5Tclose(dsttype); + H5Tclose(oddsize); + + /* Failure */ + if (nerrors) { + printf("total of %d conversion errors out of %d elements for enums\n", + nerrors, NTESTELEM); + return 1; + } + + PASSED(); + return 0; +} + + +/*------------------------------------------------------------------------- * Function: test_conv_bitfield * * Purpose: Test bitfield conversions. @@ -4146,6 +4233,7 @@ main(void) nerrors += test_compound_7(); nerrors += test_conv_int (); nerrors += test_conv_enum_1(); + nerrors += test_conv_enum_2(); nerrors += test_conv_bitfield(); nerrors += test_opaque(); diff --git a/test/ntypes.c b/test/ntypes.c index 53276a2..16d31de 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -43,6 +43,7 @@ int ipoints3[100][200][5], icheck3[100][200][5]; #define DSET_ARRAY2_NAME "array_type_2" #define DSET_VL_NAME "vl_type" #define DSET_VLSTR_NAME "vlstr_type" +#define DSET_STR_NAME "str_type" #define DSET_OPAQUE_NAME "opaque_type" #define DSET_BITFIELD_NAME "bitfield_type" @@ -277,12 +278,13 @@ test_compound_dtype2(hid_t file) unsigned long_long l; } s1; hid_t dataset, space; - hid_t dtype, native_type, tid, tid2, tid_m, tid_m2; + hid_t dtype, native_type, tid, tid2, tid_m, tid_m2, + mem_id, nest_mem_id; int i, j, n; hsize_t dims[2]; s1 *temp_point, *temp_check; s1 *points=NULL, *check=NULL; - void *tmp; + void *tmp, *bkg; TESTING("nested compound datatype"); @@ -375,14 +377,74 @@ test_compound_dtype2(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - if(H5Tget_size(native_type) != H5Tget_size(tid_m)) + /* Verify the datatype of each field retrieved and converted */ + /* check the char member */ + if((mem_id = H5Tget_member_type(native_type, 0))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_UCHAR)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_U8LE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + + /* check the integer member */ + if((mem_id = H5Tget_member_type(native_type, 1))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_INT)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I32LE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + + /* check the long long member */ + if((mem_id = H5Tget_member_type(native_type, 3))<0) TEST_ERROR; - if(!H5Tequal(native_type, tid_m)) + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_ULLONG)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_U64BE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + + /* check the nested compound member */ + if((nest_mem_id = H5Tget_member_type(native_type, 2))<0) TEST_ERROR; + if((mem_id = H5Tget_member_type(nest_mem_id, 0))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_SHORT)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I16BE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + + if((mem_id = H5Tget_member_type(nest_mem_id, 1))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_LONG)) + TEST_ERROR; +#if H5_SIZEOF_LONG==4 + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I32LE)) TEST_ERROR; +#elif H5_SIZEOF_LONG==8 + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I64LE)) TEST_ERROR; +#else +#error "Unknown 'long' size" +#endif + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(dims[0]*dims[1]*H5Tget_size(native_type)); + if((bkg=calloc(sizeof(s1),dims[0]*dims[1]))==NULL) + TEST_ERROR; if (H5Dread(dataset, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp)<0) TEST_ERROR; @@ -390,9 +452,11 @@ test_compound_dtype2(hid_t file) memcpy(check, tmp, dims[0]*dims[1]*H5Tget_size(native_type)); free(tmp); - if (H5Tconvert(native_type, tid_m, dims[0]*dims[1], check, NULL, H5P_DEFAULT)) + if (H5Tconvert(native_type, tid_m, dims[0]*dims[1], check, bkg, H5P_DEFAULT)) TEST_ERROR; + free(bkg); + /* Check that the values read are the same as the values written */ for (i = 0, temp_point=points, temp_check=check; i < 100; i++) { for (j = 0; j < 200; j++, temp_point++,temp_check++) { @@ -461,12 +525,12 @@ test_compound_dtype(hid_t file) long_long l; } s1; hid_t dataset, space; - hid_t dtype, native_type, tid, tid2; + hid_t dtype, native_type, tid, tid2, mem_id; int i, j, n; hsize_t dims[2]; s1 *temp_point, *temp_check; s1 *points, *check; - void *tmp; + void *tmp, *bkg; TESTING("compound datatype"); @@ -527,15 +591,42 @@ test_compound_dtype(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; + + /* Verify the datatype of each field retrieved and converted */ + if((mem_id = H5Tget_member_type(native_type, 0))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_UCHAR)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_U8LE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + + if((mem_id = H5Tget_member_type(native_type, 1))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_UINT)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_U32LE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); - if(H5Tget_size(native_type) < H5Tget_size(tid2)) + if((mem_id = H5Tget_member_type(native_type, 2))<0) TEST_ERROR; - if(!H5Tequal(native_type, tid2)) + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_LLONG)) TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I64BE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(dims[0]*dims[1]*H5Tget_size(native_type)); + bkg = calloc(sizeof(s1),dims[0]*dims[1]); if (H5Dread(dataset, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp)<0) TEST_ERROR; @@ -543,9 +634,11 @@ test_compound_dtype(hid_t file) memcpy(check, tmp, dims[0]*dims[1]*H5Tget_size(native_type)); free(tmp); - if (H5Tconvert(native_type, tid2, dims[0]*dims[1], check, NULL, H5P_DEFAULT)<0) + if (H5Tconvert(native_type, tid2, dims[0]*dims[1], check, bkg, H5P_DEFAULT)<0) TEST_ERROR; + free(bkg); + /* Check that the values read are the same as the values written */ for (i = 0, temp_point=points, temp_check=check; i < 100; i++) { for (j = 0; j < 200; j++, temp_point++,temp_check++) { @@ -605,15 +698,16 @@ test_compound_dtype3(hid_t file) long_long l; } s1; hid_t dataset, space; - hid_t dtype, native_type, tid, tid2, tid_m, tid_m2; + hid_t dtype, native_type, tid, tid2, tid_m, tid_m2, + mem_id, nest_mem_id; hsize_t array_dims[1]={5}; int i, j, k, n; hsize_t dims[2]; s1 *temp_point, *temp_check; s1 *points=NULL, *check=NULL; - void *tmp; + void *tmp, *bkg; - TESTING("compound datatype"); + TESTING("compound datatype with array as field"); /* Allocate space for the points & check arrays */ if((points=malloc(sizeof(s1)*100*200))==NULL) @@ -682,25 +776,47 @@ test_compound_dtype3(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; + + /* Verify the datatype of each field retrieved and converted */ + /* check the char member */ + if((mem_id = H5Tget_member_type(native_type, 0))<0) + TEST_ERROR; + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_UCHAR)) + TEST_ERROR; + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_U8LE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); - if(H5Tget_size(native_type) != H5Tget_size(tid_m)) + /* check the long long member */ + if((mem_id = H5Tget_member_type(native_type, 2))<0) TEST_ERROR; - if(!H5Tequal(native_type, tid_m)) + if(H5Tget_order(mem_id) != H5Tget_order(H5T_NATIVE_LLONG)) TEST_ERROR; - + if(H5Tget_size(mem_id) < H5Tget_size(H5T_STD_I64BE)) + TEST_ERROR; + if(H5T_INTEGER!=H5Tget_class(mem_id)) + TEST_ERROR; + H5Tclose(mem_id); + /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(dims[0]*dims[1]*H5Tget_size(native_type)); - + if((bkg=calloc(sizeof(s1),dims[0]*dims[1]))==NULL) + TEST_ERROR; + if (H5Dread(dataset, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp)<0) TEST_ERROR; memcpy(check, tmp, dims[0]*dims[1]*H5Tget_size(native_type)); free(tmp); - if (H5Tconvert(native_type, tid_m, dims[0]*dims[1], check, NULL, H5P_DEFAULT)) + if (H5Tconvert(native_type, tid_m, dims[0]*dims[1], check, bkg, H5P_DEFAULT)) TEST_ERROR; + free(bkg); + /* Check that the values read are the same as the values written */ for (i = 0, temp_point=points, temp_check=check; i < 100; i++) { for (j = 0; j < 200; j++, temp_point++,temp_check++) { @@ -766,6 +882,7 @@ test_enum_dtype(hid_t file) hsize_t dims[2]; void *tmp; short colors[8]; + unsigned char sub_colors[16]; const char *mname[] = { "RED", "GREEN", "BLUE", @@ -792,9 +909,9 @@ test_enum_dtype(hid_t file) if((tid=H5Tenum_create(H5T_STD_I16LE))<0) TEST_ERROR; for (i = 0; i < 8; i++) { - colors[i] = i; - - if(H5Tenum_insert(tid, mname[i], &(colors[i]))<0) TEST_ERROR; + sub_colors[i*2]=i; + sub_colors[i*2+1]=0; + if(H5Tenum_insert(tid, mname[i], &(sub_colors[i*2]))<0) TEST_ERROR; } /* Create the dataset */ @@ -830,9 +947,6 @@ test_enum_dtype(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - if(!H5Tequal(native_type, tid_m)) - TEST_ERROR; - /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(dims[0]*dims[1]*H5Tget_size(native_type)); @@ -853,6 +967,8 @@ test_enum_dtype(hid_t file) H5_FAILED(); printf(" Read different values than written.\n"); printf(" At index %d,%d\n", i, j); + printf(" spoints2[i][j]=%hd, scheck2[i][j]=%hd\n", spoints2[i][j], + scheck2[i][j]); goto error; } } @@ -970,8 +1086,6 @@ test_array_dtype(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - if(!H5Tequal(tid_m, native_type)) TEST_ERROR; - /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(space_dims[0]*space_dims[1]*H5Tget_size(native_type)); @@ -1095,8 +1209,6 @@ test_array_dtype2(hid_t file) if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - if(!H5Tequal(tid_m, native_type)) TEST_ERROR; - /* Read the dataset back. Temporary buffer is for special platforms like * Cray */ tmp = malloc(space_dims[0]*space_dims[1]*H5Tget_size(native_type)); @@ -1163,9 +1275,10 @@ test_vl_dtype(hid_t file) hvl_t *t1, *t2; /* Temporary pointer to VL information */ hsize_t dims1[] = {SPACE1_DIM1}; hid_t dataset, space; - hid_t dtype, native_type, tid, tid2, tid_m, tid_m2; + hid_t dtype, native_type, nat_super_type, tid, tid2, tid_m, tid_m2; size_t i, j, k; - + void* *tmp; + TESTING("variable length datatype"); /* Allocate and initialize VL data to write */ @@ -1185,8 +1298,9 @@ test_vl_dtype(hid_t file) goto error; } /* end if */ t1->len=j+1; - for(k=0; k<(j+1); k++) + for(k=0; k<(j+1); k++) { ((unsigned int *)t1->p)[k]=(unsigned int)(i*100+j*10+k); + } } /* end for */ } /* end for */ @@ -1222,15 +1336,18 @@ test_vl_dtype(hid_t file) /* Open a dataset */ if((dataset=H5Dopen(file, DSET_VL_NAME))<0) TEST_ERROR; - /* Get datatype for dataset */ + /* Get native datatype for dataset */ if((dtype = H5Dget_type(dataset))<0) TEST_ERROR; if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - - if(!H5Tequal(native_type, tid_m)) + + /* Also get native base type for this nested VL type. Should be an integer type. */ + if((nat_super_type=H5Tget_super(native_type))<0) TEST_ERROR; - + if((nat_super_type=H5Tget_super(nat_super_type))<0) + TEST_ERROR; + /* Read dataset from disk */ if(H5Dread(dataset,native_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,rdata)<0) TEST_ERROR; @@ -1247,13 +1364,25 @@ test_vl_dtype(hid_t file) printf(" VL data length don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len); goto error; } /* end if */ + + /* use temporary buffer to convert datatype. This is for special + * platforms like Cray */ + tmp=malloc(t2->len*sizeof(unsigned int)); + memcpy(tmp, t2->p, t2->len*H5Tget_size(nat_super_type)); + + if (H5Tconvert(nat_super_type, H5T_NATIVE_UINT, t2->len, tmp, NULL, H5P_DEFAULT)) + TEST_ERROR; + for(k=0; k<t2->len; k++) { - if( ((unsigned int *)t1->p)[k] != ((unsigned int *)t2->p)[k] ) { + if( ((unsigned int *)t1->p)[k] != ((unsigned int *)tmp)[k] ) { H5_FAILED(); - printf(" VL data length don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len); + printf(" VL data don't match!, wdata[%d].p=%d, rdata[%d].p=%d\n", + i,((unsigned int*)t1->p)[k],i,(unsigned int*)tmp[k]); goto error; } } /* end for */ + + free(tmp); } /* end for */ } /* end for */ @@ -1395,6 +1524,113 @@ error: /*------------------------------------------------------------------------- + * Function: test_str_dtype + * + * Purpose: Test H5Tget_native_type for fixed-length string datatype + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Raymond Lu + * October 15, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_str_dtype(hid_t file) +{ + const char wdata[SPACE1_DIM1][4]= { + "one", + "two", + "3rd", + "4th" + }; /* Information to write */ + char rdata[SPACE1_DIM1][4]; /* Information read in */ + hid_t dataset; /* Dataset ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1,dtype,native_type; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + unsigned i; /* counting variable */ + + /* Output message about test being performed */ + TESTING("fixed-length string datatype"); + + /* Create dataspace for datasets */ + if((sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL))<0) TEST_ERROR; + + /* Create a datatype to refer to */ + if((tid1 = H5Tcopy (H5T_C_S1))<0) TEST_ERROR; + + if(H5Tset_size (tid1,4)<0) TEST_ERROR; + if(H5T_STRING!=H5Tget_class(tid1)) + TEST_ERROR; + + /* Create a dataset */ + if((dataset=H5Dcreate(file,DSET_STR_NAME,tid1,sid1,H5P_DEFAULT))<0) TEST_ERROR; + + /* Write dataset to disk */ + if(H5Dwrite(dataset,tid1,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata)<0) TEST_ERROR; + + /* Close Dataset */ + if(H5Dclose(dataset)<0) TEST_ERROR; + + /* Open a dataset */ + if((dataset=H5Dopen(file, DSET_STR_NAME))<0) TEST_ERROR; + + /* Get datatype for dataset */ + if((dtype = H5Dget_type(dataset))<0) TEST_ERROR; + + /* Construct native type */ + if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) + TEST_ERROR; + + /* Check if the data type is equal */ + if(!H5Tequal(native_type, tid1) || H5T_STRING!=H5Tget_class(native_type)) + TEST_ERROR; + + /* Read dataset from disk */ + if(H5Dread(dataset,native_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,rdata)<0) TEST_ERROR; + + /* Compare data read in */ + for(i=0; i<SPACE1_DIM1; i++) { + if(strlen(wdata[i])!=strlen(rdata[i])) { + H5_FAILED(); + printf(" data length don't match!, strlen(wdata[%d])=%d, strlen(rdata[%d])=%d\n", + (int)i,(int)strlen(wdata[i]),(int)i,(int)strlen(rdata[i])); + goto error; + } /* end if */ + if( strcmp(wdata[i],rdata[i]) != 0 ) { + H5_FAILED(); + printf(" data values don't match!, wdata[%d]=%s, rdata[%d]=%s\n", + (int)i,wdata[i],(int)i,rdata[i]); + goto error; + } /* end if */ + } /* end for */ + + /* Close Dataset */ + if(H5Dclose(dataset)<0) TEST_ERROR; + + /* Close datatype */ + if(H5Tclose(tid1)<0) TEST_ERROR; + if(H5Tclose(native_type)<0) TEST_ERROR; + + /* Close disk dataspace */ + if(H5Sclose(sid1)<0) TEST_ERROR; + + PASSED(); + return 0; + +error: + return -1; +} /* end test_str_dtype() */ + + + + +/*------------------------------------------------------------------------- * Function: test_refer_dtype * * Purpose: Test H5Tget_native_type for reference datatype @@ -1932,6 +2168,7 @@ main(void) nerrors += test_array_dtype2(file)<0 ?1:0; nerrors += test_vl_dtype(file)<0 ?1:0; nerrors += test_vlstr_dtype(file)<0 ?1:0; + nerrors += test_str_dtype(file)<0 ?1:0; nerrors += test_refer_dtype(file)<0 ?1:0; nerrors += test_refer_dtype2(file)<0 ?1:0; nerrors += test_opaque_dtype(file)<0 ?1:0; diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index bbf4991..d604c93 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -914,11 +914,11 @@ display_string_type(hid_t type, int UNUSED ind) } if (H5Tis_variable_str(type)) { - printf("variable-length "); + printf("variable-length"); } else { - printf("%lu-byte ", (unsigned long)H5Tget_size(type)); + printf("%lu-byte", (unsigned long)H5Tget_size(type)); } - printf("%s %s string", pad_s, cset_s); + printf(" %s %s string", pad_s, cset_s); return TRUE; } |