diff options
-rw-r--r-- | tools/h5ls/Dependencies | 0 | ||||
-rw-r--r-- | tools/h5ls/Makefile.in | 55 | ||||
-rw-r--r-- | tools/h5ls/h5ls.c | 2166 | ||||
-rwxr-xr-x | tools/h5ls/testh5ls.sh | 143 | ||||
-rw-r--r-- | tools/h5toh4/Dependencies | 0 | ||||
-rw-r--r-- | tools/h5toh4/Makefile.in | 60 | ||||
-rw-r--r-- | tools/h5toh4/h5toh4.c | 2592 | ||||
-rw-r--r-- | tools/h5toh4/h5toh4.h | 43 | ||||
-rwxr-xr-x | tools/h5toh4/testh5toh4.sh | 299 |
9 files changed, 5358 insertions, 0 deletions
diff --git a/tools/h5ls/Dependencies b/tools/h5ls/Dependencies new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/h5ls/Dependencies diff --git a/tools/h5ls/Makefile.in b/tools/h5ls/Makefile.in new file mode 100644 index 0000000..ba75fcd --- /dev/null +++ b/tools/h5ls/Makefile.in @@ -0,0 +1,55 @@ +## HDF5 Library Makefile(.in) +## +## Copyright (C) 2001 National Center for Supercomputing Applications. +## All rights reserved. +## +## +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +SUBDIRS= +@COMMENCE@ + +## Add include directory to the C preprocessor flags, add -lh5tools and +## -lhdf5 to the list of libraries. +## +CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src \ + -I$(top_srcdir)/tools/lib @CPPFLAGS@ + +## Test programs and scripts. +## +TEST_PROGS= +TEST_SCRIPTS=$(srcdir)/testh5ls.sh + +## These are our main targets: library and tools. +## +LIBTOOLS=../lib/libh5tools.la +LIBHDF5=$(top_builddir)/src/libhdf5.la +PUB_PROGS=h5ls +PROGS=$(PUB_PROGS) $(TEST_PROGS) + +## Source and object files for the library; do not install +LIB_SRC= +LIB_OBJ=$(LIB_SRC:.c=.lo) +PUB_LIB= + +## Source and object files for programs... +PROG_SRC=h5ls.c +PROG_OBJ=$(PROG_SRC:.c=.lo) +PRIVATE_HDR= + +## Source and object files for the tests +TEST_SRC= +TEST_OBJ=$(TEST_SRC:.c=.lo) + +## Programs have to be built before they can be tested! +check test _test: $(PROGS) + +## How to build the programs... They all depend on the hdf5 library and +## the tools library compiled in this directory. +$(PROGS): $(LIBTOOLS) $(LIBHDF5) + +h5ls: h5ls.lo + @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5ls.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS) + +@CONCLUDE@ diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c new file mode 100644 index 0000000..7a6ff39 --- /dev/null +++ b/tools/h5ls/h5ls.c @@ -0,0 +1,2166 @@ +/* + * Copyright (C) 1998 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, March 23, 1998 + */ + + +/* + * We include the private header file so we can get to the uniform + * programming environment it declares. Other than that, h5ls only calls + * HDF5 API functions (except for H5G_basename()) + */ +#include <H5private.h> +#include <h5tools.h> + +/* + * If defined then include the file name as part of the object name when + * printing full object names. Otherwise leave the file name off. + */ +#define H5LS_PREPEND_FILENAME + +/* Command-line switches */ +static int verbose_g = 0; /*lots of extra output */ +static int width_g = 80; /*output width in characters */ +static hbool_t address_g = FALSE; /*print raw data addresses */ +static hbool_t data_g = FALSE; /*display dataset values? */ +static hbool_t label_g = FALSE; /*label compound values? */ +static hbool_t string_g = FALSE; /*print 1-byte numbers as ASCII? */ +static hbool_t fullname_g = FALSE; /*print full path names */ +static hbool_t recursive_g = FALSE; /*recursive descent listing */ +static hbool_t grp_literal_g = FALSE; /*list group, not contents */ +static hbool_t hexdump_g = FALSE; /*show data as raw hexadecimal */ +static hbool_t show_errors_g = FALSE; /*print HDF5 error messages */ +static hbool_t simple_output_g = FALSE; /*make output more machine-readable */ + +/* Info to pass to the iteration functions */ +typedef struct iter_t { + const char *container; /*full name of the container object */ +} iter_t; + +/* Table containing object id and object name */ +static struct { + int nalloc; /*number of slots allocated */ + int nobjs; /*number of objects */ + struct { + unsigned long id[2]; /*object number */ + char *name; /*full object name */ + } *obj; +} idtab_g; + +/* Information about how to display each type of object */ +static struct dispatch_t { + const char *name; + hid_t (*open)(hid_t loc, const char *name); + herr_t (*close)(hid_t obj); + herr_t (*list1)(hid_t obj); + herr_t (*list2)(hid_t obj, const char *name); +} dispatch_g[H5G_NTYPES]; + +#define DISPATCH(TYPE,NAME,OPEN,CLOSE,LIST1,LIST2) { \ + dispatch_g[TYPE].name = (NAME); \ + dispatch_g[TYPE].open = (OPEN); \ + dispatch_g[TYPE].close = (CLOSE); \ + dispatch_g[TYPE].list1 = (LIST1); \ + dispatch_g[TYPE].list2 = (LIST2); \ +} + +static herr_t list (hid_t group, const char *name, void *cd); +static void display_type(hid_t type, int ind); +static char *fix_name(const char *path, const char *base); + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Prints a usage message on stderr and then returns. + * + * Return: void + * + * Programmer: Robb Matzke + * Thursday, July 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +usage (const char *progname) +{ + fprintf(stderr, "\ +usage: %s [OPTIONS] [OBJECTS...]\n\ + OPTIONS\n\ + -h, -?, --help Print a usage message and exit\n\ + -a, --address Print addresses for raw data\n\ + -d, --data Print the values of datasets\n\ + -e, --errors Show all HDF5 error reporting\n\ + -f, --full Print full path names instead of base names\n\ + -g, --group Show information about a group, not its contents\n\ + -l, --label Label members of compound datasets\n\ + -r, --recursive List all groups recursively, avoiding cycles\n\ + -s, --string Print 1-byte integer datasets as ASCII\n\ + -S, --simple Use a machine-readable output format\n\ + -wN, --width=N Set the number of columns of output\n\ + -v, --verbose Generate more verbose output\n\ + -V, --version Print version number and exit\n\ + -x, --hexdump Show raw data in hexadecimal format\n\ +\n\ + OBJECTS\n\ + Each object consists of an HDF5 file name optionally followed by a\n\ + slash and an object name within the file (if no object is specified\n\ + within the file then the contents of the root group are displayed).\n\ + The file name may include a printf(3C) integer format such as\n\ + \"%%05d\" to open a file family.\n", + progname); +} + + +/*------------------------------------------------------------------------- + * Function: sym_insert + * + * Purpose: Add a symbol to the table. + * + * Return: void + * + * Programmer: Robb Matzke + * Thursday, January 21, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +sym_insert(H5G_stat_t *sb, const char *name) +{ + int n; + + /* + * Don't add it if the link count is 1 because such an object can only + * have one name. + */ + if (sb->nlink<2) return; + + /* Extend the table */ + if (idtab_g.nobjs>=idtab_g.nalloc) { + idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc); + idtab_g.obj = realloc(idtab_g.obj, + idtab_g.nalloc*sizeof(idtab_g.obj[0])); + } + + /* Insert the entry */ + n = idtab_g.nobjs++; + idtab_g.obj[n].id[0] = sb->objno[0]; + idtab_g.obj[n].id[1] = sb->objno[1]; + idtab_g.obj[n].name = malloc(strlen(name)+1); + strcpy(idtab_g.obj[n].name, name); +} + + +/*------------------------------------------------------------------------- + * Function: sym_lookup + * + * Purpose: Find another name for the specified object. + * + * Return: Success: Ptr to another name. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, January 21, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static char * +sym_lookup(H5G_stat_t *sb) +{ + int n; + + if (sb->nlink<2) return NULL; /*only one name possible*/ + for (n=0; n<idtab_g.nobjs; n++) { + if (idtab_g.obj[n].id[0]==sb->objno[0] && + idtab_g.obj[n].id[1]==sb->objno[1]) { + return idtab_g.obj[n].name; + } + } + return NULL; +} + + +/*------------------------------------------------------------------------- + * Function: display_string + * + * Purpose: Print a string value by escaping unusual characters. If + * STREAM is null then we only count how large the output would + * be. + * + * Return: Number of characters printed. + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +display_string(FILE *stream, const char *s, hbool_t escape_spaces) +{ + int nprint=0; + + for (/*void*/; s && *s; s++) { + switch (*s) { + case '"': + if (stream) fprintf(stream, "\\\""); + nprint += 2; + break; + case '\\': + if (stream) fprintf(stream, "\\\\"); + nprint += 2; + break; + case '\b': + if (stream) fprintf(stream, "\\b"); + nprint += 2; + break; + case '\f': + if (stream) fprintf(stream, "\\f"); + nprint += 2; + break; + case '\n': + if (stream) fprintf(stream, "\\n"); + nprint += 2; + break; + case '\r': + if (stream) fprintf(stream, "\\r"); + nprint += 2; + break; + case '\t': + if (stream) fprintf(stream, "\\t"); + nprint += 2; + break; + case ' ': + if (escape_spaces) { + if (stream) fprintf(stream, "\\ "); + nprint += 2; + } else { + if (stream) fprintf(stream, " "); + nprint++; + } + break; + default: + if (isprint((int)*s)) { + if (stream) putc(*s, stream); + nprint++; + } else { + if (stream) { + fprintf(stream, "\\%03o", *((const unsigned char*)s)); + } + nprint += 4; + } + break; + } + } + return nprint; +} + + +/*------------------------------------------------------------------------- + * Function: display_native_type + * + * Purpose: Prints the name of a native C data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed. + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * Robb Matzke, 1999-06-11 + * Added the C9x types, but we still prefer to display the types + * from the C language itself (like `int' vs. `int32_t'). + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_native_type(hid_t type, int UNUSED ind) +{ + if (H5Tequal(type, H5T_NATIVE_SCHAR)) { + printf("native signed char"); + } else if (H5Tequal(type, H5T_NATIVE_UCHAR)) { + printf("native unsigned char"); + } else if (H5Tequal(type, H5T_NATIVE_INT)) { + printf("native int"); + } else if (H5Tequal(type, H5T_NATIVE_UINT)) { + printf("native unsigned int"); + } else if (H5Tequal(type, H5T_NATIVE_SHORT)) { + printf("native short"); + } else if (H5Tequal(type, H5T_NATIVE_USHORT)) { + printf("native unsigned short"); + } else if (H5Tequal(type, H5T_NATIVE_LONG)) { + printf("native long"); + } else if (H5Tequal(type, H5T_NATIVE_ULONG)) { + printf("native unsigned long"); + } else if (H5Tequal(type, H5T_NATIVE_LLONG)) { + printf("native long long"); + } else if (H5Tequal(type, H5T_NATIVE_ULLONG)) { + printf("native unsigned long long"); + } else if (H5Tequal(type, H5T_NATIVE_FLOAT)) { + printf("native float"); + } else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) { + printf("native double"); + } else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) { + printf("native long double"); + } else if (H5Tequal(type, H5T_NATIVE_INT8)) { + printf("native int8_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT8)) { + printf("native uint8_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT16)) { + printf("native int16_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT16)) { + printf("native uint16_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT32)) { + printf("native int32_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT32)) { + printf("native uint32_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT64)) { + printf("native int64_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT64)) { + printf("native uint64_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST8)) { + printf("native int_least8_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST8)) { + printf("native uint_least8_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST16)) { + printf("native int_least16_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST16)) { + printf("native uint_least16_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST32)) { + printf("native int_least32_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST32)) { + printf("native uint_least32_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST64)) { + printf("native int_least64_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST64)) { + printf("native uint_least64_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_FAST8)) { + printf("native int_fast8_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST8)) { + printf("native uint_fast8_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_FAST16)) { + printf("native int_fast16_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST16)) { + printf("native uint_fast16_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_FAST32)) { + printf("native int_fast32_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST32)) { + printf("native uint_fast32_t"); + } else if (H5Tequal(type, H5T_NATIVE_INT_FAST64)) { + printf("native int_fast64_t"); + } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST64)) { + printf("native uint_fast64_t"); + } else if (H5Tequal(type, H5T_NATIVE_B8)) { + printf("native 8-bit field"); + } else if (H5Tequal(type, H5T_NATIVE_B16)) { + printf("native 16-bit field"); + } else if (H5Tequal(type, H5T_NATIVE_B32)) { + printf("native 32-bit field"); + } else if (H5Tequal(type, H5T_NATIVE_B64)) { + printf("native 64-bit field"); + } else if (H5Tequal(type, H5T_NATIVE_HSIZE)) { + printf("native hsize_t"); + } else if (H5Tequal(type, H5T_NATIVE_HSSIZE)) { + printf("native hssize_t"); + } else if (H5Tequal(type, H5T_NATIVE_HERR)) { + printf("native herr_t"); + } else if (H5Tequal(type, H5T_NATIVE_HBOOL)) { + printf("native hbool_t"); + } else { + return FALSE; + } + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_ieee_type + * + * Purpose: Print the name of an IEEE floating-point data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_ieee_type(hid_t type, int UNUSED ind) +{ + if (H5Tequal(type, H5T_IEEE_F32BE)) { + printf("IEEE 32-bit big-endian float"); + } else if (H5Tequal(type, H5T_IEEE_F32LE)) { + printf("IEEE 32-bit little-endian float"); + } else if (H5Tequal(type, H5T_IEEE_F64BE)) { + printf("IEEE 64-bit big-endian float"); + } else if (H5Tequal(type, H5T_IEEE_F64LE)) { + printf("IEEE 64-bit little-endian float"); + } else { + return FALSE; + } + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_precision + * + * Purpose: Prints information on the next line about precision and + * padding if the precision is less than the total data type + * size. + * + * Return: void + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +display_precision(hid_t type, int ind) +{ + size_t prec; /*precision */ + H5T_pad_t plsb, pmsb; /*lsb and msb padding */ + const char *plsb_s=NULL; /*lsb padding string */ + const char *pmsb_s=NULL; /*msb padding string */ + size_t nbits; /*number of bits */ + + /* + * If the precision is less than the total size then show the precision + * and offset on the following line. Also display the padding + * information. + */ + if (8*H5Tget_size(type)!=(prec=H5Tget_precision(type))) { + printf("\n%*s(%lu bit%s of precision beginning at bit %lu)", + ind, "", (unsigned long)prec, 1==prec?"":"s", + (unsigned long)H5Tget_offset(type)); + + H5Tget_pad(type, &plsb, &pmsb); + if (H5Tget_offset(type)>0) { + switch (plsb) { + case H5T_PAD_ZERO: + plsb_s = "zero"; + break; + case H5T_PAD_ONE: + plsb_s = "one"; + break; + case H5T_PAD_BACKGROUND: + plsb_s = "bkg"; + break; + case H5T_PAD_ERROR: + case H5T_NPAD: + plsb_s = "unknown"; + break; + } + } + if (H5Tget_offset(type)+prec<8*H5Tget_size(type)) { + switch (pmsb) { + case H5T_PAD_ZERO: + pmsb_s = "zero"; + break; + case H5T_PAD_ONE: + pmsb_s = "one"; + break; + case H5T_PAD_BACKGROUND: + pmsb_s = "bkg"; + break; + case H5T_PAD_ERROR: + case H5T_NPAD: + pmsb_s = "unknown"; + break; + } + } + if (plsb_s || pmsb_s) { + printf("\n%*s(", ind, ""); + if (plsb_s) { + nbits = H5Tget_offset(type); + printf("%lu %s bit%s at bit 0", + (unsigned long)nbits, plsb_s, 1==nbits?"":"s"); + } + if (plsb_s && pmsb_s) printf(", "); + if (pmsb_s) { + nbits = 8*H5Tget_size(type)-(H5Tget_offset(type)+prec); + printf("%lu %s bit%s at bit %lu", + (unsigned long)nbits, pmsb_s, 1==nbits?"":"s", + (unsigned long)(8*H5Tget_size(type)-nbits)); + } + printf(")"); + } + } +} + + +/*------------------------------------------------------------------------- + * Function: display_int_type + * + * Purpose: Print the name of an integer data type. Common information + * like number of bits, byte order, and sign scheme appear on + * the first line. Additional information might appear in + * parentheses on the following lines. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_int_type(hid_t type, int ind) +{ + H5T_order_t order; /*byte order value */ + const char *order_s=NULL; /*byte order string */ + H5T_sign_t sign; /*sign scheme value */ + const char *sign_s=NULL; /*sign scheme string */ + + if (H5T_INTEGER!=H5Tget_class(type)) return FALSE; + + /* Byte order */ + if (H5Tget_size(type)>1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE==order) { + order_s = " little-endian"; + } else if (H5T_ORDER_BE==order) { + order_s = " big-endian"; + } else if (H5T_ORDER_VAX==order) { + order_s = " mixed-endian"; + } else { + order_s = " unknown-byte-order"; + } + } else { + order_s = ""; + } + + /* Sign */ + if ((sign=H5Tget_sign(type))>=0) { + if (H5T_SGN_NONE==sign) { + sign_s = " unsigned"; + } else if (H5T_SGN_2==sign) { + sign_s = ""; + } else { + sign_s = " unknown-sign"; + } + } else { + sign_s = " unknown-sign"; + } + + /* + * Print size, order, and sign on first line, precision and padding + * information on the subsequent lines + */ + printf("%lu-bit%s%s integer", + (unsigned long)(8*H5Tget_size(type)), order_s, sign_s); + display_precision(type, ind); + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_float_type + * + * Purpose: Print info about a floating point data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_float_type(hid_t type, int ind) +{ + H5T_order_t order; /*byte order value */ + const char *order_s=NULL; /*byte order string */ + size_t spos; /*sign bit position */ + size_t esize, epos; /*exponent size and position */ + size_t msize, mpos; /*significand size and position */ + size_t ebias; /*exponent bias */ + H5T_norm_t norm; /*significand normalization */ + const char *norm_s=NULL; /*normalization string */ + H5T_pad_t pad; /*internal padding value */ + const char *pad_s=NULL; /*internal padding string */ + + if (H5T_FLOAT!=H5Tget_class(type)) return FALSE; + + /* Byte order */ + if (H5Tget_size(type)>1) { + order = H5Tget_order(type); + if (H5T_ORDER_LE==order) { + order_s = " little-endian"; + } else if (H5T_ORDER_BE==order) { + order_s = " big-endian"; + } else if (H5T_ORDER_VAX==order) { + order_s = " mixed-endian"; + } else { + order_s = " unknown-byte-order"; + } + } else { + order_s = ""; + } + + /* + * Print size and byte order on first line, precision and padding on + * subsequent lines. + */ + printf("%lu-bit%s floating-point", + (unsigned long)(8*H5Tget_size(type)), order_s); + display_precision(type, ind); + + /* Print sizes, locations, and other information about each field */ + H5Tget_fields (type, &spos, &epos, &esize, &mpos, &msize); + ebias = H5Tget_ebias(type); + norm = H5Tget_norm(type); + switch (norm) { + case H5T_NORM_IMPLIED: + norm_s = ", msb implied"; + break; + case H5T_NORM_MSBSET: + norm_s = ", msb always set"; + break; + case H5T_NORM_NONE: + norm_s = ", no normalization"; + break; + case H5T_NORM_ERROR: + norm_s = ", unknown normalization"; + break; + } + printf("\n%*s(significant for %lu bit%s at bit %lu%s)", ind, "", + (unsigned long)msize, 1==msize?"":"s", (unsigned long)mpos, + norm_s); + printf("\n%*s(exponent for %lu bit%s at bit %lu, bias is 0x%lx)", + ind, "", (unsigned long)esize, 1==esize?"":"s", + (unsigned long)epos, (unsigned long)ebias); + printf("\n%*s(sign bit at %lu)", ind, "", (unsigned long)spos); + + /* Display internal padding */ + if (1+esize+msize<H5Tget_precision(type)) { + pad = H5Tget_inpad(type); + switch (pad) { + case H5T_PAD_ZERO: + pad_s = "zero"; + break; + case H5T_PAD_ONE: + pad_s = "one"; + break; + case H5T_PAD_BACKGROUND: + pad_s = "bkg"; + break; + case H5T_PAD_ERROR: + case H5T_NPAD: + pad_s = "unknown"; + break; + } + printf("\n%*s(internal padding bits are %s)", ind, "", pad_s); + } + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_cmpd_type + * + * Purpose: Print info about a compound data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_cmpd_type(hid_t type, int ind) +{ + char *name=NULL; /*member name */ + int ndims; /*dimensionality */ + hsize_t dims[H5S_MAX_RANK]; /*dimensions */ + size_t size; /*total size of type in bytes */ + int perm[H5S_MAX_RANK]; /*index permutation */ + hid_t subtype; /*member data type */ + int i, j, n; /*miscellaneous counters */ + + + if (H5T_COMPOUND!=H5Tget_class(type)) return FALSE; + printf("struct {"); + for (i=0; i<H5Tget_nmembers(type); i++) { + + /* Name and offset */ + name = H5Tget_member_name(type, i); + printf("\n%*s\"", ind+4, ""); + n = display_string(stdout, name, FALSE); + printf("\"%*s +%-4lu ", MAX(0, 16-n), "", + (unsigned long)H5Tget_member_offset(type, i)); + free(name); + + /* Grab member's type */ + subtype = H5Tget_member_type(type, i); + + /* Dimensions and permutation */ + if(H5Tget_class(subtype)==H5T_ARRAY) { + ndims = H5Tget_array_ndims(subtype); + H5Tget_array_dims(subtype, dims, perm); + } /* end if */ + else + ndims=0; + + if (ndims>0) { + printf("["); + for (j=0; j<ndims; j++) + printf("%s%lu", j?",":"", (unsigned long)(dims[j])); + printf("]"); + + for (j=0; j<ndims; j++) + if (perm[j]!=j) + break; + + if (j<ndims) { + printf("x["); + for (j=0; j<ndims; j++) + printf("%s%d", j?",":"", perm[j]); + printf("]"); + } + printf(" "); + } + + /* Data type */ + display_type(subtype, ind+4); + H5Tclose(subtype); + } + size = H5Tget_size(type); + printf("\n%*s} %lu byte%s", + ind, "", (unsigned long)size, 1==size?"":"s"); + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_enum_type + * + * Purpose: Print info about an enumeration data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Wednesday, December 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_enum_type(hid_t type, int ind) +{ + char **name=NULL; /*member names */ + unsigned char *value=NULL; /*value array */ + int nmembs; /*number of members */ + int nchars; /*number of output characters */ + hid_t super; /*enum base integer type */ + hid_t native=-1; /*native integer data type */ + size_t dst_size; /*destination value type size */ + int i; /*miscellaneous counters */ + size_t j; + + if (H5T_ENUM!=H5Tget_class(type)) return FALSE; + nmembs = H5Tget_nmembers(type); + super = H5Tget_super(type); + printf("enum "); + display_type(super, ind+4); + printf(" {"); + + /* + * Determine what data type to use for the native values. To simplify + * things we entertain three possibilities: + * 1. long_long -- the largest native signed integer + * 2. unsigned long_long -- the largest native unsigned integer + * 3. raw format + */ + if (H5Tget_size(type)<=sizeof(long_long)) { + dst_size = sizeof(long_long); + if (H5T_SGN_NONE==H5Tget_sign(type)) { + native = H5T_NATIVE_ULLONG; + } else { + native = H5T_NATIVE_LLONG; + } + } else { + dst_size = H5Tget_size(type); + } + + /* Get the names and raw values of all members */ + assert(nmembs>0); + name = calloc((size_t)nmembs, sizeof(char*)); + value = calloc((size_t)nmembs, MAX(H5Tget_size(type), dst_size)); + for (i=0; i<nmembs; i++) { + name[i] = H5Tget_member_name(type, i); + H5Tget_member_value(type, i, value+i*H5Tget_size(type)); + } + + /* Convert values to native data type */ + if (native>0) H5Tconvert(super, native, (hsize_t)nmembs, value, NULL, H5P_DEFAULT); + + /* Sort members by increasing value */ + /*not implemented yet*/ + + /* Print members */ + for (i=0; i<nmembs; i++) { + printf("\n%*s", ind+4, ""); + nchars = display_string(stdout, name[i], TRUE); + printf("%*s = ", MAX(0, 16-nchars), ""); + + if (native<0) { + printf("0x"); + for (j=0; j<dst_size; j++) { + printf("%02x", value[i*dst_size+j]); + } + } else if (H5T_SGN_NONE==H5Tget_sign(native)) { + printf("%"PRINTF_LL_WIDTH"u", + *((unsigned long_long*)((void*)(value+i*dst_size)))); + } else { + printf("%"PRINTF_LL_WIDTH"d", + *((long_long*)((void*)(value+i*dst_size)))); + } + } + + /* Release resources */ + for (i=0; i<nmembs; i++) free(name[i]); + free(name); + free(value); + H5Tclose(super); + + if (0==nmembs) printf("\n%*s <empty>", ind+4, ""); + printf("\n%*s}", ind, ""); + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_string_type + * + * Purpose: Print information about a string data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_string_type(hid_t type, int UNUSED ind) +{ + H5T_str_t pad; + const char *pad_s=NULL; + H5T_cset_t cset; + const char *cset_s=NULL; + + if (H5T_STRING!=H5Tget_class(type)) return FALSE; + + /* Padding */ + pad = H5Tget_strpad(type); + switch (pad) { + case H5T_STR_NULLTERM: + pad_s = "null-terminated"; + break; + case H5T_STR_NULLPAD: + pad_s = "null-padded"; + break; + case H5T_STR_SPACEPAD: + pad_s = "space-padded"; + break; + case H5T_STR_RESERVED_3: + case H5T_STR_RESERVED_4: + case H5T_STR_RESERVED_5: + case H5T_STR_RESERVED_6: + case H5T_STR_RESERVED_7: + case H5T_STR_RESERVED_8: + case H5T_STR_RESERVED_9: + case H5T_STR_RESERVED_10: + case H5T_STR_RESERVED_11: + case H5T_STR_RESERVED_12: + case H5T_STR_RESERVED_13: + case H5T_STR_RESERVED_14: + case H5T_STR_RESERVED_15: + case H5T_STR_ERROR: + pad_s = "unknown-format"; + break; + } + + /* Character set */ + cset = H5Tget_cset(type); + switch (cset) { + case H5T_CSET_ASCII: + cset_s = "ASCII"; + break; + case H5T_CSET_RESERVED_1: + case H5T_CSET_RESERVED_2: + case H5T_CSET_RESERVED_3: + case H5T_CSET_RESERVED_4: + case H5T_CSET_RESERVED_5: + case H5T_CSET_RESERVED_6: + case H5T_CSET_RESERVED_7: + case H5T_CSET_RESERVED_8: + case H5T_CSET_RESERVED_9: + case H5T_CSET_RESERVED_10: + case H5T_CSET_RESERVED_11: + case H5T_CSET_RESERVED_12: + case H5T_CSET_RESERVED_13: + case H5T_CSET_RESERVED_14: + case H5T_CSET_RESERVED_15: + case H5T_CSET_ERROR: + cset_s = "unknown-character-set"; + break; + } + + printf("%lu-byte %s %s string", + (unsigned long)H5Tget_size(type), pad_s, cset_s); + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_reference_type + * + * Purpose: Prints information about a reference data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * Robb Matzke, 1999-06-04 + * Knows about object and dataset region references. + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_reference_type(hid_t type, int UNUSED ind) +{ + if (H5T_REFERENCE!=H5Tget_class(type)) return FALSE; + + if (H5Tequal(type, H5T_STD_REF_OBJ)) { + printf("object reference"); + } else if (H5Tequal(type, H5T_STD_REF_DSETREG)) { + printf("dataset region reference"); + } else { + printf("%lu-byte unknown reference", + (unsigned long)H5Tget_size(type)); + } + + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_opaque_type + * + * Purpose: Prints information about an opaque data type. + * + * Return: Success: TRUE + * + * Failure: FALSE, nothing printed + * + * Programmer: Robb Matzke + * Monday, June 7, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +display_opaque_type(hid_t type, int ind) +{ + char *tag; + size_t size; + + if (H5T_OPAQUE!=H5Tget_class(type)) return FALSE; + + size = H5Tget_size(type); + printf("%lu-byte opaque type", (unsigned long)size); + if ((tag=H5Tget_tag(type))) { + printf("\n%*s(tag = \"", ind, ""); + display_string(stdout, tag, FALSE); + printf("\")"); + free(tag); + } + return TRUE; +} + +/*------------------------------------------------------------------------- + * Function: display_vlen_type + * + * Purpose: Print information about a variable-length type + * + * Return: Success: TRUE + * + * Failure: FALSE + * + * Programmer: Robb Matzke + * Friday, December 1, 2000 + * + * Modifications: + *------------------------------------------------------------------------- + */ +static hbool_t +display_vlen_type(hid_t type, int ind) +{ + hid_t super; + + if (H5T_VLEN!=H5Tget_class(type)) return FALSE; + + printf("variable length of\n%*s", ind+4, ""); + super = H5Tget_super(type); + display_type(super, ind+4); + H5Tclose(super); + return TRUE; +} + + +/*------------------------------------------------------------------------- + * Function: display_type + * + * Purpose: Prints a data type definition. The definition is printed + * without any leading space or trailing line-feed (although + * there might be line-feeds inside the type definition). The + * first line is assumed to have IND characters before it on + * the same line (printed by the caller). + * + * Return: void + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * Robb Matzke, 1999-06-11 + * Prints the OID of shared data types. + * + *------------------------------------------------------------------------- + */ +static void +display_type(hid_t type, int ind) +{ + H5T_class_t data_class = H5Tget_class(type); + H5G_stat_t sb; + + /* Bad data type */ + if (type<0) { + printf("<ERROR>"); + return; + } + + /* Shared? If so then print the type's OID */ + if (H5Tcommitted(type)) { + if (H5Gget_objinfo(type, ".", FALSE, &sb)>=0) { + printf("shared-%lu:%lu:%lu:%lu ", + sb.fileno[1], sb.fileno[0], + sb.objno[1], sb.objno[0]); + } else { + printf("shared "); + } + } + + /* Print the type */ + if (display_native_type(type, ind) || + display_ieee_type(type, ind) || + display_int_type(type, ind) || + display_float_type(type, ind) || + display_cmpd_type(type, ind) || + display_enum_type(type, ind) || + display_string_type(type, ind) || + display_reference_type(type, ind) || + display_vlen_type(type, ind) || + display_opaque_type(type, ind)) { + return; + } + + /* Unknown type */ + printf("%lu-byte class-%u unknown", + (unsigned long)H5Tget_size(type), + (unsigned)data_class); +} + + +/*------------------------------------------------------------------------- + * Function: dump_dataset_values + * + * Purpose: Prints all values of a dataset. + * + * Return: void + * + * Programmer: Robb Matzke + * Tuesday, July 21, 1998 + * + * Modifications: + * Robb Matzke, 1999-09-27 + * Understands the simple_output_g switch which causes data to + * be displayed in a more machine-readable format. + *------------------------------------------------------------------------- + */ +static void +dump_dataset_values(hid_t dset) +{ + hid_t f_type = H5Dget_type(dset); + size_t size = H5Tget_size(f_type); + h5dump_t info; + char string_prefix[64]; + static char fmt_double[16], fmt_float[16]; + + /* Set to all default values and then override */ + memset(&info, 0, sizeof info); + + if (simple_output_g) { + info.idx_fmt = ""; + info.line_ncols = 65535; /*something big*/ + info.line_per_line = 1; + info.line_multi_new = 0; + info.line_pre = " "; + info.line_cont = " "; + + info.arr_pre = ""; + info.arr_suf = ""; + info.arr_sep = " "; + + info.cmpd_pre = ""; + info.cmpd_suf = ""; + info.cmpd_sep = " "; + + if (label_g) info.cmpd_name = "%s="; + + info.elmt_suf1 = " "; + info.str_locale = ESCAPE_HTML; + + } else { + info.idx_fmt = "(%s)"; + info.line_ncols = width_g; + info.line_multi_new = 1; + if (label_g) info.cmpd_name = "%s="; + info.line_pre = " %s "; + info.line_cont = " %s "; + info.str_repeat = 8; + } + + /* Floating point types should display full precision */ + sprintf(fmt_float, "%%1.%dg", FLT_DIG); + info.fmt_float = fmt_float; + sprintf(fmt_double, "%%1.%dg", DBL_DIG); + info.fmt_double = fmt_double; + + info.dset_format = "DSET-%lu:%lu:%lu:%lu-"; + info.dset_hidefileno = 0; + + info.obj_format = "-%lu:%lu:%lu:%lu"; + info.obj_hidefileno = 0; + + info.dset_blockformat_pre = "%sBlk%lu: "; + info.dset_ptformat_pre = "%sPt%lu: "; + + info.line_indent = ""; + + if (hexdump_g) { + /* + * Print all data in hexadecimal format if the `-x' or `--hexdump' + * command line switch was given. + */ + info.raw = TRUE; + } else if (string_g && 1==size && H5T_INTEGER==H5Tget_class(f_type)) { + /* + * Print 1-byte integer data as an ASCI character string instead of + * integers if the `-s' or `--string' command-line option was given. + */ + info.ascii = TRUE; + info.elmt_suf1 = ""; + info.elmt_suf2 = ""; + strcpy(string_prefix, info.line_pre); + strcat(string_prefix, "\""); + info.line_pre = string_prefix; + info.line_suf = "\""; + } + + /* + * Print all the values. + */ + printf(" Data:\n"); + if (h5dump_dset(stdout, &info, dset, -1, -1)<0) { + printf(" Unable to print data.\n"); + } + + H5Tclose(f_type); +} + + +/*------------------------------------------------------------------------- + * Function: list_attr + * + * Purpose: Prints information about attributes. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Friday, June 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +list_attr (hid_t obj, const char *attr_name, void UNUSED *op_data) +{ + hid_t attr, space, type, p_type; + hsize_t size[64], nelmts=1; + int ndims, i, n; + size_t need; + void *buf; + h5dump_t info; + + printf(" Attribute: "); + n = display_string(stdout, attr_name, TRUE); + printf("%*s", MAX(0, 9-n), ""); + if ((attr = H5Aopen_name(obj, attr_name))) { + space = H5Aget_space(attr); + type = H5Aget_type(attr); + + /* Data space */ + ndims = H5Sget_simple_extent_dims(space, size, NULL); + if (0==ndims) { + puts(" scalar"); + } else { + printf(" {"); + for (i=0; i<ndims; i++) { + HDfprintf(stdout, "%s%Hu", i?", ":"", size[i]); + nelmts *= size[i]; + } + puts("}"); + } + + /* Data type */ + printf(" Type: "); + display_type(type, 15); + putchar('\n'); + + /* Data */ + memset(&info, 0, sizeof info); + info.line_multi_new = 1; + if (nelmts<5) { + info.idx_fmt = ""; + info.line_1st = " Data: "; + info.line_pre = " "; + info.line_cont = " "; + info.str_repeat = 8; + + } else { + printf(" Data:\n"); + info.idx_fmt = "(%s)"; + info.line_pre = " %s "; + info.line_cont = " %s "; + info.str_repeat = 8; + } + info.line_ncols = width_g; + if (label_g) info.cmpd_name = "%s="; + if (string_g && 1==H5Tget_size(type) && + H5T_INTEGER==H5Tget_class(type)) { + info.ascii = TRUE; + info.elmt_suf1 = ""; + info.elmt_suf2 = ""; + info.idx_fmt = "(%s)"; + info.line_pre = " %s \""; + info.line_suf = "\""; + } + if (hexdump_g) { + p_type = H5Tcopy(type); + } else { + p_type = h5dump_fixtype(type); + } + if (p_type>=0) { + need = nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type)); + buf = malloc(need); + assert(buf); + if (H5Aread(attr, p_type, buf)>=0) { + h5dump_mem(stdout, &info, attr, p_type, space, buf,-1); + } + free(buf); + H5Tclose(p_type); + } + + H5Sclose(space); + H5Tclose(type); + H5Aclose(attr); + } else { + putchar('\n'); + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: dataset_list1 + * + * Purpose: List information about a dataset which should appear on the + * same line as the dataset name. This information will precede + * information which is applicable to all objects which will be + * printed by the caller. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +dataset_list1(hid_t dset) +{ + hsize_t cur_size[64]; /*current dataset dimensions */ + hsize_t max_size[64]; /*maximum dataset dimensions */ + hid_t space; /*data space */ + int ndims; /*dimensionality */ + int i; + + /* + * Information that goes on the same row as the name. The name has + * already been printed. + */ + space = H5Dget_space(dset); + ndims = H5Sget_simple_extent_dims(space, cur_size, max_size); + printf (" {"); + for (i=0; i<ndims; i++) { + HDfprintf (stdout, "%s%Hu", i?", ":"", cur_size[i]); + if (max_size[i]==H5S_UNLIMITED) { + HDfprintf (stdout, "/%s", "Inf"); + } else if (max_size[i]!=cur_size[i] || verbose_g>0) { + HDfprintf(stdout, "/%Hu", max_size[i]); + } + } + if (0==ndims) printf("SCALAR"); + putchar('}'); + H5Sclose (space); + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: dataset_list2 + * + * Purpose: List information about a dataset which should appear after + * information which is general to all objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +dataset_list2(hid_t dset, const char UNUSED *name) +{ + hid_t dcpl; /*dataset creation property list*/ + hid_t type; /*data type of dataset */ + hid_t space; /*data space of dataset */ + int nf; /*number of filters */ + unsigned filt_flags; /*filter flags */ + H5Z_filter_t filt_id; /*filter identification number */ + unsigned cd_values[20]; /*filter client data values */ + size_t cd_nelmts; /*filter client number of values*/ + size_t cd_num; /*filter client data counter */ + char f_name[256]; /*filter/file name */ + char s[64]; /*temporary string buffer */ + off_t f_offset; /*offset in external file */ + hsize_t f_size; /*bytes used in external file */ + hsize_t total, used; /*total size or offset */ + hsize_t chsize[64]; /*chunk size in elements */ + int ndims; /*dimensionality */ + int n, max_len; /*max extern file name length */ + double utilization; /*percent utilization of storage*/ + int i; + + if (verbose_g>0) { + dcpl = H5Dget_create_plist(dset); + space = H5Dget_space(dset); + type = H5Dget_type(dset); + + /* Print information about chunked storage */ + if (H5D_CHUNKED==H5Pget_layout(dcpl)) { + ndims = H5Pget_chunk(dcpl, NELMTS(chsize), chsize/*out*/); + printf(" %-10s {", "Chunks:"); + total = H5Tget_size(type); + for (i=0; i<ndims; i++) { + printf("%s%lu", i?", ":"", (unsigned long)(chsize[i])); + total *= chsize[i]; + } + printf("} %lu bytes\n", (unsigned long)total); + } + + /* Print total raw storage size */ + used = H5Sget_simple_extent_npoints(space) * H5Tget_size(type); + total = H5Dget_storage_size(dset); + printf(" %-10s ", "Storage:"); + printf("%lu logical byte%s, %lu allocated byte%s", + (unsigned long)used, 1==used?"":"s", + (unsigned long)total, 1==total?"":"s"); + if (total>0) { +#ifdef WIN32 + hsize_t mask = (hsize_t)1 << (8*sizeof(hsize_t)-1); + if ((used & mask) || (total & mask)) { + total = 0; /*prevent utilization printing*/ + } else { + utilization = (hssize_t)used*100.0 /(hssize_t)total; + } +#else + utilization = (used*100.0)/total; +#endif + printf(", %1.2f%% utilization", utilization/*(used*100.0)/total*/); + } + putchar('\n'); + + /* Print information about external strorage */ + if ((nf = H5Pget_external_count(dcpl))>0) { + for (i=0, max_len=0; i<nf; i++) { + H5Pget_external(dcpl, i, sizeof(f_name), f_name, NULL, NULL); + n = display_string(NULL, f_name, TRUE); + max_len = MAX(max_len, n); + } + printf(" %-10s %d external file%s\n", + "Extern:", nf, 1==nf?"":"s"); + printf(" %4s %10s %10s %10s %s\n", + "ID", "DSet-Addr", "File-Addr", "Bytes", "File"); + printf(" %4s %10s %10s %10s ", + "----", "----------", "----------", "----------"); + for (i=0; i<max_len; i++) putchar('-'); + putchar('\n'); + for (i=0, total=0; i<nf; i++) { + if (H5Pget_external(dcpl, i, sizeof(f_name), f_name, &f_offset, + &f_size)<0) { + HDfprintf(stdout, + " #%03d %10Hu %10s %10s ***ERROR*** %s\n", + i, total, "", "", + i+1<nf?"Following addresses are incorrect":""); + } else if (H5S_UNLIMITED==f_size) { + HDfprintf(stdout, " #%03d %10Hu %10Hu %10s ", + i, total, (hsize_t)f_offset, "INF"); + display_string(stdout, f_name, TRUE); + } else { + HDfprintf(stdout, " #%03d %10Hu %10Hu %10Hu ", + i, total, (hsize_t)f_offset, f_size); + display_string(stdout, f_name, TRUE); + } + putchar('\n'); + total += f_size; + } + printf(" %4s %10s %10s %10s ", + "----", "----------", "----------", "----------"); + for (i=0; i<max_len; i++) putchar('-'); + putchar('\n'); + } + + /* Print information about raw data filters */ + if ((nf = H5Pget_nfilters(dcpl))>0) { + for (i=0; i<nf; i++) { + cd_nelmts = NELMTS(cd_values); + filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts, + cd_values, sizeof(f_name), f_name); + f_name[sizeof(f_name)-1] = '\0'; + sprintf(s, "Filter-%d:", i); + printf(" %-10s %s-%u %s {", s, + f_name[0]?f_name:"method", + (unsigned)filt_id, + filt_flags & H5Z_FLAG_OPTIONAL?"OPT":""); + for (cd_num=0; cd_num<cd_nelmts; cd_num++) { + printf("%s%u", cd_num?", ":"", cd_values[cd_num]); + } + printf("}\n"); + } + } + + /* Print data type */ + printf(" %-10s ", "Type:"); + display_type(type, 15); + printf("\n"); + + /* Print address information */ + if (address_g) H5Ddebug(dset, 0); + + /* Close stuff */ + H5Tclose(type); + H5Sclose(space); + H5Pclose(dcpl); + } + + if (data_g) dump_dataset_values(dset); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: group_list2 + * + * Purpose: List information about a group which should appear after + * information which is general to all objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, January 21, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +group_list2(hid_t grp, const char *name) +{ + iter_t iter; + + if (recursive_g) { + iter.container = name; + H5Giterate(grp, ".", NULL, list, &iter); + } + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: datatype_list2 + * + * Purpose: List information about a data type which should appear after + * information which is general to all objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +datatype_list2(hid_t type, const char UNUSED *name) +{ + if (verbose_g>0) { + printf(" %-10s ", "Type:"); + display_type(type, 15); + printf("\n"); + } + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: link_open + * + * Purpose: This gets called to open a symbolic link. Since symbolic + * links don't correspond to actual objects we simply print the + * link information and return failure. + * + * Return: Success: 0 - an invalid object but successful return + * of this function. + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hid_t +link_open(hid_t location, const char *name) +{ + char buf[64]; + + if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1; + if (NULL==HDmemchr(buf, 0, sizeof(buf))) { + strcpy(buf+sizeof(buf)-4, "..."); + } + fputs(buf, stdout); + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: list + * + * Purpose: Prints the group member name. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Monday, March 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +list (hid_t group, const char *name, void *_iter) +{ + hid_t obj=-1; + char buf[512], comment[50], *fullname=NULL, *s=NULL; + H5G_stat_t sb; + struct tm *tm; + herr_t status; + iter_t *iter = (iter_t*)_iter; + int n; + + /* Print the object name, either full name or base name */ + fullname = fix_name(iter->container, name); + if (fullname_g) { + n = display_string(stdout, fullname, TRUE); + printf("%*s ", MAX(0, 24-n), ""); + } else { + n = display_string(stdout, name, TRUE); + printf("%*s ", MAX(0, 24-n), ""); + } + + /* Get object information */ + H5E_BEGIN_TRY { + status = H5Gget_objinfo(group, name, FALSE, &sb); + } H5E_END_TRY; + if (status<0) { + puts("**NOT FOUND**"); + return 0; + } else if (sb.type<0 || sb.type>=H5G_NTYPES) { + printf("Unknown type(%d)", sb.type); + sb.type = -1; + } + if (sb.type>=0 && dispatch_g[sb.type].name) { + fputs(dispatch_g[sb.type].name, stdout); + } + + /* + * If the object has already been printed then just show the object ID + * and return. + */ + if ((s=sym_lookup(&sb))) { + printf(", same as "); + display_string(stdout, s, TRUE); + printf("\n"); + goto done; + } else { + sym_insert(&sb, fullname); + } + + /* + * Open the object. Not all objects can be opened. If this is the case + * then return right away. + */ + if (sb.type>=0 && + (NULL==dispatch_g[sb.type].open || + (obj=(dispatch_g[sb.type].open)(group, name))<0)) { + printf(" *ERROR*\n"); + goto done; + } + + /* + * List the first line of information for the object. + */ + if (sb.type>=0 && dispatch_g[sb.type].list1) { + (dispatch_g[sb.type].list1)(obj); + } + putchar('\n'); + + /* + * Show detailed information about the object, beginning with information + * which is common to all objects. + */ + if (verbose_g>0 && H5G_LINK!=sb.type) { + if (sb.type>=0) H5Aiterate(obj, NULL, list_attr, NULL); + printf(" %-10s %lu:%lu:%lu:%lu\n", "Location:", + sb.fileno[1], sb.fileno[0], sb.objno[1], sb.objno[0]); + printf(" %-10s %u\n", "Links:", sb.nlink); + if (sb.mtime>0 && NULL!=(tm=localtime(&(sb.mtime)))) { + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); + printf(" %-10s %s\n", "Modified:", buf); + } + comment[0] = '\0'; + H5Gget_comment(group, name, sizeof(comment), comment); + strcpy(comment+sizeof(comment)-4, "..."); + if (comment[0]) { + printf(" %-10s \"", "Comment:"); + display_string(stdout, comment, FALSE); + puts("\""); + } + } + if (sb.type>=0 && dispatch_g[sb.type].list2) { + (dispatch_g[sb.type].list2)(obj, fullname); + } + + /* + * Close the object. + */ + done: + if (sb.type>=0 && obj>=0 && dispatch_g[sb.type].close) { + (dispatch_g[sb.type].close)(obj); + } + if (fullname) free(fullname); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: fix_name + * + * Purpose: Returns a malloc'd buffer that contains the PATH and BASE + * names separated by a single slash. It also removes duplicate + * and trailing slashes. + * + * Return: Success: Ptr to fixed name from malloc() + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, January 21, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static char * +fix_name(const char *path, const char *base) +{ + size_t n = (path?strlen(path):0) + (base?strlen(base):0) + 3; + char *s = malloc(n), prev='\0'; + int len=0; + + if (path) { + /* Path, followed by slash */ +#ifdef H5LS_PREPEND_FILENAME + if ('/'!=*path) s[len++] = '/'; +#endif + for (/*void*/; *path; path++) { + if ('/'!=*path || '/'!=prev) prev = s[len++] = *path; + } + if ('/'!=prev) prev = s[len++] = '/'; + } + + if (base) { + /* Base name w/o trailing slashes */ + const char *end = base + strlen(base); + while (end>base && '/'==end[-1]) --end; + for (/*void*/; base<end; base++) { + if ('/'!=*base || '/'!=prev) prev = s[len++] = *base; + } + } + + s[len] = '\0'; + return s; +} + + +/*------------------------------------------------------------------------- + * Function: get_width + * + * Purpose: Figure out how wide the screen is. This is highly + * unportable, but the user can always override the width we + * detect by giving a command-line option. These code snippets + * were borrowed from the GNU less(1). + * + * Return: Success: Number of columns. + * + * Failure: Some default number of columms. + * + * Programmer: Robb Matzke + * Friday, November 6, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +get_width(void) +{ + int width = 80; /*the default */ + char *s; + + /* + * Try to get it from the COLUMNS environment variable first since it's + * value is sometimes wrong. + */ + if ((s=getenv("COLUMNS")) && *s && isdigit((int)*s)) { + width = (int)strtol(s, NULL, 0); + } + +#if defined(H5_HAVE_STRUCT_VIDEOCONFIG) && defined(H5_HAVE__GETVIDEOCONFIG) + { + /* Microsoft C */ + struct videoconfig w; + _getvideoconfig(&w); + width = w.numtextcols; + } +#elif defined(H5_HAVE_STRUCT_TEXT_INFO) && defined(H5_HAVE_GETTEXTINFO) + { + /* Borland C or DJGPPC */ + struct text_info w; + gettextinfo(&w); + width = w.screenwidth; + } +#elif defined(H5_HAVE_GETCONSOLESCREENBUFFERINFO) + { + /* Win32 C */ + CONSOLE_SCREEN_BUFFER_INFO scr; + GetConsoleScreenBufferInfo(con_out, &scr); + width = scr.srWindow.Right - scr.srWindow.Left + 1; + } +#elif defined(H5_HAVE__SCRSIZE) + { + /* OS/2 */ + int w[2]; + _scrsize(w); + width = w[0]; + } +#elif defined(H5_HAVE_TIOCGWINSZ) && defined(H5_HAVE_IOCTL) +#ifndef __PUMAGON__ +/* the ioctl() call coredump on TFLOPS. Turn it off for now. */ + { + /* Unix with ioctl(TIOCGWINSZ) */ + struct winsize w; + if (ioctl(2, TIOCGWINSZ, &w)>=0 && w.ws_col>0) { + width = w.ws_col; + } + } +#endif +#elif defined(H5_HAVE_TIOCGETD) && defined(H5_HAVE_IOCTL) + { + /* Unix with ioctl(TIOCGETD) */ + struct uwdata w; + if (ioctl(2, WIOCGETD, &w)>=0 && w.uw_width>0) { + width = w.uw_width / w.uw_hs; + } + } +#endif + + /* Set to at least 1 */ + if (width<1) width = 1; + return width; +} + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Opens a file and lists the specified group + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Robb Matzke + * Monday, March 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +main (int argc, char *argv[]) +{ + hid_t file=-1, root=-1; + char *fname=NULL, *oname=NULL, *x; + const char *progname="h5ls"; + const char *s = NULL; + char *rest, *container=NULL; + int argno; + H5G_stat_t sb; + iter_t iter; + static char root_name[] = "/"; + char drivername[50]; + + /* Initialize h5tools lib */ + h5tools_init(); + + /* Build display table */ + DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose, + dataset_list1, dataset_list2); + DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose, + NULL, group_list2); + DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose, + NULL, datatype_list2); + DISPATCH(H5G_LINK, "-> ", link_open, NULL, + NULL, NULL); + +#if 0 + /* Name of this program without the path */ + if ((progname=strrchr(argv[0], '/'))) progname++; + else progname = argv[0]; +#endif + + /* Default output width */ + width_g = get_width(); + + /* Switches come before non-switch arguments */ + for (argno=1; argno<argc && '-'==argv[argno][0]; argno++) { + if (!strcmp(argv[argno], "--")) { + /* Last switch */ + argno++; + break; + } else if (!strcmp(argv[argno], "--help")) { + usage(progname); + exit(0); + } else if (!strcmp(argv[argno], "--address")) { + address_g = TRUE; + } else if (!strcmp(argv[argno], "--data")) { + data_g = TRUE; + } else if (!strcmp(argv[argno], "--errors")) { + show_errors_g = TRUE; + } else if (!strcmp(argv[argno], "--full")) { + fullname_g = TRUE; + } else if (!strcmp(argv[argno], "--group")) { + grp_literal_g = TRUE; + } else if (!strcmp(argv[argno], "--label")) { + label_g = TRUE; + } else if (!strcmp(argv[argno], "--recursive")) { + recursive_g = TRUE; + fullname_g = TRUE; + } else if (!strcmp(argv[argno], "--simple")) { + simple_output_g = TRUE; + } else if (!strcmp(argv[argno], "--string")) { + string_g = TRUE; + } else if (!strncmp(argv[argno], "--width=", 8)) { + width_g = (int)strtol(argv[argno]+8, &rest, 0); + if (width_g<=0 || *rest) { + usage(progname); + exit(1); + } + } else if (!strcmp(argv[argno], "--width")) { + if (argno+1>=argc) { + usage(progname); + exit(1); + } else { + s = argv[++argno]; + } + width_g = (int)strtol(s, &rest, 0); + if (width_g<=0 || *rest) { + usage(progname); + exit(1); + } + } else if (!strcmp(argv[argno], "--verbose")) { + verbose_g++; + } else if (!strcmp(argv[argno], "--version")) { + print_version(progname); + exit(0); + } else if (!strcmp(argv[argno], "--hexdump")) { + hexdump_g = TRUE; + } else if (!strncmp(argv[argno], "-w", 2)) { + if (argv[argno][2]) { + s = argv[argno]+2; + } else if (argno+1>=argc) { + usage(progname); + exit(1); + } else { + s = argv[++argno]; + } + width_g = (int)strtol(s, &rest, 0); + if (width_g<=0 || *rest) { + usage(progname); + exit(1); + } + } else if ('-'!=argv[argno][1]) { + /* Single-letter switches */ + for (s=argv[argno]+1; *s; s++) { + switch (*s) { + case '?': + case 'h': /* --help */ + usage(progname); + exit(0); + case 'a': /* --address */ + address_g = TRUE; + break; + case 'd': /* --data */ + data_g = TRUE; + break; + case 'e': /* --errors */ + show_errors_g = TRUE; + break; + case 'f': /* --full */ + fullname_g = TRUE; + break; + case 'g': /* --group */ + grp_literal_g = TRUE; + break; + case 'l': /* --label */ + label_g = TRUE; + break; + case 'r': /* --recursive */ + recursive_g = TRUE; + fullname_g = TRUE; + break; + case 'S': /* --simple */ + simple_output_g = TRUE; + break; + case 's': /* --string */ + string_g = TRUE; + break; + case 'v': /* --verbose */ + verbose_g++; + break; + case 'V': /* --version */ + print_version(progname); + exit(0); + case 'x': /* --hexdump */ + hexdump_g = TRUE; + break; + default: + usage(progname); + exit(1); + } + } + } else { + usage(progname); + exit(1); + } + } + + /* + * If no arguments remain then print a usage message (instead of doing + * absolutely nothing ;-) + */ + if (argno>=argc) { + usage(progname); + exit(1); + } + + /* Turn off HDF5's automatic error printing unless you're debugging h5ls */ + if (!show_errors_g) H5Eset_auto(NULL, NULL); + + + /* + * Each remaining argument is an hdf5 file followed by an optional slash + * and object name. + * + * Example: ../dir1/foo/bar/baz + * \_________/\______/ + * file obj + * + * The dichotomy is determined by calling H5Fopen() repeatedly until it + * succeeds. The first call uses the entire name and each subsequent call + * chops off the last component. If we reach the beginning of the name + * then there must have been something wrong with the file (perhaps it + * doesn't exist). + */ + while (argno<argc) { + fname = argv[argno++]; + oname = NULL; + file = -1; + + while (fname && *fname) { + file = h5dump_fopen(fname, drivername, sizeof drivername); + if (file>=0) { + if (verbose_g) { + printf("Opened \"%s\" with %s driver.\n", + fname, drivername); + } + break; /*success*/ + } + + /* Shorten the file name; lengthen the object name */ + x = oname; + oname = strrchr(fname, '/'); + if (x) *x = '/'; + if (!oname) break; + *oname = '\0'; + } + if (file<0) { + fprintf(stderr, "%s: unable to open file\n", argv[argno-1]); + continue; + } + if (oname) oname++; + if (!oname || !*oname) oname = root_name; + + /* Open the object and display it's information */ + if (H5Gget_objinfo(file, oname, TRUE, &sb)>=0 && + H5G_GROUP==sb.type && !grp_literal_g) { + /* + * Specified name is a group. List the complete contents of the + * group. + */ + sym_insert(&sb, oname); +#ifdef H5LS_PREPEND_FILENAME + iter.container = container = fix_name(fname, oname); +#else + iter.container = container = fix_name("", oname); +#endif + H5Giterate(file, oname, NULL, list, &iter); + free(container); + + } else if ((root=H5Gopen(file, "/"))<0) { + exit(1); /*major problem!*/ + + } else { + /* + * Specified name is a non-group object -- list that object. The + * container for the object is everything up to the base name. + */ +#ifdef H5LS_PREPEND_FILENAME + iter.container = fname; +#else + iter.container = "/"; +#endif + list(root, oname, &iter); + if (H5Gclose(root)<0) exit(1); + } + H5Fclose(file); + } + h5tools_close(); + + return 0; +} diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh new file mode 100755 index 0000000..cb3f99f --- /dev/null +++ b/tools/h5ls/testh5ls.sh @@ -0,0 +1,143 @@ +#! /bin/sh +# +# Copyright (C) 2001 National Center for Supercomputing Applications +# All rights reserved. +# +# Tests for the h5ls tool + +H5LS=h5ls # The tool name +H5LS_BIN=`pwd`/$H5LS # The path of the tool binary + +CMP='cmp -s' +DIFF='diff -c' +NLINES=20 # Max. lines of output to display if test fails + +nerrors=0 +verbose=yes + +# The build (current) directory might be different than the source directory. +if test -z "$srcdir"; then + srcdir=. +fi +test -d ../testfiles || mkdir ../testfiles + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" |cut -c1-70 |tr -d '\012' +} + +# Run a test and print PASS or *FAIL*. For now, if h5ls can complete +# with exit status 0, consider it pass. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display up to $NLINS +# lines of the actual output from the tool test. The actual output is not +# removed if $HDF5_NOCLEANUP has a non-zero value. +# Arguemnts: +# $1 -- actual output filename to use +# $2 and on -- argument for the h5ls tool +TOOLTEST() { + expect="$srcdir/../testfiles/$1" + actual="../testfiles/`basename $1 .ls`.out" + shift + + # Run test. + # Stderr is included in stdout so that the diff can detect + # any unexpected output from that stream too. + TESTING $H5LS $@ + ( + echo "#############################" + echo " output for '$H5LS $@'" + echo "#############################" + cd $srcdir/../testfiles + $RUNSERIAL $H5LS_BIN "$@" + ) >$actual 2>&1 + + exitcode=$? + if [ $exitcode -ne 0 ]; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + if [ yes = "$verbose" ]; then + echo "test returned with exit code $exitcode" + echo "test output: (up to $NLINES lines)" + head -$NLINES $actual + echo "***end of test output***" + echo "" + fi + elif [ ! -f $expect ]; then + # Create the expect file if it doesn't yet exist. + echo " CREATED" + cp $actual $expect + elif $CMP $expect $actual; then + echo " PASSED" + else + echo "*FAILED*" + echo " Expected result differs from actual result" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + rm -f $actual + fi +} + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + +# Toss in a bunch of tests. Not sure if they are the right kinds. +# test the help syntax +TOOLTEST help-1.ls -w80 -h +TOOLTEST help-2.ls -w80 -help +TOOLTEST help-3.ls -w80 -? + +# test simple command +TOOLTEST tall-1.ls -w80 tall.h5 +TOOLTEST tall-2.ls -w80 -r -d tall.h5 +TOOLTEST tgroup.ls -w80 tgroup.h5 + +# test for displaying groups +TOOLTEST tgroup-1.ls -w80 -r -g tgroup.h5 + +# test for displaying simple space datasets +TOOLTEST tdset-1.ls -w80 -r -d tdset.h5 + +# test for displaying soft links +TOOLTEST tslink-1.ls -w80 -r tslink.h5 + +# tests for hard links +TOOLTEST thlink-1.ls -w80 thlink.h5 + +# tests for compound data types +TOOLTEST tcomp-1.ls -w80 -r -d tcompound.h5 + +#test for the nested compound type +TOOLTEST tnestcomp-1.ls -w80 -r -d tnestedcomp.h5 + +# test for loop detection +TOOLTEST tloop-1.ls -w80 -r -d tloop.h5 + +# test for string +TOOLTEST tstr-1.ls -w80 -r -d tstr.h5 + +# test test file created from lib SAF team +TOOLTEST tsaf.ls -w80 -r -d tsaf.h5 + +# test for variable length data types +TOOLTEST tvldtypes1.ls -w80 -r -d tvldtypes1.h5 + +# test for array data types +TOOLTEST tarray1.ls -w80 -r -d tarray1.h5 + +# test for empty data +TOOLTEST tempty.ls -w80 -d tempty.h5 + +if test $nerrors -eq 0 ; then + echo "All h5ls tests passed." +fi + +exit $nerrors diff --git a/tools/h5toh4/Dependencies b/tools/h5toh4/Dependencies new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/h5toh4/Dependencies diff --git a/tools/h5toh4/Makefile.in b/tools/h5toh4/Makefile.in new file mode 100644 index 0000000..4c529d6 --- /dev/null +++ b/tools/h5toh4/Makefile.in @@ -0,0 +1,60 @@ +## HDF5 Library Makefile(.in) +## +## Copyright (C) 2001 National Center for Supercomputing Applications. +## All rights reserved. +## +## +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +SUBDIRS= +@COMMENCE@ + +## Add include directory to the C preprocessor flags, add -lh5tools and +## -lhdf5 to the list of libraries. +## +CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src \ + -I$(top_srcdir)/tools/lib @CPPFLAGS@ + +## Test programs and scripts. +## +TEST_PROGS= +TEST_SCRIPTS=@TESTH5TOH4@ + +## These are our main targets: library and tools. +## +LIBTOOLS=../lib/libh5tools.la +LIBHDF5=$(top_builddir)/src/libhdf5.la +PUB_PROGS=@H5TOH4@ +PROGS=$(PUB_PROGS) $(TEST_PROGS) + +## Source and object files for the library; do not install +## +LIB_SRC= +LIB_OBJ=$(LIB_SRC:.c=.lo) +PUB_LIB= + +## Source and object files for programs... +## +PROG_SRC=h5toh4.c +PROG_OBJ=$(PROG_SRC:.c=.lo) +PRIVATE_HDR=h5toh4.h + +## Source and object files for the tests +## +TEST_SRC= +TEST_OBJ=$(TEST_SRC:.c=.lo) + +## Programs have to be built before they can be tested! +## +check test _test: $(PROGS) + +## How to build the programs... They all depend on the hdf5 library and +## the tools library compiled in this directory. +## +$(PROGS): $(LIBTOOLS) $(LIBHDF5) + +h5toh4: h5toh4.lo + @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5toh4.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS) + +@CONCLUDE@ diff --git a/tools/h5toh4/h5toh4.c b/tools/h5toh4/h5toh4.c new file mode 100644 index 0000000..30b381c --- /dev/null +++ b/tools/h5toh4/h5toh4.c @@ -0,0 +1,2592 @@ +/****************************************************************************** + + Description: This file contains routines to translate H5 files to H4 files. + + Author: Paul Harten for the University of Illinois, NCSA + + Creation Date: 04 October 1998 + + History: + + +*****************************************************************************/ + +#include "h5toh4.h" +#include <errno.h> +#include <string.h> +#include <fcntl.h> +#include <h5tools.h> + + +#ifdef WIN32 +typedef unsigned int mode_t; +#endif + +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode)&0xF000) == S_IFDIR) +#endif +extern void PrintOptions_h5toh4(void); +extern char *BuildFilename(char *h5_filename, char *h4_extension); +extern int test_file(char *filename, int oflag, mode_t mode); +extern int test_dir(char *); +extern int h5toh4(char *, char *); + +extern herr_t convert_group(hid_t, char *, op_data_t *); +extern herr_t convert_dataset(hid_t, char *, op_data_t *); +extern herr_t convert_all(hid_t, char *, op_data_t *); +extern herr_t convert_attr(hid_t, char *, op_data_t *); +extern herr_t convert_shared_dataset(hid_t, int, op_data_t *); +extern herr_t convert_shared_group(hid_t, int, op_data_t *); +extern herr_t convert_dataset_string(hid_t, char *, op_data_t *); +extern int32 h5type_to_h4type(hid_t); +extern hid_t h4type_to_memtype(int32); + +extern void free_table(table_t **temp); +extern void dump_tables(char* name, table_t* table); +extern int get_table_idx(table_t*, unsigned long *); +extern int get_tableflag(table_t*, int); +extern int set_tableflag(table_t*, int); +extern char* get_objectname(table_t*, int); + +typedef herr_t (*H5G_operator_t)(hid_t, const char*, void*); + +static int prefix_len = 1024; +static char *prefix; +static table_t *group_table, *dset_table, *type_table; + +static herr_t h5atomic_type_to_h4type(const hid_t h5type, hid_t* h5memtype, size_t* h5memsize, int32* h4type); + + +/***************************************************************************** + + Routine: main() + + Description: This routine check out arguments sent, makes sure everything is + ok, chooses between the acceptable argument formats and then + calls h5toh4(). + + Input: arg - the number of arguments from the call + 1; + argv - a pointer to an array of strings which are the arguments. + This includes the routine name as the first string. + + Output: function return - error status + +*****************************************************************************/ + +int +main(int argc, char *argv[]) +{ + char *h5_filename=NULL; + char *h4_filename=NULL; + char *h4_extension; + int status = 0; + int status2 = 0; + + + argc--; + argv++; + + if (argc == 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h5toh4(); + return -1; + } + + /* take care -h (help) option first */ + { int i; + for (i=0; i < argc; i++) + if ( HDstrcmp(argv[i],"-h") == 0 ) { + PrintOptions_h5toh4(); + return 0; + } + } + + /*fargv = argv; */ + + /* Change -m with 1 filename to as 1 filename case */ + if (argc == 2 && HDstrcmp(argv[0],"-m") == 0) { + argv++; + argc--; + } + + switch(argc) { + + case 0: + + PrintOptions_h5toh4(); + break; + + case 1: /* h5toh4 file1 */ + h5_filename = argv[0]; + + if (HDstrcmp(h5_filename,"-m") == 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h5toh4(); + status = -1; + break; + } +#ifndef WIN32 + if (test_file(h5_filename,O_EXCL,(mode_t)(S_IRUSR|S_IRGRP|S_IROTH)) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } + if (test_dir(h5_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } +#endif + h4_extension = HDstrdup("hdf"); + + h4_filename = BuildFilename(h5_filename,h4_extension); + if (h4_filename == NULL) { + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } +#ifndef WIN32 + if (test_file(h4_filename,O_CREAT|O_EXCL,(mode_t)(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } +#endif + status = h5toh4(h5_filename, h4_filename); + if ( status != 0 ) { + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + } + if (h4_filename != NULL) { + HDfree(h4_filename); + } + + break; + + case 2: /* h5toh4 file_in file_out */ + h5_filename = argv[0]; + h4_filename = argv[1]; + + if (HDstrcmp(h4_filename,"-m") == 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h5toh4(); + status = -1; + break; + } +#ifndef WIN32 + if (test_file(h5_filename,O_EXCL,292) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } + if (test_dir(h5_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } + if (test_file(h4_filename,O_CREAT|O_RDWR,436) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } + if (test_dir(h4_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h4_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status = -1; + break; + } +#endif + status = h5toh4(h5_filename, h4_filename); + if ( status != 0 ) { + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + } + break; + + default: /* h5toh4 -m file1 file2 file3 ... */ + if (HDstrcmp(argv[0],"-m") != 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h5toh4(); + status = -1; + break; + } + argv++; + argc--; + + while ( argc > 0 ) { + h5_filename = argv[0]; + argv++; + argc--; + + if (HDstrcmp(h5_filename,"-m") == 0) { + fprintf(stderr,"\nError: Invalid Arguments\n"); + PrintOptions_h5toh4(); + status2 = -1; + break; + } +#ifndef WIN32 + if (test_file(h5_filename,O_EXCL,292) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status2 = -1; + continue; + } + if (test_dir(h5_filename) != 0 ) { + fprintf(stderr,"%s: Is a directory\n",h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status2 = -1; + continue; + } +#endif + h4_extension = HDstrdup("hdf"); + + h4_filename = BuildFilename(h5_filename,h4_extension); + if (h4_filename == NULL) { + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status2 = -1; + continue; + } +#ifndef WIN32 + if (test_file(h4_filename,O_CREAT|O_EXCL,436) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */ + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status2 = -1; + continue; + } +#endif + status = h5toh4(h5_filename, h4_filename); + if ( status != 0 ) { + fprintf(stderr,"Error: Problem with %s\n",h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__); + status2 = status; + } + if (h4_filename != NULL) { + HDfree(h4_filename); + } + + } + status = status2; + break; + } + + return status; + +} + + +/***************************************************************************** + + Routine: PrintOptions_h5toh4() + + Description: This routine prints the acceptable argument formats out to stderr. + + Input: None + + Output: output to stderr + +*****************************************************************************/ + +void PrintOptions_h5toh4(void) +{ + fprintf(stderr,"\nh5toh4 -h (gives this print-out)\n"); + fprintf(stderr,"h5toh4 file.h5 file.hdf\n"); + fprintf(stderr,"h5toh4 file.h5\n"); + fprintf(stderr,"h5toh4 -m file1.h5 file2.h5 ...\n\n"); +} + + +/***************************************************************************** + + Routine: h5toh4() + + Description: This routine translates information from a HDF5 file into a + HDF4 file. + + Input: h5_filename - filename of HDF5 file, + h4_filename - filename of HDF4 file + + Output: function return - error status + +*****************************************************************************/ + +int h5toh4(char *h5_filename, char *h4_filename) +{ + + hid_t fid, gid; + hid_t plist=H5P_DEFAULT; + int status = 0; + int32 hfile_id; + int32 sd_id; + op_data_t op_data; + void *edata; + hid_t (*func)(void*); + + + find_objs_t *info = malloc(sizeof(find_objs_t)); + + + + /* open hdf5 file */ + if ((fid = H5Fopen (h5_filename, H5F_ACC_RDONLY, plist)) <= 0) { + fprintf(stderr,"Error: Unable to open file %s\n",h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + return (fid); + } + + /* open root group */ + if ((gid = H5Gopen (fid, "/")) <= 0 ) { + fprintf(stderr,"Error: Unable to open root group\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + return (gid); + } else { + + /* open hdf4 file */ + if ((hfile_id = Hopen(h4_filename, DFACC_CREATE, 0)) <= 0) { + fprintf(stderr,"Error: Unable to open file %s\n", h4_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + return (hfile_id); + } else { + + if ((sd_id = SDstart(h4_filename, DFACC_RDWR)) <= 0) { + fprintf(stderr,"Error: Unable to open file %s, using SDstart\n", h4_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + return (sd_id); + } else { + + /* Initialize Vgroup interface */ + if ((status = Vstart(hfile_id)) != SUCCEED) { + fprintf(stderr,"Error: Unable to initialize Vgroup interface\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + + /* allocate and initialize internal data structure */ + init_table(&group_table); + init_table(&type_table); + init_table(&dset_table); + init_prefix(&prefix, prefix_len); + + /* init the find_objs_t*/ + info->threshold = 0; + info->prefix_len = prefix_len; + info->prefix = prefix; + info->group_table = group_table; + info->type_table = type_table; + info->dset_table = dset_table; + info->status = status; + + + + /* Disable error reporting */ + H5Eget_auto (&func, &edata); + H5Eset_auto (NULL, NULL); + + /* find all objects one time */ + if ((status = H5Giterate(fid, "/", NULL, (H5G_operator_t)find_objs, (void*)info)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the groups\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + } + + /* Enable error reporting */ + H5Eset_auto (func, edata); + +#ifdef H5DUMP_DEBUG + dump_tables(); +#endif + + if (status != SUCCEED) { + fprintf(stderr,"Error: internal error! \n"); + goto done; + } + + op_data.hfile_id = hfile_id; + op_data.sd_id = sd_id; + op_data.vgroup_id = 0; + + /* start at root group */ + if (( status = convert_group (gid, HDstrdup("/"), &op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_group did not work for %s\n","/"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + + /* Terminate access to Vgroup interface */ + if ((status = Vend(hfile_id)) != SUCCEED) { + fprintf(stderr,"Error: Unable to terminate Vgroup interface\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + } + + /* close hdf4 SDS */ + if ((status = SDend(sd_id)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close file %s, from SDstart\n", h4_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + + } + + /* close hdf4 file */ + if ((status = Hclose(hfile_id)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close file %s\n", h4_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + + } + + if ((status = H5Gclose (gid)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close root group\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + + if ((status = H5Fclose (fid)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close file %s\n", h5_filename); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__); + status = FAIL; + } + +done: + free_table(&group_table); + free_table(&dset_table); + free_table(&type_table); + + return status; + +} + +/*------------------------------------------------------------------------- + * Function: convert_group + * + * Purpose: Dump everything within the specified group + * + * Return: status + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_group (hid_t gid, char *name, op_data_t *op_data) { +H5G_stat_t statbuf; + + int32 hfile_id; + int32 vgroup_id; + int32 obj_idx; + int32 status; + int idx, flag; + + hfile_id = op_data->hfile_id; + + if ((vgroup_id = Vattach(hfile_id, -1, "w")) <= 0 ) { + fprintf(stderr,"Error: Unable to create new vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(vgroup_id); + } + + if ((status = Vsetname(vgroup_id, name)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to set name on new vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + if ((status = Vsetclass(vgroup_id, "HDF5")) != SUCCEED ) { + fprintf(stderr,"Error: Unable to set class on new vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + if (op_data->vgroup_id == 0) { + obj_idx = -1; /* Indexes assigned below start from 0 */ + } else { + if ((obj_idx = Vinsert(op_data->vgroup_id, vgroup_id)) < 0) { + fprintf(stderr,"Error: Index %d of the new vgroup is illegal\n",(int)obj_idx); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(obj_idx); + } + } + op_data->vgroup_id = vgroup_id; + op_data->sds_id = 0; + op_data->vdata_id = 0; + op_data->obj_idx = obj_idx; + + + /* hard link */ + if ((status = H5Gget_objinfo(gid, ".", TRUE, &statbuf)) != SUCCEED ) { + fprintf(stderr,"Error: H5Gget_objinfo() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return (status); + } + + if (HDstrcmp(name,"/") == 0) { /* this is the root group, just iterate */ + + if ((status = H5Aiterate(gid, NULL, (H5A_operator_t)convert_attr, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the attributes\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the groups\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + } else { + + if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) { + + fprintf(stderr,"Error: object not found, %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + status = FAIL; + + } else if((flag = get_tableflag(group_table,idx)) < 0 ) { + + fprintf(stderr,"Error: get_tableflag() should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + status = FAIL; + + } else if(flag == TRUE ) { /* this has already been converted, don't convert the attributes again */ + + if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the groups\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + } else { /* flag == FALSE */ + + /* this is now being converted */ + if ((status = set_tableflag(group_table,idx)) < 0 ) { + fprintf(stderr,"Error: set_tableflag should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + if ((status = H5Aiterate(gid, NULL, (H5A_operator_t)convert_attr, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the attributes\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to iterate over all of the groups\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + return(status); + } + + } + + } + + + if ((status = Vdetach(vgroup_id)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to detach the new Vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__); + status = FAIL; + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_dataset + * + * Purpose: Convert the specified data set + * + * Return: status + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_dataset (hid_t did, char *name, op_data_t *op_data) { +hid_t type, space, class, mem_type, type2; +/* H5G_stat_t statbuf; */ +size_t typesize; +int i, idx; +int32 dim_sizes[32], start[32], edges[32]; +int ndims; +int ndimf; +hsize_t dims[32], maxdims[32]; +hsize_t dimf[4]; +int permf[4]; +int32 hfile_id; +int32 sd_id; +int32 sds_id; +int32 vdata_id; +int32 vgroup_id; +int32 n_values; +int32 status; +int32 h4_type; +int32 recsize; +int32 n_records, num_of_recs, record_pos; +intn nmembers; +char *buffer=NULL; /* read/write buffer*/ +char fieldname_list[4096] = "\0"; +char *fieldname=NULL; +hid_t fieldtype; +int32 order; +off_t offset; +off_t offset_array[512]; +hid_t h4type_array[512], memtype_array[512]; +int32 order_array[512]; + + + /* hard link */ +/* + if ((status = H5Gget_objinfo(did, ".", TRUE, &statbuf)) != SUCCEED ) { + fprintf(stderr,"Error: H5Gget_objinfo() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return (status); + } +*/ + + if ((type = H5Dget_type(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((space = H5Dget_space(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) { + fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((ndims = H5Sget_simple_extent_dims(space,dims,maxdims)) < 0 ) { + fprintf(stderr, "Error: Problems getting ndims, dims, and maxdims of dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = ndims; + return status; + } + + if ((class = H5Tget_class(type)) < 0 ) { + fprintf(stderr,"Error: problem with getting class\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = class; + return status; + } + + switch (class) { + case H5T_INTEGER: + case H5T_FLOAT: + sd_id = op_data->sd_id; +#define NEWWAY +#ifdef NEWWAY + if (FAIL==h5atomic_type_to_h4type(type, &mem_type, &typesize, &h4_type)){ + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +#else + if ((h4_type = h5type_to_h4type(type)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h4 type to mem type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + if ((typesize = H5Tget_size(mem_type)) <= 0) { + fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +#endif + if ((buffer = HDmalloc(n_values*typesize)) == NULL) { + fprintf(stderr, "Error: Problems with HDmalloc of memory space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((status = H5Dread(did, mem_type, space, space, H5P_DEFAULT, buffer)) != SUCCEED) { + fprintf(stderr, "Error: Problems with H5Dread\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + for (i=0;i<ndims;i++) { + if (maxdims[i] == H5S_UNLIMITED) { + if ( i == 0 ) { + dim_sizes[0] = 0; /* this is how HDF4 communicates unlimited dimension */ + } else { + dim_sizes[i] = (int32)dims[i]; + } + } else { + dim_sizes[i] = (int32)maxdims[i]; + } + start[i] = 0; + edges[i] = (int32)dims[i]; + } + if ((sds_id = SDcreate(sd_id, name, h4_type, ndims, dim_sizes)) <= 0 ) { + fprintf(stderr, "Error: Unable to create SDS %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + op_data->sds_id = sds_id; + if ((status = SDwritedata(sds_id, start, NULL, edges, buffer)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to write SDS %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) { + fprintf(stderr,"Error: iterate over attributes\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + if ((status = SDendaccess(sds_id)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to end access to SDS %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + break; + case H5T_TIME: + fprintf(stderr,"Warning: H5T_TIME not yet implemented.\n"); + break; + case H5T_STRING: + if (ndims==1) { + convert_dataset_string(did, name, op_data); + } else { + fprintf(stderr,"Warning: HDF5 datasets of H5T_STRING type with ndims > 1 are not converted.\n"); + } + break; + case H5T_BITFIELD: + fprintf(stderr,"Warning: H5T_BITFIELD not yet implemented.\n"); + break; + case H5T_OPAQUE: + fprintf(stderr,"Warning: H5T_OPAQUE not yet implemented.\n"); + break; + case H5T_ARRAY: + fprintf(stderr,"Warning: H5T_OPAQUE not yet implemented.\n"); + break; + case H5T_COMPOUND: + if (ndims==1) { + if ((nmembers = H5Tget_nmembers(type)) <= 0 ) { + fprintf(stderr, "Error: Unable to get information about compound datatype %d\n",nmembers); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + + offset = 0; + for (idx=0;idx<nmembers;idx++) { + if ((fieldtype = H5Tget_member_type(type, idx)) < 0 ) { + fprintf(stderr,"Error: H5 datasets of H5T_COMPOUND type with fieldtype %d, idx %d.\n",fieldtype,idx); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + /* Special case for array fields */ + if(H5Tget_class(fieldtype)==H5T_ARRAY) { + hid_t arr_base_type; + + /* Get the number of dimensions */ + if ((ndimf = H5Tget_array_ndims(fieldtype)) < 0 || ndimf > H5S_MAX_RANK ) { + fprintf(stderr, "Error: rank of members of compound type should not be %d\n",ndimf); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + /* Get the dimensions and dimension permutations */ + if (H5Tget_array_dims(fieldtype,dimf,permf) < 0) { + fprintf(stderr, "Error: cannot retrieve dimensions for array\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + /* Get the 'real' field type */ + if ((arr_base_type=H5Tget_super(fieldtype)) < 0) { + fprintf(stderr, "Error: cannot retrieve base type for array\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + if (H5Tclose(fieldtype) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + + /* Assign the array's base type as the field type for future use */ + fieldtype=arr_base_type; + } /* end if */ + else + ndimf=0; +#ifdef NEWWAY + if (FAIL==h5atomic_type_to_h4type(fieldtype, &mem_type, &typesize, &h4_type)){ + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +#else + if ((h4_type = h5type_to_h4type(fieldtype)) < 0 ) { + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h4 type to mem type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + if ((typesize = H5Tget_size(mem_type)) <= 0) { + fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +#endif + order = 1; + if (ndimf > 0) { + order *= dimf[permf[0]]; + if (ndimf > 1) { + order *= dimf[permf[1]]; + if (ndimf > 2) { + order *= dimf[permf[2]]; + if (ndimf > 3) { + order *= dimf[permf[3]]; + } + } + } + } + h4type_array[idx] = h4_type; /* used for VSfdefine */ + memtype_array[idx] = mem_type; /* used during the build of the memory compound type */ + offset_array[idx] = offset; /* used during the build of the memory compound type */ + order_array[idx] = order; /* used for VSfdefine */ + + offset += order * typesize; /* calculating packed size of memory compound type */ + } + hfile_id = op_data->hfile_id; + vgroup_id = op_data->vgroup_id; + if ((vdata_id = VSattach(hfile_id, -1, "w")) <= 0 ) { + fprintf(stderr, "Error: Unable to create vdata %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +/* + * This step is done during the convert_shared_dataset() call instead of here. + * + if ((idx = Vinsert(vgroup_id, vdata_id)) < 0 ) { + fprintf(stderr, "Error: Unable to insert vdata %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +*/ + op_data->vdata_id = vdata_id; + if ((status = VSsetname(vdata_id, name)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set vdata name %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((status = VSsetclass(vdata_id, "HDF5")) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set class on vdata %s\n", name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((type2 = H5Tcreate(H5T_COMPOUND, (size_t)offset)) <= 0 ) { + fprintf(stderr, "Error: unable to execute H5Tcreate()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + for (idx=0;idx<nmembers;idx++) { + /* Special case for array fields */ + if(H5Tget_member_class(type,idx)==H5T_ARRAY) { + hid_t arr_type; + + if ((arr_type = H5Tget_member_type(type, idx)) < 0 ) { + fprintf(stderr,"Error: H5 datasets of H5T_COMPOUND type with fieldtype %d, idx %d.\n",arr_type,idx); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + /* Get the number of dimensions */ + if ((ndimf = H5Tget_array_ndims(arr_type)) < 0 || ndimf > H5S_MAX_RANK ) { + fprintf(stderr, "Error: rank of members of compound type should not be %d\n",ndimf); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + /* Get the dimensions and dimension permutations */ + if (H5Tget_array_dims(arr_type,dimf,permf) < 0) { + fprintf(stderr, "Error: cannot retrieve dimensions for array\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + if (H5Tclose(arr_type) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + } /* end if */ + else + ndimf=0; + + if ((fieldname = H5Tget_member_name(type, idx)) == NULL ) { + fprintf(stderr, "Error: Unable to get fieldname for compound type %d, idx %d\n", type, idx); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((offset = H5Tget_offset(memtype_array[idx])) < 0 || offset >= 128 ) { + fprintf(stderr, "Error: H5Tget_offset() is returning a bad value %d\n",(int)offset); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + if (ndimf == 0 ) { + if ((status = H5Tinsert(type2,fieldname,offset_array[idx]+offset,memtype_array[idx])) != SUCCEED ) { + fprintf(stderr, "Error: Problems inserting field into compound datatype\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + } else { + hid_t arr_type; + + /* Create the array datatype */ + if ((arr_type = H5Tarray_create(memtype_array[idx], ndimf, dimf, permf)) < 0 ) { + fprintf(stderr,"Error: cannot create array datatype\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + + if ((status = H5Tinsert(type2,fieldname,offset_array[idx]+offset,arr_type)) != SUCCEED ) { + fprintf(stderr, "Error: Problems inserting field into compound datatype\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + + if (H5Tclose(arr_type) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + return FAIL; + } + } + if ((status = VSfdefine(vdata_id, fieldname, h4type_array[idx], order_array[idx])) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set field %d\n", idx); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + strcat(fieldname_list,fieldname); + if (idx<nmembers-1) { + strcat(fieldname_list,", "); + } + + if (fieldname != NULL) { + HDfree(fieldname); + } + } + if ((status = VSsetfields(vdata_id, fieldname_list)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set fieldname list %s\n", name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((status = VSsetinterlace(vdata_id, FULL_INTERLACE)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set FULL_INTERLACE mode, status %d\n", (int)status); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((recsize = H5Tget_size(type2)) <= 0 ) { + fprintf(stderr, "Error: Unable to get record size %d\n", (int)recsize); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } +/* + Since the space is rank 1, n_records does not depend on maxdims. +*/ + n_records = n_values; + if ((buffer = HDmalloc(n_records*recsize)) == NULL) { + fprintf(stderr, "Error: Problems with HDmalloc of memory space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((status = H5Dread(did, type2, space, space, H5P_DEFAULT, buffer)) != SUCCEED) { + fprintf(stderr, "Error: Problems with H5Dread\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((status = H5Tclose(type2)) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } + + if ((record_pos = VSseek(vdata_id, 0)) != 0 ) { + fprintf(stderr, "Error: Could not seek the beginning of the Vdata, %d\n", (int)record_pos); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = record_pos; + break; + } + if ((num_of_recs = VSwrite(vdata_id, (void *)buffer, n_records, FULL_INTERLACE)) != n_records ) { + fprintf(stderr, "Error: Only able to write %d of %d records\n", (int)num_of_recs, (int)n_records); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = num_of_recs; + break; + } + + /* there are only vdata attributes, no field attributes */ + if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) { + fprintf(stderr,"Error: iterate over attributes\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + if ((status = VSdetach(vdata_id)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to detach to vdata %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + break; + } + + } else { + + fprintf(stderr,"Warning: HDF5 datasets of H5T_COMPOUND type with ndims > 1 are not converted.\n"); + + } + break; + default: + fprintf(stderr,"Error: %d class not found\n",class); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + + if ((status = H5Tclose(type)) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + + if ((status = H5Sclose(space)) < 0 ) { + fprintf(stderr,"Error: closing space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + } + + if (buffer != NULL) { + HDfree(buffer); + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_attr + * + * Purpose: dump the attribute + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ + +herr_t +convert_attr (hid_t attr, char *attr_name, op_data_t *op_data) +{ +hid_t attr_id, type, space, mem_type, class; +size_t typesize; +char *attr_values=NULL; +int32 status; +int32 h4_type; +int32 sds_id; +int32 vdata_id; +int32 vgroup_id; +int32 n_values; +int32 order; +hid_t fxdlenstr; +size_t lenstr; +H5T_cset_t cset; +H5T_str_t strpad; + + sds_id = op_data->sds_id; + vdata_id = op_data->vdata_id; + vgroup_id = op_data->vgroup_id; + + if ((attr_id = H5Aopen_name (attr, attr_name))>= 0) { + + if ((type = H5Aget_type(attr_id)) <= 0) { + fprintf(stderr, "Error: H5Aget_type() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((class = H5Tget_class(type)) < 0 ) { + fprintf(stderr,"Error: problem with getting class\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = class; + return status; + } + + switch (class) { + case H5T_INTEGER: + case H5T_FLOAT: + + + if ((space = H5Aget_space(attr_id)) <= 0) { + fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) { + fprintf(stderr, "Error: H5sget_simple_extent_npoints() didn't return correct value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + +#ifdef NEWWAY + if (FAIL==h5atomic_type_to_h4type(type, &mem_type, &typesize, &h4_type)){ + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + break; + } +#else + if ((h4_type = h5type_to_h4type(type)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h5 type to h4 type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h4 type to mem type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((typesize = H5Tget_size(mem_type)) <= 0) { + fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } +#endif + + if ((attr_values = HDmalloc(n_values*typesize)) == NULL) { + fprintf(stderr, "Error: Problems with HDmalloc of memory space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((status = H5Aread(attr_id, mem_type, attr_values)) != SUCCEED) { + fprintf(stderr, "Error: Problems with H5Aread\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if (sds_id != 0) { + if ((status = SDsetattr(sds_id, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } else if (vdata_id != 0) { + if ((status = VSsetattr(vdata_id, -1, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } else { + if ((status = Vsetattr(vgroup_id, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } + + if ((status = H5Sclose(space)) != SUCCEED ) { + fprintf(stderr, "Error: Problems closing H5Sclose\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + if ((status = H5Aclose(attr_id)) != SUCCEED ) { + fprintf(stderr, "Error: Problems closing H5Aclose\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if (attr_values != NULL) { + HDfree(attr_values); + } + + status = SUCCEED; + break; + + case H5T_TIME: + fprintf(stderr,"Warning: H5T_TIME attribute not yet implemented.\n"); + break; + case H5T_STRING: + + fxdlenstr = type; + h4_type = DFNT_CHAR; + + if ((space = H5Aget_space(attr_id)) <= 0) { + fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) { + fprintf(stderr, "Error: H5sget_simple_extent_npoints() didn't return correct value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((mem_type = H5Tcopy(H5T_C_S1)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h4 type to mem type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = mem_type; + return status; + } + if ((lenstr = H5Tget_size(fxdlenstr)) <= 0 ) { + fprintf(stderr, "Error: size of fixed length string type should not be %d\n",(int)lenstr); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return lenstr; + } + if ((status = H5Tset_size(mem_type,lenstr)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_size()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return status; + } + + strpad = H5Tget_strpad(fxdlenstr); + if ((strpad != H5T_STR_NULLTERM) && (strpad != H5T_STR_NULLPAD) && (strpad != H5T_STR_SPACEPAD)) { + fprintf(stderr, "Error: Invalid string padding value, %d\n",(int)strpad); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return strpad; + } + if ((status = H5Tset_strpad(mem_type, H5T_STR_SPACEPAD)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_strpad()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return status; + } + + if ((cset = H5Tget_cset(fxdlenstr)) != H5T_CSET_ASCII ) { + fprintf(stderr, "Error: cset value != %d\n",(int)H5T_CSET_ASCII); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return cset; + } + if ((status = H5Tset_cset(mem_type,cset)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_cset()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + return status; + } + + order = n_values * lenstr; + if ((attr_values = HDmalloc(order)) == NULL) { + fprintf(stderr, "Error: Problems with HDmalloc of memory space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((status = H5Aread(attr_id, mem_type, attr_values)) != SUCCEED) { + fprintf(stderr, "Error: Problems with H5Aread\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if (sds_id != 0) { + if ((status = SDsetattr(sds_id, attr_name, h4_type, order, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } else if (vdata_id != 0) { + if ((status = VSsetattr(vdata_id, -1, attr_name, h4_type, order, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } else { + if ((status = Vsetattr(vgroup_id, attr_name, h4_type, order, attr_values)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + } + + if ((status = H5Sclose(space)) != SUCCEED ) { + fprintf(stderr, "Error: Problems closing H5Sclose\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + if ((status = H5Aclose(attr_id)) != SUCCEED ) { + fprintf(stderr, "Error: Problems closing H5Aclose\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if (attr_values != NULL) { + HDfree(attr_values); + } + + status = SUCCEED; + break; + case H5T_BITFIELD: + fprintf(stderr,"Warning: H5T_BITFIELD attribute not yet implemented.\n"); + break; + case H5T_OPAQUE: + fprintf(stderr,"Warning: H5T_OPAQUE attribute not yet implemented.\n"); + break; + case H5T_COMPOUND: + fprintf(stderr,"Warning: H5T_COMPOUND attribute not implemented.\n"); + break; + default: + fprintf(stderr,"Error: %d class not found\n",class); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + } + + if ((status = H5Tclose(type)) != SUCCEED ) { + fprintf(stderr, "Error: Problems closing H5Tclose\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__); + status = FAIL; + return status; + } + + } else { + + status = FAIL; + + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_all + * + * Purpose: Dump everything in the specified object + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_all (hid_t group, char *name, op_data_t *op_data) +{ + hid_t obj; + H5G_stat_t statbuf, statbuf2; + int status; + op_data_t op_data_save; + int32 vgroup_id; + int32 sd_id; + int32 sds_id; + int idx, flag; + void *edata; + hid_t (*func)(void*); + + op_data_save = *op_data; + + vgroup_id = op_data->vgroup_id; + sd_id = op_data->sd_id; + sds_id = op_data->sds_id; + + if ((status = H5Gget_objinfo(group, name, FALSE, &statbuf)) != SUCCEED ) { + fprintf(stderr,"Error: H5Gget_objinfo() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (status); + } + statbuf2 = statbuf; + + switch (statbuf.type) { + + case H5G_LINK: /* this is a soft link only */ + + + /* Disable error reporting */ + H5Eget_auto (&func, &edata); + H5Eset_auto (NULL, NULL); + + /* test to see if object exists */ + if ((status = H5Gget_objinfo(group, name, TRUE, NULL)) != SUCCEED ) { + fprintf(stderr,"Warning: the object pointed to by the symbolic link \"%s\" does not exist.\n",name); + } + + /* Enable error reporting */ + H5Eset_auto (func, edata); + + if (status != SUCCEED) { + break; + } + + /* follow link for type */ + if ((status = H5Gget_objinfo(group, name, TRUE, &statbuf)) != SUCCEED ) { + fprintf(stderr,"Error: H5Gget_objinfo() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (status); + } + + if (statbuf.type==H5G_DATASET ) { + + if ((idx = get_table_idx(dset_table, statbuf.objno)) < 0 ) { + + fprintf(stderr,"Error: object not found\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if((flag = get_tableflag(dset_table,idx)) < 0 ) { + + fprintf(stderr,"Error: get_tableflag() should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if(flag == TRUE ) { /* this has already been converted, add as a tag/ref */ + + if ((obj = H5Dopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open H5 dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to convert to tag/ref\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + } + } + if ((status = H5Dclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } else { /* flag == FALSE */ + + if ((obj = H5Dopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open H5 dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if (( status = convert_dataset (obj, name, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_dataset did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to convert to tag/ref\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + } + if(( status = set_tableflag(dset_table,idx)) != SUCCEED ) { + fprintf(stderr,"Error: set_tableflag() did not work for %s\n", name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + break; + } + } + if ((status = H5Dclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } + + } else if (statbuf.type==H5G_GROUP ) { + + if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) { + + fprintf(stderr,"Error: object not found\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if((flag = get_tableflag(group_table,idx)) < 0 ) { + + fprintf(stderr,"Error: get_tableflag() should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if(flag == TRUE ) { + + if (( status = convert_shared_group (group, idx, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_group did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } else { /* flag == FALSE */ + + if ((obj = H5Gopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open group\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if (( status = convert_group (obj, name, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_group did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + } + if ((status = H5Gclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close group %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } + + } + + break; + + case H5G_GROUP: + + if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) { + + fprintf(stderr,"Error: object not found\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if((flag = get_tableflag(group_table,idx)) < 0 ) { + + fprintf(stderr,"Error: get_tableflag() should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if(flag == TRUE ) { + + if (( status = convert_shared_group (group, idx, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_group did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } else { /* flag == FALSE */ + + if ((obj = H5Gopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open group\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if (( status = convert_group (obj, name, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_group did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + } + if ((status = H5Gclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close group %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } + + break; + + case H5G_DATASET: + + if ((idx = get_table_idx(dset_table, statbuf.objno)) < 0 ) { + + fprintf(stderr,"Error: object not found\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if((flag = get_tableflag(dset_table,idx)) < 0 ) { + + fprintf(stderr,"Error: get_tableflag() should never return < 0\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + + } else if(flag == TRUE ) { /* this has already been converted, add as a tag/ref */ + + if ((obj = H5Dopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open H5 dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to convert to tag/ref\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + } + } + if ((status = H5Dclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } else { /* flag == FALSE */ + + if ((obj = H5Dopen (group, name)) <= 0 ) { + fprintf(stderr,"Error: Unable to open H5 dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + return (obj); + } else { + if (( status = convert_dataset (obj, name, op_data)) != SUCCEED) { + fprintf(stderr,"Error: convert_dataset did not work for %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to convert to tag/ref\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + } + if(( status = set_tableflag(dset_table,idx)) != SUCCEED ) { + fprintf(stderr,"Error: set_tableflag() did not work for %s\n", name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + break; + } + } + if ((status = H5Dclose(obj)) != SUCCEED) { + fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__); + status = FAIL; + break; + } + + } + + break; + + case H5G_TYPE: + /* object is ignored */ + break; + + default: + fprintf (stderr,"Unknown Object %s\n", name); + status = FAIL; + break; + + } + + *op_data = op_data_save; + + return SUCCEED; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_shared_dataset + * + * Purpose: Handle a shared dataset which has already been converted. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_shared_dataset(hid_t did, int idx, op_data_t *op_data) +{ + int status=SUCCEED; + int32 vgroup_id; + char *dataset_name=NULL; + char *dataset_name2=NULL; + int32 hfile_id; + int32 sd_id; + int32 sds_id; + int32 sds_ref; + int32 vdata_ref; + int32 sds_index; + int32 numtagref; + hid_t type, space, class; + hsize_t dims[32], maxdims[32]; + int n_values, ndims; + + vgroup_id = op_data->vgroup_id; + + if ((dataset_name = get_objectname(dset_table, idx)) == NULL ) { + fprintf(stderr,"Error: get_objectname() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (status); + } + + if ((dataset_name2 = strrchr(dataset_name,'/')) == NULL) { /* find last "/" in dataset_name */ + dataset_name2 = dataset_name; /* no "/"s were found */ + } else { + dataset_name2 = dataset_name2 + sizeof(char); /* 1 character past last "/" */ + } + + if ((type = H5Dget_type(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((space = H5Dget_space(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) { + fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((ndims = H5Sget_simple_extent_dims(space,dims,maxdims)) < 0 ) { + fprintf(stderr, "Error: Problems getting ndims, dims, and maxdims of dataset\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = ndims; + return status; + } + + if ((class = H5Tget_class(type)) < 0 ) { + fprintf(stderr,"Error: problem with getting class\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = class; + return status; + } + + switch (class) { + case H5T_INTEGER: + case H5T_FLOAT: + sd_id = op_data->sd_id; + if ((sds_index = SDnametoindex(sd_id, dataset_name2)) < 0 ) { + fprintf (stderr,"Error: Problem with SDnametoindex().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (sds_index); + } + if ((sds_id = SDselect(sd_id, sds_index)) < 0 ) { + fprintf (stderr,"Error: Problem with SDselect().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (sds_id); + } + if ((sds_ref = SDidtoref(sds_id)) < 0 ) { + fprintf (stderr,"Error: Problem with SDidtoref().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (sds_ref); + } + if ((numtagref = Vaddtagref(vgroup_id, DFTAG_NDG, sds_ref)) < 0 ) { + fprintf (stderr,"Error: Problem with Vaddtagref().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (numtagref); + } + break; + case H5T_TIME: + fprintf(stderr,"Error: H5T_TIME not yet implemented.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + break; + case H5T_STRING: + hfile_id = op_data->hfile_id; + if (ndims==1) { + if ((vdata_ref = VSfind(hfile_id,dataset_name2)) <= 0 ) { + fprintf (stderr,"Error: Problem with VSfind().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (vdata_ref); + } + if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VH, vdata_ref)) < 0 ) { + fprintf (stderr,"Error: Problem with Vaddtagref().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (numtagref); + } + } + break; + case H5T_BITFIELD: + fprintf(stderr,"Error: H5T_BITFIELD not yet implemented.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + break; + case H5T_OPAQUE: + fprintf(stderr,"Error: H5T_OPAQUE not yet implemented.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + break; + case H5T_COMPOUND: + hfile_id = op_data->hfile_id; + if (ndims==1) { + if ((vdata_ref = VSfind(hfile_id,dataset_name2)) <= 0 ) { + fprintf (stderr,"Error: Problem with VSfind().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (vdata_ref); + } + if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VH, vdata_ref)) < 0 ) { + fprintf (stderr,"Error: Problem with Vaddtagref().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + return (numtagref); + } + } + break; + default: + fprintf(stderr,"Error: %d class not found\n",class); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = FAIL; + } + + if ((status = H5Tclose(type)) < 0 ) { + fprintf(stderr,"Error: closing type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__); + status = FAIL; + } + + if (dataset_name != NULL) { + HDfree (dataset_name); + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_shared_group + * + * Purpose: Handle a shared group which has already been converted. + * + * Return: status + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_shared_group (hid_t group, int idx, op_data_t *op_data) { + + int32 hfile_id; + int32 vgroup_id; + int32 vgroup_ref; + int32 numtagref; + int32 status = SUCCEED; + hid_t group2; + char *group_name=NULL; + char *group_name2=NULL; + char vgroup_name[VGNAMELENMAX]; + + group2 = group; + hfile_id = op_data->hfile_id; + + if ((group_name = get_objectname(group_table, idx)) == NULL ) { + fprintf(stderr,"Error: get_objectname() did not work\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + status = FAIL; + return (status); + } + + if ((group_name2 = strrchr(group_name,'/')) == NULL) { /* find last "/" in group_name */ + group_name2 = group_name; /* no "/"s were found */ + } else { + group_name2 = group_name2 + sizeof(char); /* 1 character past last "/" */ + } + + if ((status = Vgetname(op_data->vgroup_id,vgroup_name)) < 0 ) { + fprintf (stderr,"Error: Problem with Vfind().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + return (status); + } + + if ((vgroup_ref = Vfind(hfile_id,vgroup_name)) <= 0 ) { + fprintf (stderr,"Error: Problem with Vfind().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + return (vgroup_ref); + } + + if ((vgroup_id = Vattach(hfile_id, vgroup_ref, "w")) <= 0 ) { + fprintf(stderr,"Error: Unable to create new vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + return(vgroup_id); + } + + if ((vgroup_ref = Vfind(hfile_id,group_name2)) <= 0 ) { + fprintf (stderr,"Error: Problem with Vfind().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + return (vgroup_ref); + } + + if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VG, vgroup_ref)) < 0 ) { + fprintf (stderr,"Error: Problem with Vaddtagref().\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + return (numtagref); + } + + if ((status = Vdetach(vgroup_id)) != SUCCEED ) { + fprintf(stderr,"Error: Unable to detach the new Vgroup\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__); + status = FAIL; + } + + if (group_name != NULL) { + HDfree(group_name); + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: convert_dataset_string + * + * Purpose: convert a dataset with string elements. + * + * Return: status + * + * Programmer: Paul Harten + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +herr_t +convert_dataset_string (hid_t did, char *name, op_data_t *op_data) { + + int32 hfile_id; + int32 vgroup_id; + int32 vdata_id; +hid_t fxdlenstr, space, class, mem_type; +const char* fieldname = {"string"}; +const char* fieldname_list = fieldname; +char *buffer; +int32 status; +int32 h4_type; +int32 recsize, n_records, n_values, num_of_recs, record_pos; +size_t lenstr; +H5T_cset_t cset; +H5T_str_t strpad; + + if ((fxdlenstr = H5Dget_type(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((class = H5Tget_class(fxdlenstr)) != H5T_STRING ) { + fprintf(stderr,"Error: problem with getting class\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__); + status = class; + return status; + } + + if ((space = H5Dget_space(did)) <= 0) { + fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = FAIL; + return status; + } + + if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) { + fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = FAIL; + return status; + } + + h4_type = DFNT_CHAR; + if ((mem_type = H5Tcopy(H5T_C_S1)) == FAIL ) { + fprintf(stderr, "Error: Problems translating h4 type to mem type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = mem_type; + return status; + } + if ((lenstr = H5Tget_size(fxdlenstr)) <= 0 ) { + fprintf(stderr, "Error: size of fixed length string type should not be %d\n",(int)lenstr); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return lenstr; + } + if ((status = H5Tset_size(mem_type,lenstr)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_size()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + strpad = H5Tget_strpad(fxdlenstr); + if ((strpad != H5T_STR_NULLTERM) && (strpad != H5T_STR_NULLPAD) && (strpad != H5T_STR_SPACEPAD)) { + fprintf(stderr, "Error: Invalid string padding value, %d\n",(int)strpad); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return strpad; + } + if ((status = H5Tset_strpad(mem_type, strpad)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_strpad()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + if ((cset = H5Tget_cset(fxdlenstr)) != H5T_CSET_ASCII ) { + fprintf(stderr, "Error: cset value != %d\n",(int)H5T_CSET_ASCII); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return cset; + } + if ((status = H5Tset_cset(mem_type,cset)) != SUCCEED ) { + fprintf(stderr, "Error: Problem with H5Tset_cset()\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + hfile_id = op_data->hfile_id; + vgroup_id = op_data->vgroup_id; + if ((vdata_id = VSattach(hfile_id, -1, "w")) <= 0 ) { + fprintf(stderr, "Error: Unable to create vdata %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = FAIL; + return status; + } + + op_data->vdata_id = vdata_id; + if ((status = VSsetname(vdata_id, name)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set vdata name %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + if ((status = VSsetclass(vdata_id, "HDF5")) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set class on vdata %s\n", name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + if ((status = VSfdefine(vdata_id, fieldname, h4_type, lenstr)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to VSfdefine() field\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + if ((status = VSsetfields(vdata_id, fieldname_list)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set fieldname list %s\n", fieldname_list); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + if ((status = VSsetinterlace(vdata_id, FULL_INTERLACE)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to set FULL_INTERLACE mode, status %d\n", (int)status); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + if ((recsize = H5Tget_size(mem_type)) <= 0 ) { + fprintf(stderr, "Error: Unable to get record size %d\n", (int)recsize); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = recsize; + return status; + } +/* + Since the space is rank 1, n_records does not depend on maxdims. +*/ + n_records = n_values; + if ((buffer = HDmalloc(n_records*recsize)) == NULL) { + fprintf(stderr, "Error: Problems with HDmalloc of memory space\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = FAIL; + return status; + } + if ((status = H5Dread(did, mem_type, space, space, H5P_DEFAULT, buffer)) != SUCCEED) { + fprintf(stderr, "Error: Problems with H5Dread\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + if ((record_pos = VSseek(vdata_id, 0)) != 0 ) { + fprintf(stderr, "Error: Could not seek the beginning of the Vdata, %d\n", (int)record_pos); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = record_pos; + return status; + } + if ((num_of_recs = VSwrite(vdata_id, (void *)buffer, n_records, FULL_INTERLACE)) != n_records ) { + fprintf(stderr, "Error: Only able to write %d of %d records\n", (int)num_of_recs, (int)n_records); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + status = num_of_recs; + return status; + } + + /* there are only vdata attributes, no field attributes */ + if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) { + fprintf(stderr,"Error: iterate over attributes\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + if ((status = VSdetach(vdata_id)) != SUCCEED ) { + fprintf(stderr, "Error: Unable to detach to vdata %s.\n",name); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__); + return status; + } + + if (buffer != NULL) { + HDfree(buffer); + } + + return status; + +} + + +/*------------------------------------------------------------------------- + * Function: h5atomic_type_to_h4type + * + * Purpose: Match an H5 atomic type to an appropriate H4 type. + * Assign an appropirate H5 memory type that matches the H4 type. + * Return the H5 memory type, H4 type and sizeof H4 via pointers. + * + * Return: SUCCEED on suceed, FAIL on failure. + * When fail, pointer values of h5memtype, h5memsize and h4_type + * may have changed and are undefined. + * + * Programmer: Albert Cheng, March 2000 + * + * Modifications: + * + *-----------------------------------------------------------------------*/ +static herr_t h5atomic_type_to_h4type(const hid_t h5type, hid_t* h5memtype, size_t* h5memsize, int32* h4type) +{ + H5T_class_t class; + size_t h5typesize, h4typesize; + H5T_sign_t sign; + hid_t mem_datatype = FAIL; + + if ((class = H5Tget_class(h5type)) < 0 ) { + fprintf(stderr,"Error: problem with getting type class\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + + switch(class){ + case H5T_INTEGER: + if ((h5typesize = H5Tget_size(h5type)) == 0 ) { + fprintf(stderr,"Error: problem with getting type size\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + if ((sign = H5Tget_sign(h5type)) == H5T_SGN_ERROR) { + fprintf(stderr,"Error: problem with getting type sign\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + /* deduce the proper HDF4 integer type to use according to the size of the HDF5 type. */ + /* Current HDF4 types can be 8, 16, 32 bits (1, 2, 4 bytes). */ + switch(h5typesize){ + case 1: + *h4type = (sign == H5T_SGN_2 ? DFNT_INT8 : DFNT_UINT8); + h4typesize = sizeof(int8); + if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG); + }else + return(FAIL); + break; + case 2: + *h4type = (sign == H5T_SGN_2 ? DFNT_INT16 : DFNT_UINT16); + h4typesize = sizeof(int16); + if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG); + }else + return(FAIL); + break; + case 4: + *h4type = (sign == H5T_SGN_2 ? DFNT_INT32 : DFNT_UINT32); + h4typesize = sizeof(int32); + if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT); + }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){ + mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG); + }else + return(FAIL); + break; + default: + fprintf(stderr,"Error: unmatchable integer type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + break; + /* end of case H5T_INTEGER */ + + case H5T_FLOAT: + if ((h5typesize = H5Tget_size(h5type)) == 0 ) { + fprintf(stderr,"Error: problem with getting type size\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + /* deduce the proper HDF4 floating point type to use according to the size of the HDF5 type. */ + /* Current HDF4 types can be 32 or 64 bits (4 or 8 bytes). */ + switch(h5typesize){ + case 4: + *h4type = DFNT_FLOAT32; + h4typesize = sizeof(float32); + if (h4typesize == H5Tget_size(H5T_NATIVE_FLOAT)){ + mem_datatype = H5T_NATIVE_FLOAT; + }else if (h4typesize == H5Tget_size(H5T_NATIVE_DOUBLE)){ + mem_datatype = H5T_NATIVE_DOUBLE; + }else + return(FAIL); + break; + case 8: + *h4type = DFNT_FLOAT64; + h4typesize = sizeof(float64); + if (h4typesize == H5Tget_size(H5T_NATIVE_FLOAT)){ + mem_datatype = H5T_NATIVE_FLOAT; + }else if (h4typesize == H5Tget_size(H5T_NATIVE_DOUBLE)){ + mem_datatype = H5T_NATIVE_DOUBLE; + }else + return(FAIL); + break; + default: + fprintf(stderr,"Error: unmatchable H5 float type\n"); + DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__); + return FAIL; + } + break; + /* end of case H5T_FLOAT */ + + default: + return FAIL; + } + + *h5memsize = h4typesize; + *h5memtype = mem_datatype; + return(SUCCEED); +} +#ifndef NEWWAY +/***************************************************************************** + + Routine: h5type_to_h4type(h5type) + + Description: Translate h5 datatype into h4 datatype + + Input: h5 datatype + + Output: function return, h4 datatype + +*****************************************************************************/ + +int32 h5type_to_h4type(hid_t h5_datatype) +{ + int32 h4_datatype; + + if (H5Tequal(h5_datatype,H5T_STD_I8BE)) { + h4_datatype = DFNT_INT8; + } else if (H5Tequal(h5_datatype,H5T_STD_I16BE)) { + h4_datatype = DFNT_INT16; + } else if (H5Tequal(h5_datatype,H5T_STD_I32BE)) { + h4_datatype = DFNT_INT32; +/* + * This is not supported by HDF4 + * + } else if (H5Tequal(h5_datatype,H5T_STD_I64BE)) { + h4_datatype = DFNT_INT64; +*/ + } else if (H5Tequal(h5_datatype,H5T_STD_U8BE)) { + h4_datatype = DFNT_UINT8; + } else if (H5Tequal(h5_datatype,H5T_STD_U16BE)) { + h4_datatype = DFNT_UINT16; + } else if (H5Tequal(h5_datatype,H5T_STD_U32BE)) { + h4_datatype = DFNT_UINT32; + } else if (H5Tequal(h5_datatype,H5T_STD_U64BE)) { + h4_datatype = DFNT_UINT64; + } else if (H5Tequal(h5_datatype,H5T_IEEE_F32BE)) { + h4_datatype = DFNT_FLOAT32; + } else if (H5Tequal(h5_datatype,H5T_IEEE_F64BE)) { + h4_datatype = DFNT_FLOAT64; + } else if (H5Tequal(h5_datatype,H5T_STD_I8LE)) { + h4_datatype = DFNT_INT8; + } else if (H5Tequal(h5_datatype,H5T_STD_I16LE)) { + h4_datatype = DFNT_INT16; + } else if (H5Tequal(h5_datatype,H5T_STD_I32LE)) { + h4_datatype = DFNT_INT32; +/* + * This is not supported by HDF4 + * + } else if (H5Tequal(h5_datatype,H5T_STD_I64LE)) { + h4_datatype = DFNT_INT64; +*/ + } else if (H5Tequal(h5_datatype,H5T_STD_U8LE)) { + h4_datatype = DFNT_UINT8; + } else if (H5Tequal(h5_datatype,H5T_STD_U16LE)) { + h4_datatype = DFNT_UINT16; + } else if (H5Tequal(h5_datatype,H5T_STD_U32LE)) { + h4_datatype = DFNT_UINT32; + } else if (H5Tequal(h5_datatype,H5T_STD_U64LE)) { + h4_datatype = DFNT_UINT64; + } else if (H5Tequal(h5_datatype,H5T_IEEE_F32LE)) { + h4_datatype = DFNT_FLOAT32; + } else if (H5Tequal(h5_datatype,H5T_IEEE_F64LE)) { + h4_datatype = DFNT_FLOAT64; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_SCHAR)) { + h4_datatype = DFNT_INT8; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_UCHAR)) { + h4_datatype = DFNT_UINT8; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_SHORT)) { + h4_datatype = DFNT_INT16; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_USHORT)) { + h4_datatype = DFNT_UINT16; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_INT)) { + h4_datatype = DFNT_INT32; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_UINT)) { + h4_datatype = DFNT_UINT32; +/* + * This is not supported by HDF4 + * + } else if (H5Tequal(h5_datatype,H5T_NATIVE_LONG)) { + h4_datatype = DFNT_INT64; +*/ + } else if (H5Tequal(h5_datatype,H5T_NATIVE_ULONG)) { + h4_datatype = DFNT_UINT64; +/* + * This is not supported by HDF4 + * + } else if (H5Tequal(h5_datatype,H5T_NATIVE_LLONG)) { + h4_datatype = DFNT_INT128; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_ULLONG)) { + h4_datatype = DFNT_UINT128; +*/ + } else if (H5Tequal(h5_datatype,H5T_NATIVE_FLOAT)) { + h4_datatype = DFNT_FLOAT32; + } else if (H5Tequal(h5_datatype,H5T_NATIVE_DOUBLE)) { + h4_datatype = DFNT_FLOAT64; +/* + * This is not supported by HDF4 + * + } else if (H5Tequal(h5_datatype,H5T_NATIVE_LDOUBLE)) { + h4_datatype = DFNT_FLOAT128; +*/ + } else { + h4_datatype = FAIL; + } + + return h4_datatype; + +} + + +/***************************************************************************** + + Routine: h4type_to_memtype(h4type) + + Description: Translate h4 datatype into mem datatype + + Input: h4 datatype + + Output: function return, mem datatype + +*****************************************************************************/ + +hid_t h4type_to_memtype(int32 h4_datatype) +{ + hid_t mem_datatype; + + switch (h4_datatype) { + case DFNT_INT8: + case DFNT_NINT8: + case DFNT_LINT8: + mem_datatype = H5T_NATIVE_SCHAR; break; + case DFNT_UINT8: + case DFNT_NUINT8: + case DFNT_LUINT8: + mem_datatype = H5T_NATIVE_UCHAR; break; + case DFNT_INT16: + case DFNT_NINT16: + case DFNT_LINT16: + mem_datatype = H5T_NATIVE_SHORT; break; + case DFNT_UINT16: + case DFNT_NUINT16: + case DFNT_LUINT16: + mem_datatype = H5T_NATIVE_USHORT; break; + case DFNT_INT32: + case DFNT_NINT32: + case DFNT_LINT32: + mem_datatype = H5T_NATIVE_INT; break; + case DFNT_UINT32: + case DFNT_NUINT32: + case DFNT_LUINT32: + mem_datatype = H5T_NATIVE_UINT; break; + case DFNT_INT64: + case DFNT_NINT64: + case DFNT_LINT64: + mem_datatype = H5T_NATIVE_LONG; break; + case DFNT_UINT64: + case DFNT_NUINT64: + case DFNT_LUINT64: + mem_datatype = H5T_NATIVE_ULONG; break; + case DFNT_INT128: + case DFNT_NINT128: + case DFNT_LINT128: + mem_datatype = H5T_NATIVE_LLONG; break; + case DFNT_UINT128: + case DFNT_NUINT128: + case DFNT_LUINT128: + mem_datatype = H5T_NATIVE_ULLONG; break; + case DFNT_FLOAT32: + case DFNT_NFLOAT32: + case DFNT_LFLOAT32: + mem_datatype = H5T_NATIVE_FLOAT; break; + case DFNT_FLOAT64: + case DFNT_NFLOAT64: + case DFNT_LFLOAT64: + mem_datatype = H5T_NATIVE_DOUBLE; break; + case DFNT_FLOAT128: + case DFNT_NFLOAT128: + case DFNT_LFLOAT128: + mem_datatype = H5T_NATIVE_LDOUBLE; break; + default: + mem_datatype = FAIL; + } + + return mem_datatype; + +} +#endif + + +/***************************************************************************** + + Routine: test_file + + Description: Test a file for read/write - ability. + + Input: filename - Unix filename + + Output: function return, global variable - errno + +*****************************************************************************/ + +int test_file(char *filename,int oflag,mode_t mode) +{ + int fid; + + errno = 0; + + fid = open(filename, oflag, mode); + if (fid < 0) { + perror(filename); + } + close(fid); + + return errno; + +} + + +/***************************************************************************** + + Routine: test_dir + + Description: Test pathway to determine if it is a directory + + Input: path - pathname given + + Output: function return TRUE/FALSE + +*****************************************************************************/ + +int test_dir(char *path) +{ + + struct stat buf; + struct stat *buf_ptr; + int idir; + + buf_ptr = &buf; + + idir = stat(path, buf_ptr); + if (idir < 0) { + if (errno == 2) { + return 0; + } else { + perror(path); + } + } + + return S_ISDIR(buf_ptr->st_mode); +} + +/***************************************************************************** + + Routine: BuildFilename() + + Description: Build a filename with new extension + + Input: filename - present filename + ext - extension to root of filename + + Output: (filename:r).ext + +*****************************************************************************/ + +char *BuildFilename(char *filename, char *ext) +{ + /* build outgoing filename */ + + char *filename_out; + char *lastper_ptr, *lastdir_ptr; + int root_len; + + lastper_ptr = strrchr(filename,'.'); + lastdir_ptr = strrchr(filename,'/'); + + if ( lastper_ptr <= lastdir_ptr ) { /* no extension */ + root_len = strlen(filename); + } else { /* existing extension */ + root_len = (int)(lastper_ptr - filename); + } + + filename_out = (char *)HDmalloc(root_len + strlen(ext) + 2); + filename_out = strncpy(filename_out, filename, (size_t)root_len); + filename_out[root_len] = '\0'; + filename_out = strcat(filename_out,"."); + filename_out = strcat(filename_out,ext); + + return filename_out; +} + diff --git a/tools/h5toh4/h5toh4.h b/tools/h5toh4/h5toh4.h new file mode 100644 index 0000000..d268060 --- /dev/null +++ b/tools/h5toh4/h5toh4.h @@ -0,0 +1,43 @@ +/* + * Copyright © 1998 NCSA + * All rights reserved. + * + * Programmer: Paul Harten <pharten@ncsa.uiuc.edu> + * Friday, October 16th, 1998 + * + * Purpose: Convert H5 files to H4 files. + */ + +#ifndef _H5TOH4_H +#define _H5TOH4_H + +#include "hdf.h" +#include "mfhdf.h" +#include "hdf5.h" + +#ifdef H5_HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif + +typedef struct op_data_t { + /* + * information being carried between iterations. + * + */ + + int32 hfile_id; + int32 vgroup_id; + int32 sd_id; + int32 sds_id; + int32 vdata_id; + int32 obj_idx; + +} op_data_t; + +#ifdef H5TOH4_DEBUG +#define DEBUG_PRINT(s1,s2,s3,n1) ( fprintf(stderr,s1,s2,s3,n1) ) +#else +#define DEBUG_PRINT(s1,s2,s3,n1) ( fprintf(stderr," ") ) +#endif + +#endif diff --git a/tools/h5toh4/testh5toh4.sh b/tools/h5toh4/testh5toh4.sh new file mode 100755 index 0000000..986a6a2 --- /dev/null +++ b/tools/h5toh4/testh5toh4.sh @@ -0,0 +1,299 @@ +#! /bin/sh +# +# Copyright (C) 1997-2001 National Center for Supercomputing Applications. +# All rights reserved. +# + +H5TOH4=h5toh4 # a relative name +H5TOH4_BIN=`pwd`/$H5TOH4 # an absolute command path + +cmp='cmp -s' +diff='diff -c' + +RM='rm -f' +SED='sed ' +H4DUMP='hdp' + +# Verify if $H4DUMP is a valid command. +tmpfile=/tmp/testh5toh4.$$ +$H4DUMP -H > $tmpfile +if test -s "$tmpfile"; then + # Find out which version of hdp is being used. Over simplified + # algorithm but will do the job for now. + if ( grep -s 'NCSA HDF Version 4.1 Release [3-9]' $tmpfile > /dev/null ) + then + H4DUMPVER=413 + else + H4DUMPVER=0 + echo " Some tests maybe skipped because your version of $H4DUMP does" + echo " not handle loops in Vgroups correctly. You need version" + echo " 4.1 Release 3 or later. Visit http://hdf.ncsa.uiuc.edu" + echo " or email hdfhelp@ncsa.uiuc.edu for more information." + fi +else + echo " Could not run the '$H4DUMP' command. The test can still proceed" + echo " but it may fail if '$H4DUMP' is needed to verify the output." + echo " You can make sure '$H4DUMP' is among your shell PATH and run" + echo " the test again. You may also visit http://hdf.ncsa.uiuc.edu" + echo " or email hdfhelp@ncsa.uiuc.edu for more information." + H4DUMP=: + H4DUMPVER=0 +fi +$RM $tmpfile + +# The build (current) directory might be different than the source directory. +if test -z "$srcdir"; then + srcdir=. +fi +mkdir ../testfiles >/dev/null 2>&1 + +SRCDIR="$srcdir/../testfiles" +OUTDIR="../testfiles/Results" + +test -d $OUTDIR || mkdir $OUTDIR + +nerrors=0 +verbose=yes + +# Print a line-line message left justified in a field of 70 characters +# beginning with the word "Testing". +TESTING() { + SPACES=" " + echo "Testing $* $SPACES" |cut -c1-70 |tr -d '\012' +} + +# Run a test and print PASS or *FAIL*. If a test fails then increment +# the `nerrors' global variable and (if $verbose is set) display the +# difference between the actual and the expected hdf4 files. The +# expected hdf4 files are in testfiles/Expected directory. +# The actual hdf4 file is not removed if $HDF5_NOCLEANUP is to a non-null +# value. +CONVERT() { + # Run h5toh4 convert. + TESTING $H5TOH4 $@ + + # + # Set up arguments to run the conversion test. + # The converter assumes all hdf5 files has the .h5 suffix as in the form + # of foo.h5. It creates the corresponding hdf4 files with the .hdf suffix + # as in the form of foo.hdf. One exception is that if exactly two file + # names are given, it treats the first argument as an hdf5 file and creates + # the corresponding hdf4 file with the name as the second argument, WITOUT + # any consideration of the suffix. (For this test script, in order to + # match the output hdf4 file with the expected hdf4 file, it expects the + # second file of the two-files tests has the .hdf suffix too.) + # + # If SRCDIR != OUTDIR, need to copy the input hdf5 files from the SRCDIR + # to the OUTDIR and transform the input file pathname because of the suffix + # convention mentioned above. This way, the hdf4 files are always created + # in the OUTDIR directory. + # + + INFILES="" + OUTFILES="" + MULTIRUN="" + + case "$1" in + "-m") # multiple files conversion + MULTIRUN="-m" + shift + for f in $* + do + if test "$SRCDIR" != "$OUTDIR"; then + cp $SRCDIR/$f $OUTDIR/$f + fi + INFILES="$INFILES $f" + OUTFILES="$OUTFILES `basename $f .h5`.hdf" + shift + done + ;; + * ) # Single file conversion + case $# in + 1) if test "$SRCDIR" != "$OUTDIR"; then + cp $SRCDIR/$1 $OUTDIR/$1 + fi + INFILES="$1" + OUTFILES="`basename $1 .h5`.hdf" + ;; + 2) # hdf4 file specified + if test "$SRCDIR" != "$OUTDIR"; then + cp $SRCDIR/$1 $OUTDIR/$1 + fi + INFILES="$1" + OUTFILES="$2" + ;; + *) # Illegal + echo "Illegal arguments" + exit 1 + ;; + esac + ;; + esac + + # run the conversion and remove input files that have been copied over + ( + cd $OUTDIR + $H5TOH4_BIN $MULTIRUN $INFILES 2>/dev/null + if test "$SRCDIR" != "$OUTDIR"; then + $RM $INFILES + fi + ) + + # Verify results + result="passed" + for f in $OUTFILES + do + if $cmp $SRCDIR/Expected/$f $OUTDIR/$f + then + : + else + # Use hdp to dump the files and verify the output. + # Filter out the output of "reference = ..." because + # reference numbers are immaterial in general. + outfile=`basename $f .hdf` + expect_out=$outfile.expect + actual_out=$outfile.actual + + if [ $outfile = "tloop" -a $H4DUMPVER -lt 413 ] + then + echo " -SKIP-" + result="skipped" + touch $expect_out $actual_out # fake them + else + (cd $SRCDIR/Expected + $H4DUMP dumpvg $outfile.hdf + $H4DUMP dumpvd $outfile.hdf + $H4DUMP dumpsds $outfile.hdf ) | + sed -e 's/reference = [0-9]*;//' > $expect_out + (cd $OUTDIR + $H4DUMP dumpvg $outfile.hdf + $H4DUMP dumpvd $outfile.hdf + $H4DUMP dumpsds $outfile.hdf ) | + sed -e 's/reference = [0-9]*;//' > $actual_out + fi + + if [ "passed" = $result -a ! -s $actual_out ] ; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + result=failed + test yes = "$verbose" && + echo " H4DUMP failed to produce valid output" + elif $cmp $expect_out $actual_out; then + : + else + if test "passed" = $result; then + echo "*FAILED*" + nerrors="`expr $nerrors + 1`" + result=failed + fi + test yes = "$verbose" && + echo " Actual result (*.actual) differs from expected result (*.expect)" && + $diff $expect_out $actual_out |sed 's/^/ /' + fi + fi + + # Clean up output file + if test -z "$HDF5_NOCLEANUP"; then + $RM $expect_out $actual_out + $RM $OUTDIR/$f + fi + done + if test "passed" = "$result"; then + echo " PASSED" + fi +} + + + +############################################################################## +############################################################################## +### T H E T E S T S ### +############################################################################## +############################################################################## + +$RM $OUTDIR/*.hdf $OUTDIR/*.tmp + +# +# The HDF4 filenames are created based upon the HDF5 filenames +# without the extension. +# + +# test for converting H5 groups to H4 Vgroups. +CONVERT tgroup.h5 + +# test for converting H5 datasets to H4 SDS's. +CONVERT tdset.h5 + +# test for converting H5 attributes to H4 attributes. +CONVERT tattr.h5 + +# test for converting H5 soft links. +CONVERT tslink.h5 + +# test for converting H5 hard links. +CONVERT thlink.h5 + +# test for converting H5 compound data type to H4 Vdata. +CONVERT tcompound.h5 + +# test for converting all H5 objects at in same file. +CONVERT tall.h5 + +# tests for converting H5 objects with loops. +CONVERT tloop.h5 + +# test for converting extendable H5 datasets to H4 SDS's. +CONVERT tdset2.h5 + +# test for converting extendable H5 datasets with compound data type to H4 Vdata. +CONVERT tcompound2.h5 + +# tests for converting H5 objects from many different pathways. +CONVERT tmany.h5 + +# tests for converting H5 string objects. +CONVERT tstr.h5 + +# tests for converting more H5 string objects. +CONVERT tstr2.h5 + +# +# The test for conversion are the same as above with the only difference +# being that the HDF4 filenames are given explicitly. +# + +$RM $OUTDIR/*.tmp +CONVERT tgroup.h5 tgroup.hdf +CONVERT tdset.h5 tdset.hdf +CONVERT tattr.h5 tattr.hdf +CONVERT tslink.h5 tslink.hdf +CONVERT thlink.h5 thlink.hdf +CONVERT tcompound.h5 tcompound.hdf +CONVERT tall.h5 tall.hdf +CONVERT tloop.h5 tloop.hdf +CONVERT tdset2.h5 tdset2.hdf +CONVERT tcompound2.h5 tcompound2.hdf +CONVERT tmany.h5 tmany.hdf +CONVERT tstr.h5 tstr.hdf +CONVERT tstr2.h5 tstr2.hdf + +# +# Again, the test for conversion are the same as the first set of test. +# Here, multiple conversion are done on HDF5 files at one time. +# + +$RM $OUTDIR/*.hdf $OUTDIR/*.tmp +CONVERT -m tgroup.h5 tdset.h5 tattr.h5 tslink.h5 thlink.h5 +CONVERT -m tcompound.h5 tall.h5 +CONVERT -m tloop.h5 +CONVERT -m tdset2.h5 tcompound2.h5 tmany.h5 +CONVERT -m tstr.h5 tstr2.h5 + +if test $nerrors -eq 0 ; then + echo "All h5toh4 tests passed." +fi + +if test -z "$HDF5_NOCLEANUP"; then + $RM -r $OUTDIR +fi +exit $nerrors |