summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5T.c1
-rw-r--r--src/H5Tbit.c119
-rw-r--r--src/H5Tconv.c382
-rw-r--r--src/H5Tpkg.h7
4 files changed, 507 insertions, 2 deletions
diff --git a/src/H5T.c b/src/H5T.c
index f10752d..f614d32 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -955,6 +955,7 @@ H5T_init_interface(void)
status |= H5T_register(H5T_PERS_SOFT, "i_i", fixedpt, fixedpt, H5T_conv_i_i, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "f_f", floatpt, floatpt, H5T_conv_f_f, H5AC_dxpl_id);
+ status |= H5T_register(H5T_PERS_SOFT, "f_i", floatpt, fixedpt, H5T_conv_f_i, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "s_s", string, string, H5T_conv_s_s, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "b_b", bitfield, bitfield, H5T_conv_b_b, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "ibo", fixedpt, fixedpt, H5T_conv_order, H5AC_dxpl_id);
diff --git a/src/H5Tbit.c b/src/H5Tbit.c
index 157da5d..d063137 100644
--- a/src/H5Tbit.c
+++ b/src/H5Tbit.c
@@ -78,7 +78,7 @@ H5T_bit_copy (uint8_t *dst, size_t dst_offset, const uint8_t *src,
* ... v v v v v V V V V V
* ...+---------------+---------------+
* ...|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
- * ...+---------------+---------------+
+ ...+---------------+---------------+
* dst[d_idx+1] dst[d_idx]
*/
while (src_offset && size>0) {
@@ -161,6 +161,59 @@ H5T_bit_copy (uint8_t *dst, size_t dst_offset, const uint8_t *src,
/*-------------------------------------------------------------------------
+ * Function: H5T_bit_shift
+ *
+ * Purpose: Simulation of hardware shifting. Shifts a bit vector
+ * in a way similar to shifting a variable value, like
+ * value <<= 3, or value >>= 16.
+ *
+ * Return: void
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, Febuary 4, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5T_bit_shift (uint8_t *buf, hssize_t shift_dist, size_t buf_size)
+{
+ uint8_t *tmp_buf;
+ size_t buf_size_bit = 8*buf_size;
+ size_t i;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5T_bit_shift);
+
+ if(!shift_dist)
+ goto done;
+ if(abs(shift_dist) >= buf_size_bit) {
+ H5T_bit_set (buf, 0, buf_size_bit, FALSE);
+ goto done;
+ }
+
+ tmp_buf = (uint8_t*)HDcalloc(buf_size, 1);
+
+ /* Shift vector by making copies */
+ if(shift_dist > 0) /* left shift */
+ H5T_bit_copy (tmp_buf, shift_dist, buf, 0, buf_size_bit-shift_dist);
+ else { /* right shift */
+ shift_dist = -shift_dist;
+ H5T_bit_copy(tmp_buf, 0, buf, shift_dist, buf_size_bit-shift_dist);
+ }
+
+ /* Copy back the vector */
+ for(i=0; i<buf_size; i++)
+ buf[i] = tmp_buf[i];
+
+ HDfree(tmp_buf);
+
+done:
+ FUNC_LEAVE_NOAPI_VOID
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_bit_get_d
*
* Purpose: Return a small bit sequence as a number.
@@ -439,7 +492,7 @@ H5T_bit_inc(uint8_t *buf, size_t start, size_t size)
unsigned acc, mask;
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_bit_find);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_bit_inc);
assert(buf);
start %= 8;
@@ -480,3 +533,65 @@ H5T_bit_inc(uint8_t *buf, size_t start, size_t size)
FUNC_LEAVE_NOAPI(carry ? TRUE : FALSE);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_bit_dec
+ *
+ * Purpose: decrement part of a bit field by 1.
+ * At this moment, START is always 0 and the algorithm only
+ * works from the end to the front for the buffer.
+ *
+ * Return: void
+ *
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, Jan 28, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5T_bit_dec(uint8_t *buf, size_t start, size_t size)
+{
+ size_t idx;
+
+ assert(buf);
+
+ for(idx=0; idx < size/8; idx++) {
+ if(buf[idx] != 0x00) {
+ buf[idx] -= 1;
+ break;
+ } else if(buf[idx]==0x00) {
+ buf[idx] -= 1;
+ }
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_bit_neg
+ *
+ * Purpose: Bit-negate buffer.
+ * At this moment, START is always 0.
+ *
+ * Return: void
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, Jan 28, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5T_bit_neg(uint8_t *buf, size_t start, size_t size)
+{
+ size_t i;
+
+ assert(buf);
+
+ for(i=0; i<size/8; i++)
+ buf[i] = ~(buf[i]);
+}
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 862c19a..cd7a301 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -2935,6 +2935,7 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
}
} else if (src->u.atomic.prec<dst->u.atomic.prec) {
H5T_bit_copy (d, dst->u.atomic.offset, s, src->u.atomic.offset, src->u.atomic.prec);
+ /* Why is it set to TRUE? */
H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec, dst->u.atomic.prec-src->u.atomic.prec, TRUE);
} else {
H5T_bit_copy (d, dst->u.atomic.offset, s, src->u.atomic.offset, dst->u.atomic.prec);
@@ -8363,3 +8364,384 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
done:
FUNC_LEAVE_NOAPI(ret_value);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_conv_f_i
+ *
+ * Purpose: Convert one floating-point type to an integer. This is
+ * the catch-all function for float-integer conversions and
+ * is probably not particularly fast.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, Jan 21, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
+ size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg,
+ hid_t UNUSED dxpl_id)
+{
+ /* Traversal-related variables */
+ H5T_t *src_p; /*source data type */
+ H5T_t *dst_p; /*destination data type */
+ H5T_atomic_t src; /*atomic source info */
+ H5T_atomic_t dst; /*atomic destination info */
+ int direction; /*forward or backward traversal */
+ hsize_t elmtno; /*element number */
+ size_t half_size; /*half the type size */
+ hsize_t olap; /*num overlapping elements */
+ ssize_t bitno; /*bit number */
+ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/
+ uint8_t dbuf[64]; /*temp destination buffer */
+
+ /* Conversion-related variables */
+ hssize_t expo; /*source exponent */
+ hssize_t mant; /*source mantissa */
+ hssize_t sign; /*source sign bit value */
+ uint8_t *int_buf; /*buffer for temporary value */
+ size_t buf_size; /*buffer size for temporary value */
+ size_t msize; /*mantissa size after restored implied 1 */
+ size_t i; /*miscellaneous counters */
+ size_t first; /*first bit(MSB) in an integer */
+ ssize_t sfirst; /*a signed version of `first' */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5T_conv_f_i, FAIL);
+
+ switch (cdata->command) {
+ case H5T_CONV_INIT:
+ if (NULL==(src_p=H5I_object(src_id)) ||
+ NULL==(dst_p=H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ src = src_p->u.atomic;
+ dst = dst_p->u.atomic;
+ if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order");
+ if (dst_p->size>sizeof(dbuf))
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large");
+ if (8*sizeof(expo)-1<src.u.f.esize)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large");
+ cdata->need_bkg = H5T_BKG_NO;
+ break;
+
+ case H5T_CONV_FREE:
+ break;
+
+ case H5T_CONV_CONV:
+ /* Get the data types */
+ if (NULL==(src_p=H5I_object(src_id)) ||
+ NULL==(dst_p=H5I_object(dst_id)))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ src = src_p->u.atomic;
+ dst = dst_p->u.atomic;
+
+ /*
+ * Do we process the values from beginning to end or vice versa? Also,
+ * how many of the elements have the source and destination areas
+ * overlapping?
+ */
+ if (src_p->size==dst_p->size || buf_stride) {
+ sp = dp = (uint8_t*)buf;
+ direction = 1;
+ olap = nelmts;
+ } else if (src_p->size>=dst_p->size) {
+ double olap_d = HDceil((double)(dst_p->size)/
+ (double)(src_p->size-dst_p->size));
+ olap = (size_t)olap_d;
+ sp = dp = (uint8_t*)buf;
+ direction = 1;
+ } else {
+ double olap_d = HDceil((double)(src_p->size)/
+ (double)(dst_p->size-src_p->size));
+ olap = (size_t)olap_d;
+ sp = (uint8_t*)buf + (nelmts-1) * src_p->size;
+ dp = (uint8_t*)buf + (nelmts-1) * dst_p->size;
+ direction = -1;
+ }
+
+ /* Allocate enough space for the buffer holding temporary
+ * converted value
+ */
+ buf_size = (int)pow(2, src.u.f.esize) / 8 + 1;
+ int_buf = (uint8_t*)HDcalloc(buf_size, 1);
+
+ /* The conversion loop */
+ for (elmtno=0; elmtno<nelmts; elmtno++) {
+ /*
+ * If the source and destination buffers overlap then use a
+ * temporary buffer for the destination.
+ */
+ if (direction>0) {
+ s = sp;
+ d = elmtno<olap ? dbuf : dp;
+ } else {
+ s = sp;
+ d = elmtno+olap >= nelmts ? dbuf : dp;
+ }
+#ifndef NDEBUG
+ /* I don't quite trust the overlap calculations yet --rpm */
+ if (d==dbuf) {
+ assert ((dp>=sp && dp<sp+src_p->size) ||
+ (sp>=dp && sp<dp+dst_p->size));
+ } else {
+ assert ((dp<sp && dp+dst_p->size<=sp) ||
+ (sp<dp && sp+src_p->size<=dp));
+ }
+#endif
+ /*
+ * Put the data in little endian order so our loops aren't so
+ * complicated. We'll do all the conversion stuff assuming
+ * little endian and then we'll fix the order at the end.
+ */
+ if (H5T_ORDER_BE==src.order) {
+ half_size = src_p->size/2;
+ for (i=0; i<half_size; i++) {
+ uint8_t tmp = s[src_p->size-(i+1)];
+ s[src_p->size-(i+1)] = s[i];
+ s[i] = tmp;
+ }
+ }
+
+ /*zero-set all destination bits*/
+ H5T_bit_set (d, dst.offset, dst.prec, FALSE);
+
+ /*
+ * Find the sign bit value of the source.
+ */
+ sign = H5T_bit_get_d(s, src.prec-1, 1);
+
+ /*
+ * Check for special cases: +0, -0, +Inf, -Inf, NaN
+ */
+ if (H5T_bit_find (s, src.u.f.mpos, src.u.f.msize,
+ H5T_BIT_LSB, TRUE)<0) {
+ if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
+ H5T_BIT_LSB, TRUE)<0) {
+ /* +0 or -0 */
+ /* Set all bits to zero */
+ goto padding;
+ } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
+ H5T_BIT_LSB, FALSE)<0) {
+ /* +Infinity or -Infinity */
+ if(sign) { /* -Infinity */
+ if (H5T_SGN_2==dst.u.i.sign)
+ H5T_bit_set (d, dst.prec-1, 1, TRUE);
+ } else { /* +Infinity */
+ if (H5T_SGN_NONE==dst.u.i.sign)
+ H5T_bit_set (d, dst.offset, dst.prec, TRUE);
+ else if (H5T_SGN_2==dst.u.i.sign)
+ H5T_bit_set (d, dst.offset, dst.prec-1, TRUE);
+ }
+ goto padding;
+ }
+ } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
+ H5T_BIT_LSB, FALSE)<0) {
+ /*
+ * NaN. There are many NaN values, so we just set all bits to zero.
+ */
+ goto padding;
+ }
+
+ /*
+ * Get the exponent as an unsigned quantity from the section of
+ * the source bit field where it's located. Not expecting
+ * exponent to be greater than the maximal value of hssize_t.
+ */
+ expo = H5T_bit_get_d(s, src.u.f.epos, src.u.f.esize);
+
+ /*
+ * Calculate the true source exponent by adjusting according to
+ * the source exponent bias.
+ */
+ if (0==expo || H5T_NORM_NONE==src.u.f.norm) {
+ /*Don't get this part*/
+ bitno = H5T_bit_find(s, src.u.f.mpos, src.u.f.msize,
+ H5T_BIT_MSB, TRUE);
+ assert(bitno>=0);
+ expo -= (src.u.f.ebias-1) + (src.u.f.msize-bitno);
+ } else if (H5T_NORM_IMPLIED==src.u.f.norm) {
+ expo -= src.u.f.ebias;
+ } else {
+ assert("normalization method not implemented yet" && 0);
+ HDabort();
+ }
+
+ /*
+ * Get the mantissa as bit vector from the section of
+ * the source bit field where it's located.
+ * Keep the little-endian order in the buffer.
+ * A sequence 0x01020304 will be like in the buffer,
+ * 04 03 02 01
+ * | | | |
+ * V V V V
+ * buf[0] buf[1] buf[2] buf[3]
+ */
+ H5T_bit_copy(int_buf, 0, s, src.u.f.mpos, src.u.f.msize);
+
+ /*
+ * Restore the implicit bit for mantissa if it's implied.
+ * Equivalent to mantissa |= (hsize_t)1<<src.u.f.msize.
+ */
+ if (H5T_NORM_IMPLIED==src.u.f.norm) {
+ H5T_bit_inc(int_buf, src.u.f.msize, 8*buf_size-src.u.f.msize);
+ msize = src.u.f.msize + 1;
+ } else
+ msize = src.u.f.msize;
+
+ /* Keep the print commands for future debugging */
+ /*fprintf(stderr, "expo=%ld ", expo);
+ fprintf(stderr, "src.u.f.msize=%d ", src.u.f.msize);
+ fprintf(stderr, "mant=0x%016x\n", mant);*/
+
+ /*
+ * Shift mantissa part by exponent minus mantissa size(right shift),
+ * or by mantissa size minus exponent(left shift).
+ */
+ if( H5T_NORM_IMPLIED==src.u.f.norm) {
+ H5T_bit_shift(int_buf, expo - src.u.f.msize, buf_size);
+ } else if(H5T_NORM_NONE==src.u.f.norm) {
+ /* How to do this? */
+ }
+
+ /*fprintf(stderr, "int_buf=");
+ for(i=0; i<buf_size; i++)
+ fprintf(stderr, "%02x ", int_buf[i]);
+ fprintf(stderr, "\n");*/
+
+ /* Convert to integer representation if negative.
+ * equivalent to ~(value - 1).
+ */
+ if(sign) {
+ H5T_bit_dec(int_buf, 0, 8*buf_size);
+ /*fprintf(stderr, "decremented int_buf=");
+ for(i=0; i<buf_size; i++)
+ fprintf(stderr, "%02x ", int_buf[i]);
+ fprintf(stderr, "\n");*/
+
+ H5T_bit_neg(int_buf, 0, 8*buf_size);
+ /*fprintf(stderr, "negated int_buf=");
+ for(i=0; i<buf_size; i++)
+ fprintf(stderr, "%02x ", int_buf[i]);
+ fprintf(stderr, "\n");*/
+ }
+
+ /*
+ * What is the bit position for the most significant bit(MSB) of S
+ * which is set?
+ */
+ sfirst = H5T_bit_find(int_buf, 0, 8*buf_size, H5T_BIT_MSB, TRUE);
+ first = (size_t)sfirst;
+ /*fprintf(stderr, " first=%d\n", first);*/
+
+ if(sfirst < 0) {
+ /*
+ * The source has no bits set and must therefore be zero.
+ * Set the destination to zero - nothing to do.
+ */
+ } else if (H5T_SGN_NONE==dst.u.i.sign) {
+ /*
+ * Destination is unsigned. If the source value is greater
+ * than the maximal destination value then it overflows, the
+ * destination will be set to the maximum possible value. When the
+ * source is negative, underflow happens. Set the destination to be
+ * zero.
+ */
+ if(!sign) {
+ if (first>=dst.prec) {
+ /*overflow*/
+ if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, s, d)<0) {
+ H5T_bit_set (d, dst.offset, dst.prec, TRUE);
+ }
+ } else if (first <dst.prec) {
+ /*copy source value into it*/
+ H5T_bit_copy (d, dst.offset, int_buf, 0, first+1);
+ }
+ }
+ } else if (H5T_SGN_2==dst.u.i.sign) {
+ if(sign) { /*negative*/
+ /* if overflows, do nothing except turn on the sign bit
+ * because 0x80...00 is the biggest negative value.
+ */
+ if(first < dst.prec-1)
+ H5T_bit_copy (d, dst.offset, int_buf, 0, first+1);
+
+ H5T_bit_set (d, (dst.offset + dst.prec-1), 1, TRUE);
+ } else { /*positive*/
+ if (first >= dst.prec-1) {
+ /*overflow*/
+ if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, s, d)<0) {
+ H5T_bit_set (d, dst.offset, dst.prec-1, TRUE);
+ }
+ } else if(first < dst.prec-1) {
+ H5T_bit_copy (d, dst.offset, int_buf, 0, first+1);
+ }
+ }
+ }
+
+ /*fprintf(stderr, "dst.offset=%d, d=0x", dst.offset);
+ for(i=0; i<dst.prec/8; i++)
+ fprintf(stderr, "%02x ", d[i]);
+ fprintf(stderr, "\n");*/
+
+ padding:
+ /*
+ * Set padding areas in destination.
+ */
+ if (dst.offset>0) {
+ assert (H5T_PAD_ZERO==dst.lsb_pad || H5T_PAD_ONE==dst.lsb_pad);
+ H5T_bit_set (d, 0, dst.offset, (hbool_t)(H5T_PAD_ONE==dst.lsb_pad));
+ }
+ if (dst.offset+dst.prec!=8*dst_p->size) {
+ assert (H5T_PAD_ZERO==dst.msb_pad || H5T_PAD_ONE==dst.msb_pad);
+ H5T_bit_set (d, dst.offset+dst.prec,
+ 8*dst_p->size - (dst.offset+ dst.prec),
+ (hbool_t)(H5T_PAD_ONE==dst.msb_pad));
+ }
+
+ /*
+ * Put the destination in the correct byte order. See note at
+ * beginning of loop.
+ */
+ if (H5T_ORDER_BE==dst.order) {
+ half_size = dst_p->size/2;
+ for (i=0; i<half_size; i++) {
+ uint8_t tmp = d[dst_p->size-(i+1)];
+ d[dst_p->size-(i+1)] = d[i];
+ d[i] = tmp;
+ }
+ }
+
+ /*
+ * If we had used a temporary buffer for the destination then we
+ * should copy the value to the true destination buffer.
+ */
+ if (d==dbuf)
+ HDmemcpy (dp, d, dst_p->size);
+ if (buf_stride) {
+ sp += direction * buf_stride;
+ dp += direction * buf_stride;
+ } else {
+ sp += direction * src_p->size;
+ dp += direction * dst_p->size;
+ }
+
+ HDmemset(int_buf, 0, buf_size);
+ }
+
+ HDfree(int_buf);
+
+ break;
+
+ default:
+ HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index a01d995..e068c25 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -379,6 +379,10 @@ H5_DLL herr_t H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
hsize_t nelmts, size_t buf_stride,
size_t bkg_stride, void *_buf, void *bkg,
hid_t dset_xfer_plist);
+H5_DLL herr_t H5T_conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
+ hsize_t nelmts, size_t buf_stride,
+ size_t bkg_stride, void *_buf, void *bkg,
+ hid_t dset_xfer_plist);
H5_DLL herr_t H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
hsize_t nelmts, size_t buf_stride,
size_t bkg_stride, void *_buf, void *bkg,
@@ -1062,6 +1066,7 @@ H5_DLL herr_t H5T_conv_i32le_f64le(hid_t src_id, hid_t dst_id,
/* Bit twiddling functions */
H5_DLL void H5T_bit_copy(uint8_t *dst, size_t dst_offset, const uint8_t *src,
size_t src_offset, size_t size);
+H5_DLL void H5T_bit_shift(uint8_t *buf, hssize_t shift_dist, size_t buf_size);
H5_DLL void H5T_bit_set(uint8_t *buf, size_t offset, size_t size,
hbool_t value);
H5_DLL hsize_t H5T_bit_get_d(uint8_t *buf, size_t offset, size_t size);
@@ -1070,6 +1075,8 @@ H5_DLL void H5T_bit_set_d(uint8_t *buf, size_t offset, size_t size,
H5_DLL ssize_t H5T_bit_find(uint8_t *buf, size_t offset, size_t size,
H5T_sdir_t direction, hbool_t value);
H5_DLL htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size);
+H5_DLL void H5T_bit_dec(uint8_t *buf, size_t start, size_t size);
+H5_DLL void H5T_bit_neg(uint8_t *buf, size_t start, size_t size);
/* VL functions */
H5_DLL H5T_t * H5T_vlen_create(const H5T_t *base);