diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/h5ls.c | 39 | ||||
-rw-r--r-- | tools/h5tools.c | 98 | ||||
-rw-r--r-- | tools/h5tools.h | 16 |
3 files changed, 115 insertions, 38 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c index 0ae0c21..c79c8d1 100644 --- a/tools/h5ls.c +++ b/tools/h5ls.c @@ -86,6 +86,7 @@ dump_dataset_values(hid_t dset) memset(&info, 0, sizeof info); info.idx_fmt = " (%s) "; info.line_ncols = width_g; + if (verbose_g) info.cmpd_name = "%s="; /* * If the dataset is a 1-byte integer type then format it as an ASCI @@ -177,6 +178,7 @@ list (hid_t group, const char *name, void __unused__ *op_data) int i; char buf[512], comment[50]; H5G_stat_t statbuf; + struct tm *tm; /* Disable error reporting */ H5Eget_auto (&func, &edata); @@ -185,13 +187,6 @@ list (hid_t group, const char *name, void __unused__ *op_data) /* Print info about each name */ printf ("%-25s ", name); - if (H5Gstat (group, name, TRUE, &statbuf)>=0) { - sprintf (buf, "%lu:%lu:%lu:%lu", - statbuf.fileno[1], statbuf.fileno[0], - statbuf.objno[1], statbuf.objno[0]); - printf ("%-20s ", buf); - } - if ((obj=H5Dopen (group, name))>=0) { hsize_t size[64]; hsize_t maxsize[64]; @@ -209,7 +204,6 @@ list (hid_t group, const char *name, void __unused__ *op_data) printf ("}\n"); H5Dclose (space); H5Aiterate (obj, NULL, list_attr, NULL); - if (dump_g) dump_dataset_values(obj); H5Dclose (obj); } else if ((obj=H5Gopen (group, name))>=0) { printf ("Group\n"); @@ -228,11 +222,30 @@ list (hid_t group, const char *name, void __unused__ *op_data) printf ("Unknown Type\n"); } - /* Display the comment if the object has one */ - comment[0] = '\0'; - H5Gget_comment(group, name, sizeof(comment), comment); - strcpy(comment+sizeof(comment)-4, "..."); - if (comment[0]) printf("%26s%s\n", "", comment); + if (verbose_g>0) { + if (H5Gstat(group, name, TRUE, &statbuf)>=0) { + printf(" %-10s %lu:%lu:%lu:%lu\n", + "Location:", statbuf.fileno[1], statbuf.fileno[0], + statbuf.objno[1], statbuf.objno[0]); + if (statbuf.mtime>0 && NULL!=(tm = localtime(&(statbuf.mtime)))) { + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); + printf(" %-10s %s\n", "Modtime:", buf); + } + } + + /* Display the comment if the object has one */ + comment[0] = '\0'; + H5Gget_comment(group, name, sizeof(comment), comment); + strcpy(comment+sizeof(comment)-4, "..."); + if (comment[0]) printf(" %-10s %s\n", "Comment:", comment); + } + + if (dump_g && (obj=H5Dopen(group, name))) { + /* Turn on error reporting before dumping the data */ + H5Eset_auto(func, edata); + dump_dataset_values(obj); + H5Dclose(obj); + } /* Restore error reporting */ H5Eset_auto (func, edata); diff --git a/tools/h5tools.c b/tools/h5tools.c index 7941377..fae2251 100644 --- a/tools/h5tools.c +++ b/tools/h5tools.c @@ -22,7 +22,7 @@ * size of that temporary buffer in bytes. For efficiency's sake, choose the * largest value suitable for your machine (for testing use a small value). */ -#define H5DUMP_BUFSIZE 1024 +#define H5DUMP_BUFSIZE (1024*1024) #define OPT(X,S) ((X)?(X):(S)) #define MIN(X,Y) ((X)<(Y)?(X):(Y)) @@ -103,10 +103,10 @@ h5dump_prefix(char *s/*out*/, const h5dump_t *info, hsize_t elmtno, int ndims, static void h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) { - size_t i, n, offset; + size_t i, n, offset, size, dims[4], nelmts; char temp[1024], *name; hid_t memb; - int nmembs, j; + int nmembs, j, k, ndims; if (H5Tequal(type, H5T_NATIVE_DOUBLE)) { sprintf(temp, "%g", *((double*)vp)); @@ -115,6 +115,9 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) } else if (H5Tequal(type, H5T_NATIVE_CHAR) || H5Tequal(type, H5T_NATIVE_UCHAR)) { switch (*((char*)vp)) { + case '"': + strcpy(temp, "\\\""); + break; case '\\': strcpy(temp, "\\\\"); break; @@ -164,7 +167,18 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) /* The value */ offset = H5Tget_member_offset(type, j); memb = H5Tget_member_type(type, j); - h5dump_sprint(temp+strlen(temp), info, memb, (char*)vp+offset); + size = H5Tget_size(memb); + ndims = H5Tget_member_dims(type, j, dims, NULL); + assert(ndims>=0 && ndims<=4); + for (k=0, nelmts=1; k<ndims; k++) nelmts *= dims[k]; + + if (nelmts>1) strcat(temp, OPT(info->arr_pre, "[")); + for (i=0; i<nelmts; i++) { + if (i) strcat(temp, OPT(info->arr_sep, ",")); + h5dump_sprint(temp+strlen(temp), info, memb, + (char*)vp+offset+i*size); + } + if (nelmts>1) strcat(temp, OPT(info->arr_suf, "]")); H5Tclose(memb); } strcat(temp, OPT(info->cmpd_suf, "}")); @@ -361,8 +375,8 @@ h5dump_fixtype(hid_t f_type) hid_t m_type=-1, f_memb; hid_t *memb=NULL; char **name=NULL; - int nmembs, i; - size_t size; + int nmembs, i, j, *ndims=NULL; + size_t size, offset, *dims=NULL, nelmts; size = H5Tget_size(f_type); switch (H5Tget_class(f_type)) { @@ -385,7 +399,7 @@ h5dump_fixtype(hid_t f_type) } else { m_type = H5Tcopy(H5T_NATIVE_LLONG); } - H5Tset_sign(m_type, H5Tget_size(f_type)); + H5Tset_sign(m_type, H5Tget_sign(f_type)); break; case H5T_FLOAT: @@ -404,23 +418,51 @@ h5dump_fixtype(hid_t f_type) break; case H5T_COMPOUND: + /* + * We have to do this in two steps. The first step scans the file + * type and converts the members to native types and remembers all + * their names and sizes, computing the size of the memory compound + * type at the same time. Then we create the memory compound type + * and add the members. + */ nmembs = H5Tget_nmembers(f_type); memb = calloc(nmembs, sizeof(hid_t)); name = calloc(nmembs, sizeof(char*)); + ndims = calloc(nmembs, sizeof(int)); + dims = calloc(nmembs*4, sizeof(size_t)); for (i=0, size=0; i<nmembs; i++) { + + /* Get the member type and fix it */ f_memb = H5Tget_member_type(f_type, i); memb[i] = h5dump_fixtype(f_memb); - size = ALIGN(size, H5Tget_size(memb[i])) + H5Tget_size(memb[i]); H5Tclose(f_memb); + if (memb[i]<0) goto done; + + /* Get the member dimensions */ + ndims[i] = H5Tget_member_dims(f_type, i, dims+i*4, NULL); + assert(ndims[i]>=0 && ndims[i]<=4); + for (j=0, nelmts=1; j<ndims[i]; j++) nelmts *= dims[i*4+j]; + + /* Get the member name */ name[i] = H5Tget_member_name(f_type, i); - if (memb[i]<0 || NULL==name[i]) goto done; + if (NULL==name[i]) goto done; + + /* + * Compute the new offset so each member is aligned on a byte + * boundary which is the same as the member size. + */ + size = ALIGN(size, H5Tget_size(memb[i])) + + nelmts * H5Tget_size(memb[i]); } m_type = H5Tcreate(H5T_COMPOUND, size); - for (i=0, size=0; i<nmembs; i++) { - H5Tinsert(m_type, name[i], size, memb[i]); - size = ALIGN(size, H5Tget_size(memb[i])) + H5Tget_size(memb[i]); + for (i=0, offset=0; i<nmembs; i++) { + H5Tinsert_array(m_type, name[i], offset, ndims[i], dims+i*4, + NULL, memb[i]); + for (j=0, nelmts=1; j<ndims[i]; j++) nelmts *= dims[i*4+j]; + offset = ALIGN(offset, H5Tget_size(memb[i])) + + nelmts * H5Tget_size(memb[i]); } break; @@ -440,13 +482,15 @@ h5dump_fixtype(hid_t f_type) done: /* Clean up temp buffers */ - if (memb && name) { + if (memb && name && ndims && dims) { for (i=0; i<nmembs; i++) { if (memb[i]>=0) H5Tclose(memb[i]); if (name[i]) free(name[i]); } free(memb); free(name); + free(ndims); + free(dims); } return m_type; @@ -456,9 +500,10 @@ h5dump_fixtype(hid_t f_type) /*------------------------------------------------------------------------- * Function: h5dump * - * Purpose: Print some values from a dataset. The values to print are - * determined by the P_SPACE argument and the format to use to - * print them is determined by the P_TYPE argument. + * Purpose: Print some values from a dataset DSET to the file STREAM + * after converting all types to P_TYPE (which should be a + * native type). If P_TYPE is a negative value then it will be + * computed from the dataset type using only native types. * * Return: Success: 0 * @@ -478,16 +523,14 @@ h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type) hid_t p_type = _p_type; hid_t f_type; int status; + h5dump_t info_dflt; - /* Check the data space */ - f_space = H5Dget_space(dset); - if (H5Sis_simple(f_space)<=0) return -1; - H5Sclose(f_space); - - /* - * Check the data type. If the caller didn't supply a data type then - * use an appropriate native data type. - */ + /* Use default values */ + if (!stream) stream = stdout; + if (!info) { + memset(&info_dflt, 0, sizeof info_dflt); + info = &info_dflt; + } if (p_type<0) { f_type = H5Dget_type(dset); p_type = h5dump_fixtype(f_type); @@ -495,6 +538,11 @@ h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type) if (p_type<0) return -1; } + /* Check the data space */ + f_space = H5Dget_space(dset); + if (H5Sis_simple(f_space)<=0) return -1; + H5Sclose(f_space); + /* Print the data */ status = h5dump_simple(stream, info, dset, p_type); if (p_type!=_p_type) H5Tclose(p_type); diff --git a/tools/h5tools.h b/tools/h5tools.h index 3b9b231..374bb71 100644 --- a/tools/h5tools.h +++ b/tools/h5tools.h @@ -18,6 +18,22 @@ */ typedef struct h5dump_t { /* + * Fields associated with compound array members. + * + * pre: A string to print at the beginning of each array. The + * default value is the left square bracket `['. + * + * sep: A string to print between array values. The default + * value is a comma. + * + * suf: A strint to print at the end of each array. The default + * value is a right square bracket `]'. + */ + const char *arr_pre; + const char *arr_sep; + const char *arr_suf; + + /* * Fields associated with compound data types. * * name: How the name of the struct member is printed in the |