summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5D.c4
-rw-r--r--src/H5Fprivate.h5
-rw-r--r--src/H5Odtype.c106
-rw-r--r--src/H5T.c174
-rw-r--r--src/H5Tconv.c207
-rw-r--r--src/H5Tpkg.h14
-rw-r--r--src/H5Tpublic.h4
7 files changed, 463 insertions, 51 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 8621018..98bfca9 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1455,7 +1455,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5T_bkg_t need_bkg; /*type of background buf*/
H5S_t *free_this_space=NULL; /*data space to free */
hbool_t must_convert; /*have to xfer the slow way*/
-#if defined(H5S_DEBUG) || defined(H5T_DEBUG)
+#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
@@ -1827,7 +1827,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
H5T_bkg_t need_bkg; /*type of background buf*/
H5S_t *free_this_space=NULL; /*data space to free */
hbool_t must_convert; /*have to xfer the slow way*/
-#if defined(H5S_DEBUG) || defined(H5T_DEBUG)
+#ifdef H5S_DEBUG
H5_timer_t timer;
#endif
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 21fb762..2110bd3 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -378,13 +378,10 @@ typedef struct H5F_low_class_t {
* whether that storage is file, local memory, shared memory, network
* distributed global memory, etc.
*/
-#if defined WIN32
-typedef UINT uint;
-#endif
typedef struct H5F_low_t {
const H5F_low_class_t *type;/* What type of file is this? */
haddr_t eof; /* Address of logical end-of-file */
- uint eof_written; /* whether the last byte is written */
+ uintn eof_written; /* whether the last byte is written */
union {
/* File families */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index a0da1ac..5d3ac32 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -72,14 +72,16 @@ static intn interface_initialize_g = 0;
* Monday, December 8, 1997
*
* Modifications:
- *
+ * Robb Matzke, Thursday, May 20, 1999
+ * Added support for bitfields and opaque data types.
*-------------------------------------------------------------------------
*/
static herr_t
H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
{
- uintn flags, perm_word, version;
- intn i, j;
+ uintn flags, perm_word, version;
+ intn i, j;
+ size_t z;
FUNC_ENTER(H5O_dtype_decode_helper, FAIL);
@@ -111,6 +113,32 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
UINT16DECODE(*pp, dt->u.atomic.prec);
break;
+ case H5T_BITFIELD:
+ /*
+ * Bit fields...
+ */
+ dt->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
+ dt->u.atomic.lsb_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO;
+ dt->u.atomic.msb_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO;
+ UINT16DECODE(*pp, dt->u.atomic.offset);
+ UINT16DECODE(*pp, dt->u.atomic.prec);
+ break;
+
+ case H5T_OPAQUE:
+ /*
+ * Opaque types...
+ */
+ z = flags & 0xff;
+ assert(0==(z&0x7)); /*must be aligned*/
+ if (NULL==(dt->u.opaque.tag=H5MM_malloc(z+1))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ }
+ HDmemcpy(dt->u.opaque.tag, *pp, z);
+ dt->u.opaque.tag[z] = '\0';
+ *pp += z;
+ break;
+
case H5T_STRING:
/*
* Character string types...
@@ -283,7 +311,8 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
* Monday, December 8, 1997
*
* Modifications:
- *
+ * Robb Matzke, Thursday, May 20, 1999
+ * Added support for bitfields and opaque types.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -293,7 +322,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
uintn perm_word;
char *hdr = (char *)*pp;
intn i, j;
- size_t n, z;
+ size_t n, z, aligned;
FUNC_ENTER(H5O_dtype_encode_helper, FAIL);
@@ -358,6 +387,61 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
UINT16ENCODE(*pp, dt->u.atomic.prec);
break;
+ case H5T_BITFIELD:
+ /*
+ * Bitfield data types...
+ */
+ switch (dt->u.atomic.order) {
+ case H5T_ORDER_LE:
+ break; /*nothing */
+ case H5T_ORDER_BE:
+ flags |= 0x01;
+ break;
+ default:
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "byte order is not supported in file format yet");
+ }
+
+ switch (dt->u.atomic.lsb_pad) {
+ case H5T_PAD_ZERO:
+ break; /*nothing */
+ case H5T_PAD_ONE:
+ flags |= 0x02;
+ break;
+ default:
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "bit padding is not supported in file format yet");
+ }
+
+ switch (dt->u.atomic.msb_pad) {
+ case H5T_PAD_ZERO:
+ break; /*nothing */
+ case H5T_PAD_ONE:
+ flags |= 0x04;
+ break;
+ default:
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "bit padding is not supported in file format yet");
+ }
+
+ UINT16ENCODE(*pp, dt->u.atomic.offset);
+ UINT16ENCODE(*pp, dt->u.atomic.prec);
+ break;
+
+ case H5T_OPAQUE:
+ /*
+ * Opaque data types... The tag is stored in a field which is a
+ * multiple of eight characters and null padded (not necessarily
+ * null terminated).
+ */
+ z = HDstrlen(dt->u.opaque.tag);
+ aligned = (z+7) & 0xf8;
+ flags |= aligned;
+ HDmemcpy(*pp, dt->u.opaque.tag, MIN(z,aligned));
+ for (n=MIN(z,aligned); n<aligned; n++) (*pp)[n] = 0;
+ *pp += aligned;
+ break;
+
case H5T_STRING:
/*
* Character string types... (not fully implemented)
@@ -694,6 +778,14 @@ H5O_dtype_size(H5F_t *f, const void *mesg)
ret_value += 4;
break;
+ case H5T_BITFIELD:
+ ret_value += 4;
+ break;
+
+ case H5T_OPAQUE:
+ ret_value += (HDstrlen(dt->u.opaque.tag)+7) & 0xf8;
+ break;
+
case H5T_FLOAT:
ret_value += 12;
break;
@@ -964,6 +1056,10 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE *stream,
fprintf(stream, "\n");
}
+ } else if (H5T_OPAQUE==dt->type) {
+ fprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
+ "Tag:", dt->u.opaque.tag);
+
} else {
switch (dt->u.atomic.order) {
case H5T_ORDER_LE:
diff --git a/src/H5T.c b/src/H5T.c
index 2ccdcb1..bba0874 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -176,6 +176,7 @@ H5T_init_interface(void)
{
H5T_t *dt = NULL;
hid_t fixedpt=-1, floatpt=-1, string=-1, compound=-1, enum_type=-1;
+ hid_t bitfield=-1;
herr_t status;
herr_t ret_value=FAIL;
@@ -239,11 +240,7 @@ H5T_init_interface(void)
H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_OPAQUE;
dt->size = 1;
- dt->u.atomic.order = H5T_ORDER_NONE;
- dt->u.atomic.offset = 0;
- dt->u.atomic.prec = 8 * dt->size;
- dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
- dt->u.atomic.msb_pad = H5T_PAD_ZERO;
+ dt->u.opaque.tag = H5MM_strdup("");
if ((H5T_NATIVE_OPAQUE_g = H5I_register(H5I_DATATYPE, dt)) < 0) {
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize H5T layer");
@@ -702,6 +699,7 @@ H5T_init_interface(void)
fixedpt = H5T_NATIVE_INT;
floatpt = H5T_NATIVE_FLOAT;
string = H5T_C_S1;
+ bitfield = H5T_STD_B8LE;
compound = H5Tcreate(H5T_COMPOUND, 1);
enum_type = H5Tcreate(H5T_ENUM, 1);
status = 0;
@@ -718,6 +716,9 @@ H5T_init_interface(void)
status |= H5Tregister(H5T_PERS_SOFT, "s_s",
string, string,
H5T_conv_s_s);
+ status |= H5Tregister(H5T_PERS_SOFT, "b_b",
+ bitfield, bitfield,
+ H5T_conv_b_b);
status |= H5Tregister(H5T_PERS_SOFT, "ibo",
fixedpt, fixedpt,
H5T_conv_order);
@@ -1718,9 +1719,9 @@ H5Tget_order(hid_t type_id)
"not a data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Order */
@@ -1771,9 +1772,9 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
"operation not allowed after members are defined");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Commit */
@@ -1820,9 +1821,9 @@ H5Tget_precision(hid_t type_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Precision */
@@ -1946,9 +1947,9 @@ H5Tget_offset(hid_t type_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Offset */
@@ -2065,9 +2066,9 @@ H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Get values */
@@ -2119,9 +2120,9 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
"operation not allowed after members are defined");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
}
/* Commit */
@@ -3603,7 +3604,94 @@ H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/)
}
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tset_tag
+ *
+ * Purpose: Tag an opaque datatype with a unique ASCII identifier.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, May 20, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_tag(hid_t type_id, const char *tag)
+{
+ H5T_t *dt=NULL;
+
+ FUNC_ENTER(H5Tset_tag, FAIL);
+ H5TRACE2("e","is",type_id,tag);
+
+ /* Check args */
+ if (H5I_DATATYPE != H5I_get_type(type_id) ||
+ NULL == (dt = H5I_object(type_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ if (H5T_STATE_TRANSIENT!=dt->state) {
+ HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+ }
+ if (H5T_OPAQUE!=dt->type) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an opaque data type");
+ }
+ if (!tag) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no tag");
+ }
+
+ /* Commit */
+ H5MM_xfree(dt->u.opaque.tag);
+ dt->u.opaque.tag = H5MM_strdup(tag);
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tget_tag
+ *
+ * Purpose: Get tha tag associated with an opaque datatype.
+ *
+ * Return: A pointer to an allocated string. The caller should free
+ * the string. NULL is returned for errors.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, May 20, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5Tget_tag(hid_t type_id)
+{
+ H5T_t *dt=NULL;
+ char *ret_value=NULL;
+
+ FUNC_ENTER(H5Tget_tag, NULL);
+
+ /* Check args */
+ if (H5I_DATATYPE != H5I_get_type(type_id) ||
+ NULL == (dt = H5I_object(type_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
+ }
+ if (dt->parent) dt = dt->parent; /*defer to parent*/
+ if (H5T_OPAQUE != dt->type) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "operation not defined for data type class");
+ }
+ /* result */
+ if (NULL==(ret_value=H5MM_strdup(dt->u.opaque.tag))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ FUNC_LEAVE(ret_value);
+}
+
/*-------------------------------------------------------------------------
* Function: H5Tregister
@@ -4104,10 +4192,10 @@ H5T_create(H5T_class_t type, size_t size)
case H5T_TIME:
case H5T_STRING:
case H5T_BITFIELD:
- case H5T_OPAQUE:
HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL,
"type class is not appropriate - use H5Tcopy()");
+ case H5T_OPAQUE:
case H5T_COMPOUND:
if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
@@ -4304,6 +4392,9 @@ H5T_open_oid (H5G_entry_t *ent)
* Robb Matzke, 22 Dec 1998
* Now able to copy enumeration data types.
*
+ * Robb Matzke, 20 May 1999
+ * Now able to copy opaque types.
+ *
*-------------------------------------------------------------------------
*/
H5T_t *
@@ -4410,6 +4501,12 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
s = old_dt->u.enumer.name[i];
new_dt->u.enumer.name[i] = H5MM_xstrdup(s);
}
+
+ } else if (H5T_OPAQUE == new_dt->type) {
+ /*
+ * Copy the tag name.
+ */
+ new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag);
}
FUNC_LEAVE(new_dt);
@@ -4550,6 +4647,8 @@ H5T_lock (H5T_t *dt, hbool_t immutable)
* Robb Matzke, 1999-04-27
* This function fails if the datatype state is IMMUTABLE.
*
+ * Robb Matzke, 1999-05-20
+ * Closes opaque types also.
*-------------------------------------------------------------------------
*/
herr_t
@@ -4601,6 +4700,11 @@ H5T_close(H5T_t *dt)
H5MM_xfree(dt);
break;
+ case H5T_OPAQUE:
+ H5MM_xfree(dt->u.opaque.tag);
+ H5MM_xfree(dt);
+ break;
+
default:
H5MM_xfree(dt);
}
@@ -4639,7 +4743,7 @@ H5T_is_atomic(const H5T_t *dt)
FUNC_ENTER(H5T_is_atomic, FAIL);
assert(dt);
- if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type) {
+ if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_OPAQUE!=dt->type) {
ret_value = TRUE;
} else {
ret_value = FALSE;
@@ -4718,6 +4822,7 @@ H5T_set_size(H5T_t *dt, size_t size)
case H5T_TIME:
case H5T_BITFIELD:
case H5T_ENUM:
+ case H5T_OPAQUE:
/* nothing to check */
break;
@@ -4740,17 +4845,6 @@ H5T_set_size(H5T_t *dt, size_t size)
}
break;
- case H5T_OPAQUE:
- /*
- * The significant bits of an opaque type are not allowed to
- * change implicitly.
- */
- if (prec != dt->u.atomic.prec) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
- "unable to change precision of an opaque type");
- }
- break;
-
default:
assert("not implemented yet" && 0);
}
@@ -4845,9 +4939,9 @@ H5T_set_precision(H5T_t *dt, size_t prec)
}
dt->size = dt->parent->size;
} else {
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
} else if (H5T_ENUM==dt->type) {
/*nothing*/
@@ -4865,7 +4959,6 @@ H5T_set_precision(H5T_t *dt, size_t prec)
case H5T_INTEGER:
case H5T_TIME:
case H5T_BITFIELD:
- case H5T_OPAQUE:
/* nothing to check */
break;
@@ -4961,9 +5054,9 @@ H5T_set_offset(H5T_t *dt, size_t offset)
}
dt->size = dt->parent->size;
} else {
- if (H5T_COMPOUND==dt->type) {
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "operation not defined for compound data types");
+ "operation not defined for specified data type");
} else if (H5T_ENUM==dt->type) {
/*nothing*/
} else {
@@ -5574,6 +5667,8 @@ H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/)
* Robb Matzke, 22 Dec 1998
* Able to compare enumeration data types.
*
+ * Robb Matzke, 20 May 1999
+ * Compares bitfields and opaque types.
*-------------------------------------------------------------------------
*/
intn
@@ -5758,6 +5853,9 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
if (tmp>0) HGOTO_DONE(1);
}
+ } else if (H5T_OPAQUE==dt1->type) {
+ HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag));
+
} else {
/*
* Atomic data types...
@@ -6425,8 +6523,7 @@ H5T_debug(H5T_t *dt, FILE *stream)
s1 = "sign?";
break;
}
- if (s1)
- fprintf(stream, ", %s", s1);
+ if (s1) fprintf(stream, ", %s", s1);
break;
case H5T_FLOAT:
@@ -6501,6 +6598,9 @@ H5T_debug(H5T_t *dt, FILE *stream)
}
}
fprintf(stream, "\n");
+
+ } else if (H5T_OPAQUE==dt->type) {
+ fprintf(stream, ", tag=\"%s\"", dt->u.opaque.tag);
} else {
/* Unknown */
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 7aad1e1..fe4e6c3 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -496,6 +496,213 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
/*-------------------------------------------------------------------------
+ * Function: H5T_conv_b_b
+ *
+ * Purpose: Convert from one bitfield to any other bitfield.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, May 20, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ void *_buf, void UNUSED *background)
+{
+ uint8_t *buf = (uint8_t*)_buf;
+ H5T_t *src=NULL, *dst=NULL; /*source and dest data types */
+ intn direction; /*direction of traversal */
+ size_t elmtno; /*element number */
+ size_t olap; /*num overlapping elements */
+ size_t half_size; /*1/2 of total size for swapping*/
+ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/
+ uint8_t dbuf[256]; /*temp destination buffer */
+ size_t msb_pad_offset; /*offset for dest MSB padding */
+ size_t i;
+
+ FUNC_ENTER(H5T_conv_b_b, FAIL);
+
+ switch(cdata->command) {
+ case H5T_CONV_INIT:
+ /* Capability query */
+ if (H5I_DATATYPE != H5I_get_type(src_id) ||
+ NULL == (src = H5I_object(src_id)) ||
+ H5I_DATATYPE != H5I_get_type(dst_id) ||
+ NULL == (dst = H5I_object(dst_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ if (H5T_ORDER_LE!=src->u.atomic.order &&
+ H5T_ORDER_BE!=src->u.atomic.order) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unsupported byte order");
+ }
+ if (H5T_ORDER_LE!=dst->u.atomic.order &&
+ H5T_ORDER_BE!=dst->u.atomic.order) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unsupported byte order");
+ }
+ cdata->need_bkg = H5T_BKG_NO;
+ break;
+
+ case H5T_CONV_FREE:
+ break;
+
+ case H5T_CONV_CONV:
+ /* Get the data types */
+ if (H5I_DATATYPE!=H5I_get_type (src_id) ||
+ NULL==(src=H5I_object (src_id)) ||
+ H5I_DATATYPE!=H5I_get_type (dst_id) ||
+ NULL==(dst=H5I_object (dst_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ /*
+ * 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->size==dst->size) {
+ sp = dp = (uint8_t*)buf;
+ direction = 1;
+ olap = nelmts;
+ } else if (src->size>=dst->size) {
+ double olap_d = HDceil((double)(dst->size)/
+ (double)(src->size-dst->size));
+
+ olap = (size_t)olap_d;
+ sp = dp = (uint8_t*)buf;
+ direction = 1;
+ } else {
+ double olap_d = HDceil((double)(src->size)/
+ (double)(dst->size-src->size));
+ olap = (size_t)olap_d;
+ sp = (uint8_t*)buf + (nelmts-1) * src->size;
+ dp = (uint8_t*)buf + (nelmts-1) * dst->size;
+ direction = -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->size) ||
+ (sp>=dp && sp<dp+dst->size));
+ } else {
+ assert ((dp<sp && dp+dst->size<=sp) ||
+ (sp<dp && sp+src->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->u.atomic.order) {
+ half_size = src->size/2;
+ for (i=0; i<half_size; i++) {
+ uint8_t tmp = s[src->size-(i+1)];
+ s[src->size-(i+1)] = s[i];
+ s[i] = tmp;
+ }
+ }
+
+ /*
+ * Copy the significant part of the value. If the source is larger
+ * than the destination then invoke the overflow function or copy
+ * as many bits as possible.
+ */
+ if (src->u.atomic.prec>dst->u.atomic.prec) {
+ if (!H5T_overflow_g ||
+ (H5T_overflow_g)(src_id, dst_id, s, d)<0) {
+ H5T_bit_copy(d, dst->u.atomic.offset,
+ s, src->u.atomic.offset, dst->u.atomic.prec);
+ }
+ } else {
+ H5T_bit_copy(d, dst->u.atomic.offset,
+ s, src->u.atomic.offset,
+ src->u.atomic.prec);
+ }
+
+ /*
+ * Fill the destination padding areas.
+ */
+ switch (dst->u.atomic.lsb_pad) {
+ case H5T_PAD_ZERO:
+ H5T_bit_set(d, 0, dst->u.atomic.offset, FALSE);
+ break;
+ case H5T_PAD_ONE:
+ H5T_bit_set(d, 0, dst->u.atomic.offset, TRUE);
+ break;
+ default:
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unsupported LSB padding");
+ }
+ msb_pad_offset = dst->u.atomic.offset + dst->u.atomic.prec;
+ switch (dst->u.atomic.msb_pad) {
+ case H5T_PAD_ZERO:
+ H5T_bit_set(d, msb_pad_offset, 8*dst->size-msb_pad_offset,
+ FALSE);
+ break;
+ case H5T_PAD_ONE:
+ H5T_bit_set(d, msb_pad_offset, 8*dst->size-msb_pad_offset,
+ TRUE);
+ break;
+ default:
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unsupported MSB padding");
+ }
+
+ /*
+ * Put the destination in the correct byte order. See note at
+ * beginning of loop.
+ */
+ if (H5T_ORDER_BE==dst->u.atomic.order) {
+ half_size = dst->size/2;
+ for (i=0; i<half_size; i++) {
+ uint8_t tmp = d[dst->size-(i+1)];
+ d[dst->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->size);
+ sp += direction * src->size;
+ dp += direction * dst->size;
+ }
+
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unknown conversion command");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
* Function: H5T_conv_struct_init
*
* Purpose: Initialize the `priv' field of `cdata' with conversion
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index f0906d7..ac37243 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -53,11 +53,11 @@ typedef struct H5T_atomic_t {
struct {
H5T_cset_t cset; /*character set */
H5T_str_t pad; /*space or null padding of extra bytes */
- } s;
+ } s; /*string types */
struct {
- H5R_type_t rtype; /* Type of reference stored */
- } r;
+ H5R_type_t rtype; /*type of reference stored */
+ } r; /*reference types */
} u;
} H5T_atomic_t;
@@ -85,6 +85,11 @@ typedef struct H5T_enum_t {
char **name; /*array of symbol names */
} H5T_enum_t;
+/* An opaque data type */
+typedef struct H5T_opaque_t {
+ char *tag; /*short type description string */
+} H5T_opaque_t;
+
typedef enum H5T_state_t {
H5T_STATE_TRANSIENT, /*type is a modifiable transient */
H5T_STATE_RDONLY, /*transient, not modifiable, closable*/
@@ -104,6 +109,7 @@ struct H5T_t {
H5T_atomic_t atomic; /*an atomic data type */
H5T_compnd_t compnd; /*a compound data type (struct) */
H5T_enum_t enumer; /*an enumeration type (enum) */
+ H5T_opaque_t opaque; /*an opaque data type */
} u;
};
@@ -171,6 +177,8 @@ __DLL__ herr_t H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);
__DLL__ herr_t H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);
+__DLL__ herr_t H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
+ size_t nelmts, void *_buf, void *bkg);
__DLL__ herr_t H5T_conv_schar_uchar(hid_t src_id, hid_t dst_id,
H5T_cdata_t *cdata, size_t nelmts,
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index e3b6248..4b76131 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -401,6 +401,10 @@ __DLL__ hid_t H5Tenum_nameof(hid_t type, void *value, char *name/*out*/,
__DLL__ hid_t H5Tenum_valueof(hid_t type, const char *name,
void *value/*out*/);
+/* Operations defined on opaque data types */
+__DLL__ herr_t H5Tset_tag(hid_t type, const char *tag);
+__DLL__ char *H5Tget_tag(hid_t type);
+
/* Querying property values */
__DLL__ hid_t H5Tget_super(hid_t type);
__DLL__ H5T_class_t H5Tget_class(hid_t type_id);