diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2011-04-29 18:38:41 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2011-04-29 18:38:41 (GMT) |
commit | 87994982f9a061f8a8c5584dcafbde7b3b33b790 (patch) | |
tree | 511d65dcf60397c626db8283490dc0a2855bfd60 /tools/h5dump/h5dump.c | |
parent | 170e7e53a515be431a33c4e191b0be7c74e14ae5 (diff) | |
download | hdf5-87994982f9a061f8a8c5584dcafbde7b3b33b790.zip hdf5-87994982f9a061f8a8c5584dcafbde7b3b33b790.tar.gz hdf5-87994982f9a061f8a8c5584dcafbde7b3b33b790.tar.bz2 |
[svn-r20677] Merge packed bits option from 1.8 branch to trunk. CMake only. Autotools merge to come.
Tested: local Linux
Diffstat (limited to 'tools/h5dump/h5dump.c')
-rw-r--r-- | tools/h5dump/h5dump.c | 250 |
1 files changed, 248 insertions, 2 deletions
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 64575c2..da6e806 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -93,11 +93,25 @@ static int display_ai = TRUE; /*array index */ static int display_escape = FALSE; /*escape non printable characters */ static int display_region = FALSE; /*print region reference data */ static int enable_error_stack= FALSE; /* re-enable error stack */ +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +static int display_packed_bits = FALSE; /*print 1-8 byte numbers as packed bits*/ +#endif /* sort parameters */ static H5_index_t sort_by = H5_INDEX_NAME; /*sort_by [creation_order | name] */ static H5_iter_order_t sort_order = H5_ITER_INC; /*sort_order [ascending | descending] */ +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +#define PACKED_BITS_MAX 8 /* Maximum number of packed-bits to display */ +#define PACKED_BITS_SIZE_MAX 8*sizeof(long long) /* Maximum bits size of integer types of packed-bits */ +/* mask list for packed bits */ +static unsigned long long packed_mask[PACKED_BITS_MAX]; /* packed bits are restricted to 8*sizeof(llong) bytes */ + +/* packed bits display parameters */ +static int packed_offset[PACKED_BITS_MAX]; +static int packed_length[PACKED_BITS_MAX]; +#endif + /** ** Added for XML ** **/ @@ -117,6 +131,9 @@ static int indent; /*how far in to indent the line /* internal functions */ static hid_t h5_fileaccess(void); static void dump_oid(hid_t oid); +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +static void dump_packed_bits(unsigned int packed_index, hid_t type); +#endif static void print_enum(hid_t type); static int xml_name_to_XID(const char *, char *, int , int ); static void init_prefix(char **prfx, size_t prfx_len); @@ -387,7 +404,14 @@ struct handler_t { * parameters. The long-named ones can be partially spelled. When * adding more, make sure that they don't clash with each other. */ -static const char *s_opts = "hnpeyBHirVa:c:d:f:g:k:l:t:w:xD:uX:o:b*F:s:S:Aq:z:m:RE"; +/* The following initialization makes use of C language cancatenating */ +/* "xxx" "yyy" into "xxxyyy". */ +static const char *s_opts = "hnpeyBHirVa:c:d:f:g:k:l:t:w:xD:uX:o:b*F:s:S:Aq:z:m:RE" +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +"M:" +#endif +; /* end of *s_opt initialization */ + static struct long_options l_opts[] = { { "help", no_arg, 'h' }, { "hel", no_arg, 'h' }, @@ -501,6 +525,9 @@ static struct long_options l_opts[] = { { "format", require_arg, 'm' }, { "region", no_arg, 'R' }, { "enable-error-stack", no_arg, 'E' }, +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + { "packed-bits", require_arg, 'M' }, +#endif { NULL, 0, '\0' } }; @@ -656,6 +683,16 @@ usage(const char *prog) fprintf(stdout, " -m T, --format=T Set the floating point output format\n"); fprintf(stdout, " -q Q, --sort_by=Q Sort groups and attributes by index Q\n"); fprintf(stdout, " -z Z, --sort_order=Z Sort groups and attributes by order Z\n"); +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + fprintf(stdout, + " -M L, --packedbits=L Print packed bits as unsigned integers, using mask\n" + " format L for an integer dataset specified with\n" + " option -d. L is a list of offset,length values,\n" + " separated by commas. Offset is the beginning bit in\n" + " the data value and length is the number of bits of\n" + " the mask.\n" + ); +#endif fprintf(stdout, " -R, --region Print dataset pointed by region references\n"); fprintf(stdout, " -x, --xml Output in XML using Schema\n"); fprintf(stdout, " -u, --use-dtd Output in XML using DTD\n"); @@ -712,6 +749,12 @@ usage(const char *prog) fprintf(stdout, " using a little-endian type\n"); fprintf(stdout, "\n"); fprintf(stdout, " h5dump -d /dset -b LE -o out.bin quux.h5\n"); +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + fprintf(stdout, "\n"); + fprintf(stdout, " 4) Display two packed bits (bits 0-1 and bits 4-6) in the dataset /dset\n"); + fprintf(stdout, "\n"); + fprintf(stdout, " h5dump -d /dset -M 0,1,4,3 quux.h5\n"); +#endif fprintf(stdout, "\n"); } @@ -2270,7 +2313,19 @@ dump_dataset(hid_t did, const char *name, struct subset_t *sset) if(display_dcpl) dump_dcpl(dcpl_id, type, did); - if(display_data) + if(display_data) { +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + int data_loop = 1; + int i; + if(display_packed_bits) + data_loop = packed_bits_num; + for(i=0;i<data_loop;i++) { + if(display_packed_bits) { + dump_packed_bits(i, type); + packed_data_mask = packed_mask[i]; + packed_data_offset = packed_offset[i]; + } +#endif switch(H5Tget_class(type)) { case H5T_TIME: indentation(indent + COL); @@ -2293,6 +2348,10 @@ dump_dataset(hid_t did, const char *name, struct subset_t *sset) default: break; } /* end switch */ +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + } /* for(i=0;i<data_loop;i++) */ +#endif + } indent += COL; @@ -2672,6 +2731,64 @@ dump_oid(hid_t oid) indentation(indent + COL); printf("%s %s %d %s\n", OBJID, BEGIN, oid, END); } +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +/*------------------------------------------------------------------------- + * Function: dump_packed_bits + * + * Purpose: Prints the packed bits offset and length + * + * Return: void + * + *------------------------------------------------------------------------- + */ +static void +dump_packed_bits(unsigned int packed_index, hid_t type) +{ + int packed_bits_size = 0; + hid_t n_type = h5tools_get_native_type(type); + if(H5Tget_class(n_type)==H5T_INTEGER) { + if(H5Tequal(n_type, H5T_NATIVE_SCHAR) == TRUE) { + packed_bits_size = 8 * sizeof(char); + } + else if(H5Tequal(n_type, H5T_NATIVE_UCHAR) == TRUE) { + packed_bits_size = 8 * sizeof(unsigned char); + } + else if(H5Tequal(n_type, H5T_NATIVE_SHORT) == TRUE) { + packed_bits_size = 8 * sizeof(short); + } + else if(H5Tequal(n_type, H5T_NATIVE_USHORT) == TRUE) { + packed_bits_size = 8 * sizeof(unsigned short); + } + else if(H5Tequal(n_type, H5T_NATIVE_INT) == TRUE) { + packed_bits_size = 8 * sizeof(int); + } + else if(H5Tequal(n_type, H5T_NATIVE_UINT) == TRUE) { + packed_bits_size = 8 * sizeof(unsigned int); + } + else if(H5Tequal(n_type, H5T_NATIVE_LONG) == TRUE) { + packed_bits_size = 8 * sizeof(long); + } + else if(H5Tequal(n_type, H5T_NATIVE_ULONG) == TRUE) { + packed_bits_size = 8 * sizeof(unsigned long); + } + else if(H5Tequal(n_type, H5T_NATIVE_LLONG) == TRUE) { + packed_bits_size = 8 * sizeof(long long); + } + else if(H5Tequal(n_type, H5T_NATIVE_ULLONG) == TRUE) { + packed_bits_size = 8 * sizeof(unsigned long long); + } + else + error_msg("Packed Bit not valid for this datatype"); + } + indentation(indent + COL); + if ((packed_bits_size>0) && (packed_offset[packed_index] + packed_length[packed_index]) > packed_bits_size) { + error_msg("Packed Bit offset+length value(%d) too large. Max is %d\n", + packed_offset[packed_index]+packed_length[packed_index], packed_bits_size); + packed_mask[packed_index] = 0; + }; + printf("%s %s=%d %s=%d\n", PACKED_BITS, PACKED_OFFSET, packed_offset[packed_index], PACKED_LENGTH, packed_length[packed_index]); +} +#endif /*------------------------------------------------------------------------- * Function: dump_comment @@ -3583,6 +3700,120 @@ parse_subset_params(char *dset) return s; } +#ifdef H5_HAVE_H5DUMP_PACKED_BITS +/*------------------------------------------------------------------------- + * Function: parse_mask_list + * + * Purpose: Parse a list of comma or space separated integers and fill + * the packed_bits list and counter. The string being passed into this function + * should be at the start of the list you want to parse. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * + *------------------------------------------------------------------------- + */ +static int +parse_mask_list(const char *h_list) +{ + const char *ptr; + int offset_value, length_value; + unsigned long long temp_mask; + + /* sanity check */ + HDassert(h_list); + + HDmemset(packed_mask,0,sizeof(packed_mask)); + + packed_bits_num = 0; + /* scan in pair of offset,length separated by commas. */ + ptr = h_list; + while (*ptr) { + /* scan for an offset which is an unsigned int */ + if (!HDisdigit(*ptr)){ + error_msg("Bad mask list(%s)\n", h_list); + return FAIL; + } + offset_value = HDatoi(ptr); + if (offset_value < 0 || offset_value >= PACKED_BITS_SIZE_MAX){ + error_msg("Packed Bit offset value(%d) must be between 0 and %d\n", + offset_value, PACKED_BITS_SIZE_MAX - 1); + return FAIL; + } + + /* skip to end of integer */ + while (HDisdigit(*++ptr)) + ; + /* Look for the common separator */ + if (*ptr++ != ',') { + error_msg("Bad mask list(%s), missing expected comma separator.\n", h_list); + return FAIL; + } + + /* scan for a length which is a positive int */ + if (!HDisdigit(*ptr)){ + error_msg("Bad mask list(%s)\n", h_list); + return FAIL; + } + length_value = HDatoi(ptr); + if (length_value <= 0){ + error_msg("Packed Bit length value(%d) must be positive.\n", + length_value); + return FAIL; + }; + if ((offset_value + length_value) > PACKED_BITS_SIZE_MAX){ + error_msg("Packed Bit offset+length value(%d) too large. Max is %d\n", + offset_value+length_value, PACKED_BITS_SIZE_MAX); + return FAIL; + }; + + /* skip to end of int */ + while (HDisdigit(*++ptr)) + ; + + /* store the offset,length pair */ + if (packed_bits_num >= PACKED_BITS_MAX){ + /* too many requests */ + error_msg("Too many masks requested (max. %d). Mask list(%s)\n", + PACKED_BITS_MAX, h_list); + return FAIL; + } + packed_offset[packed_bits_num] = offset_value; + packed_length[packed_bits_num] = length_value; + /* create the bit mask by left shift 1's by length, then negate it. */ + /* After packed_mask is calculated, packed_length is not needed but */ + /* keep it for debug purpose. */ + temp_mask = ~0L; + if(length_value<8*sizeof(unsigned long long)) { + temp_mask = temp_mask << length_value; + packed_mask[packed_bits_num] = ~temp_mask; + } + else + packed_mask[packed_bits_num] = temp_mask; + packed_bits_num++; + + /* skip a possible comma separator */ + if (*ptr == ','){ + if (!(*++ptr)){ + /* unexpected end of string */ + error_msg("Bad mask list(%s), unexpected end of string.\n", h_list); + return FAIL; + } + } + } + HDassert(packed_bits_num <= PACKED_BITS_MAX); + if (packed_bits_num == 0){ + /* got no masks! */ + error_msg("Bad mask list(%s)\n", h_list); + return FAIL; + } + return SUCCEED; +} + +#endif + /*------------------------------------------------------------------------- * Function: handle_datasets * @@ -4172,6 +4403,21 @@ parse_start: } break; +#ifdef H5_HAVE_H5DUMP_PACKED_BITS + case 'M': + if (!last_was_dset) { + error_msg("option `-%c' can only be used after --dataset option\n", + opt); + leave(EXIT_FAILURE); + } + if (parse_mask_list(opt_arg) != SUCCEED){ + usage(h5tools_getprogname()); + leave(EXIT_FAILURE); + } + display_packed_bits = TRUE; + break; +#endif + /** begin XML parameters **/ case 'x': /* select XML output */ |