summaryrefslogtreecommitdiffstats
path: root/tools/h5tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/h5tools.c')
-rw-r--r--tools/h5tools.c98
1 files changed, 73 insertions, 25 deletions
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);