summaryrefslogtreecommitdiffstats
path: root/tools/h5tools.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-07-24 14:28:32 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-07-24 14:28:32 (GMT)
commit78c70d7be5430c106c53f5c067128518bc874d7d (patch)
treebf4445accf81ab4d6f218ade9712fd9a70d383af /tools/h5tools.c
parent181a423f85bf5febedd0d1b083e77f8b978d5b50 (diff)
downloadhdf5-78c70d7be5430c106c53f5c067128518bc874d7d.zip
hdf5-78c70d7be5430c106c53f5c067128518bc874d7d.tar.gz
hdf5-78c70d7be5430c106c53f5c067128518bc874d7d.tar.bz2
[svn-r541] Changes since 19980723
---------------------- ./tools/h5dump.c ./tools/h5ls.c ./tools/h5tools.h Able to handle compound data types now. Moved code that chooses memory data type based on file data type from h5ls to libh5tools.a(h5dump.o)
Diffstat (limited to 'tools/h5tools.c')
-rw-r--r--tools/h5tools.c191
1 files changed, 183 insertions, 8 deletions
diff --git a/tools/h5tools.c b/tools/h5tools.c
index ef1e954..7941377 100644
--- a/tools/h5tools.c
+++ b/tools/h5tools.c
@@ -27,6 +27,7 @@
#define OPT(X,S) ((X)?(X):(S))
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
#define NELMTS(X) (sizeof(X)/sizeof(*X))
+#define ALIGN(A,Z) ((((A)+(Z)-1)/(Z))*(Z))
/*-------------------------------------------------------------------------
@@ -102,8 +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;
- char temp[1024];
+ size_t i, n, offset;
+ char temp[1024], *name;
+ hid_t memb;
+ int nmembs, j;
if (H5Tequal(type, H5T_NATIVE_DOUBLE)) {
sprintf(temp, "%g", *((double*)vp));
@@ -111,9 +114,30 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
sprintf(temp, "%g", *((float*)vp));
} else if (H5Tequal(type, H5T_NATIVE_CHAR) ||
H5Tequal(type, H5T_NATIVE_UCHAR)) {
- if ('\\'==*((char*)vp)) strcpy(temp, "\\\\");
- else if (isprint(*((char*)vp))) sprintf(temp, "%c", *((char*)vp));
- else sprintf(temp, "\\%03o", *((unsigned char*)vp));
+ switch (*((char*)vp)) {
+ case '\\':
+ strcpy(temp, "\\\\");
+ break;
+ case '\b':
+ strcpy(temp, "\\b");
+ break;
+ case '\f':
+ strcpy(temp, "\\f");
+ break;
+ case '\n':
+ strcpy(temp, "\\n");
+ break;
+ case '\r':
+ strcpy(temp, "\\r");
+ break;
+ case '\t':
+ strcpy(temp, "\\t");
+ break;
+ default:
+ if (isprint(*((char*)vp))) sprintf(temp, "%c", *((char*)vp));
+ else sprintf(temp, "\\%03o", *((unsigned char*)vp));
+ break;
+ }
} else if (H5Tequal(type, H5T_NATIVE_SHORT)) {
sprintf(temp, "%d", *((short*)vp));
} else if (H5Tequal(type, H5T_NATIVE_USHORT)) {
@@ -126,6 +150,24 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
sprintf(temp, "%ld", *((long*)vp));
} else if (H5Tequal(type, H5T_NATIVE_ULONG)) {
sprintf(temp, "%lu", *((unsigned long*)vp));
+ } else if (H5T_COMPOUND==H5Tget_class(type)) {
+ nmembs = H5Tget_nmembers(type);
+ strcpy(temp, OPT(info->cmpd_pre, "{"));
+ for (j=0; j<nmembs; j++) {
+ if (j) strcat(temp, OPT(info->cmpd_sep, ","));
+
+ /* The name */
+ name = H5Tget_member_name(type, j);
+ sprintf(temp+strlen(temp), OPT(info->cmpd_name, ""), name);
+ free(name);
+
+ /* The value */
+ offset = H5Tget_member_offset(type, j);
+ memb = H5Tget_member_type(type, j);
+ h5dump_sprint(temp+strlen(temp), info, memb, (char*)vp+offset);
+ H5Tclose(memb);
+ }
+ strcat(temp, OPT(info->cmpd_suf, "}"));
} else {
strcpy(temp, "0x");
n = H5Tget_size(type);
@@ -243,7 +285,7 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
for (i=0; i<hs_nelmts; i++) {
/* Render the element */
h5dump_sprint(p_buf, info, p_type, sm_buf+i*p_type_nbytes);
- if (i+1<hs_nelmts) {
+ if (elmtno+i+1<p_nelmts) {
strcat(p_buf, OPT(info->elmt_suf1, ","));
}
@@ -297,6 +339,121 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
/*-------------------------------------------------------------------------
+ * Function: h5dump_fixtype
+ *
+ * Purpose: Given a file data type choose a memory data type which is
+ * appropriate for printing the data.
+ *
+ * Return: Success: Memory data type
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, July 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+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;
+
+ size = H5Tget_size(f_type);
+ switch (H5Tget_class(f_type)) {
+
+ case H5T_INTEGER:
+ /*
+ * Use the smallest native integer type of the same sign as the file
+ * such that the memory type is at least as large as the file type.
+ * If there is no memory type large enough then use the largest
+ * memory type available.
+ */
+ if (size<=sizeof(char)) {
+ m_type = H5Tcopy(H5T_NATIVE_CHAR);
+ } else if (size<=sizeof(short)) {
+ m_type = H5Tcopy(H5T_NATIVE_SHORT);
+ } else if (size<=sizeof(int)) {
+ m_type = H5Tcopy(H5T_NATIVE_INT);
+ } else if (size<=sizeof(long)) {
+ m_type = H5Tcopy(H5T_NATIVE_LONG);
+ } else {
+ m_type = H5Tcopy(H5T_NATIVE_LLONG);
+ }
+ H5Tset_sign(m_type, H5Tget_size(f_type));
+ break;
+
+ case H5T_FLOAT:
+ /*
+ * Use the smallest native floating point type available such that
+ * its size is at least as large as the file type. If there is not
+ * native type large enough then use the largest native type.
+ */
+ if (size<=sizeof(float)) {
+ m_type = H5Tcopy(H5T_NATIVE_FLOAT);
+ } else if (size<=sizeof(double)) {
+ m_type = H5Tcopy(H5T_NATIVE_DOUBLE);
+ } else {
+ m_type = H5Tcopy(H5T_NATIVE_LDOUBLE);
+ }
+ break;
+
+ case H5T_COMPOUND:
+ nmembs = H5Tget_nmembers(f_type);
+ memb = calloc(nmembs, sizeof(hid_t));
+ name = calloc(nmembs, sizeof(char*));
+
+ for (i=0, size=0; i<nmembs; i++) {
+ 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);
+ name[i] = H5Tget_member_name(f_type, i);
+ if (memb[i]<0 || NULL==name[i]) goto done;
+ }
+
+ 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]);
+ }
+ break;
+
+ case H5T_TIME:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ /*
+ * These type classes are not implemented yet.
+ */
+ break;
+
+ default:
+ /* What the heck? */
+ break;
+ }
+
+ done:
+ /* Clean up temp buffers */
+ if (memb && name) {
+ for (i=0; i<nmembs; i++) {
+ if (memb[i]>=0) H5Tclose(memb[i]);
+ if (name[i]) free(name[i]);
+ }
+ free(memb);
+ free(name);
+ }
+
+ return m_type;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: h5dump
*
* Purpose: Print some values from a dataset. The values to print are
@@ -315,13 +472,31 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
*-------------------------------------------------------------------------
*/
int
-h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
+h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
{
hid_t f_space;
+ hid_t p_type = _p_type;
+ hid_t f_type;
+ int status;
+ /* Check the data space */
f_space = H5Dget_space(dset);
if (H5Sis_simple(f_space)<=0) return -1;
H5Sclose(f_space);
- return h5dump_simple(stream, info, dset, p_type);
+ /*
+ * Check the data type. If the caller didn't supply a data type then
+ * use an appropriate native data type.
+ */
+ if (p_type<0) {
+ f_type = H5Dget_type(dset);
+ p_type = h5dump_fixtype(f_type);
+ H5Tclose(f_type);
+ if (p_type<0) return -1;
+ }
+
+ /* Print the data */
+ status = h5dump_simple(stream, info, dset, p_type);
+ if (p_type!=_p_type) H5Tclose(p_type);
+ return status;
}