diff options
Diffstat (limited to 'src/H5Torder.c')
-rw-r--r-- | src/H5Torder.c | 221 |
1 files changed, 179 insertions, 42 deletions
diff --git a/src/H5Torder.c b/src/H5Torder.c index 6c0667b..590a6c7 100644 --- a/src/H5Torder.c +++ b/src/H5Torder.c @@ -18,24 +18,72 @@ * the datatype byte order for the H5T interface. */ +/****************/ +/* Module Setup */ +/****************/ + #define H5T_PACKAGE /*suppress error about including H5Tpkg */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5T_init_order_interface +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5Tpkg.h" /* Datatypes */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5T_set_order(H5T_t *dtype, H5T_order_t order); + + +/*********************/ +/* Public Variables */ +/*********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + /*-------------------------------------------------------------------------- NAME H5T_init_order_interface -- Initialize interface-specific information USAGE herr_t H5T_init_order_interface() - RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -57,30 +105,31 @@ H5T_init_order_interface(void) * * Purpose: Returns the byte order of a datatype. * - * Return: Success: A byte order constant - * + * Return: Success: A byte order constant. If the type is compound + * and its members have mixed orders, this function + * returns H5T_ORDER_MIXED. * Failure: H5T_ORDER_ERROR (Negative) * * Programmer: Robb Matzke * Wednesday, January 7, 1998 - * + * *------------------------------------------------------------------------- */ H5T_order_t H5Tget_order(hid_t type_id) { - H5T_t *dt; - H5T_order_t ret_value; + H5T_t *dt; /* Datatype to query */ + H5T_order_t ret_value; /* Return value */ FUNC_ENTER_API(H5Tget_order, H5T_ORDER_ERROR) H5TRACE1("To", "i", type_id); /* Check args */ - if(NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR, "not a datatype") + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_ORDER_ERROR, "not a datatype") /* Get order */ - if((ret_value = H5T_get_order(dt)) == H5T_ORDER_ERROR) + if(H5T_ORDER_ERROR == (ret_value = H5T_get_order(dt))) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "cant't get order for specified datatype") done: @@ -102,20 +151,51 @@ done: *------------------------------------------------------------------------- */ H5T_order_t -H5T_get_order(const H5T_t *dt) +H5T_get_order(const H5T_t *dtype) { - H5T_order_t ret_value; /* Return value */ + H5T_order_t ret_value = H5T_ORDER_NONE; /* Return value */ FUNC_ENTER_NOAPI(H5T_get_order, H5T_ORDER_ERROR) - /*defer to parent*/ - while(dt->shared->parent) - dt = dt->shared->parent; - if(!H5T_IS_ATOMIC(dt->shared)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "operation not defined for specified datatype") + /* Defer to parent */ + while(dtype->shared->parent) + dtype = dtype->shared->parent; + + /* Set order for atomic type. */ + if(H5T_IS_ATOMIC(dtype->shared)) + ret_value = dtype->shared->u.atomic.order; + else { + /* Check for compound datatype */ + if(H5T_COMPOUND == dtype->shared->type) { + H5T_order_t memb_order = H5T_ORDER_NONE; + int nmemb; /* Number of members in compound & enum types */ + int i; /* Local index variable */ + + /* Retrieve the number of members */ + if((nmemb = H5T_get_nmembers(dtype)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR, "can't get number of members from compound data type") + + /* Get order for each compound member type. */ + for(i = 0; i < nmemb; i++) { + /* Get order for member */ + if((memb_order = H5T_get_order(dtype->shared->u.compnd.memb[i].type)) == H5T_ORDER_ERROR) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5T_ORDER_ERROR, "can't get order for compound member") - /* Order */ - ret_value = dt->shared->u.atomic.order; + /* Ignore the H5T_ORDER_NONE, write down the first non H5T_ORDER_NONE order. */ + if(memb_order != H5T_ORDER_NONE && ret_value == H5T_ORDER_NONE) + ret_value = memb_order; + + /* If the orders are mixed, stop the loop and report it. + * (H5T_ORDER_NONE is ignored) + */ + if(memb_order != H5T_ORDER_NONE && ret_value != H5T_ORDER_NONE + && memb_order != ret_value) { + ret_value = H5T_ORDER_MIXED; + break; + } /* end if */ + } /* end for */ + } /* end if */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -127,46 +207,103 @@ done: * * Purpose: Sets the byte order for a datatype. * + * Notes: There are some restrictions on this operation: + * 1. For enum type, members shouldn't be defined yet. + * 2. H5T_ORDER_NONE only works for reference and fixed-length + * string. + * 3. For opaque type, the order will be ignored. + * 4. For compound type, all restrictions above apply to the + * members. + * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Wednesday, January 7, 1998 * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived datatypes. - * *------------------------------------------------------------------------- */ herr_t H5Tset_order(hid_t type_id, H5T_order_t order) { - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + H5T_t *dt; /* Datatype to modify */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Tset_order, FAIL) H5TRACE2("e", "iTo", type_id, order); /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - if (H5T_STATE_TRANSIENT!=dt->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only") - if (order < H5T_ORDER_LE || order > H5T_ORDER_NONE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") - if (H5T_ENUM==dt->shared->type && dt->shared->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined") - while (dt->shared->parent) - dt = dt->shared->parent; /*defer to parent*/ - if (order == H5T_ORDER_NONE && !(H5T_REFERENCE == dt->shared->type || H5T_IS_FIXED_STRING(dt->shared))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") - if (!H5T_IS_ATOMIC(dt->shared)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "operation not defined for specified datatype") - - /* Commit */ - dt->shared->u.atomic.order = order; + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(order < H5T_ORDER_LE || order > H5T_ORDER_NONE || order == H5T_ORDER_MIXED) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "illegal byte order") + if(H5T_STATE_TRANSIENT != dt->shared->state) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype is read-only") + + /* Call internal routine to set the order */ + if(H5T_set_order(dt, order) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't set order") done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Tset_order() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_set_order + * + * Purpose: Private function to set the byte order for a datatype. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 13 August 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_set_order(H5T_t *dtype, H5T_order_t order) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_set_order, FAIL) + + if(H5T_ENUM == dtype->shared->type && dtype->shared->u.enumer.nmembs > 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "operation not allowed after enum members are defined") + + /* For derived data type, defer to parent */ + while(dtype->shared->parent) + dtype = dtype->shared->parent; + + /* Check for setting order on inappropriate datatype */ + if(order == H5T_ORDER_NONE && !(H5T_REFERENCE == dtype->shared->type || + H5T_OPAQUE == dtype->shared->type || H5T_IS_FIXED_STRING(dtype->shared))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "illegal byte order for type") + + /* For atomic data type */ + if(H5T_IS_ATOMIC(dtype->shared)) + dtype->shared->u.atomic.order = order; + else { + /* Check for compound datatype */ + if(H5T_COMPOUND == dtype->shared->type) { + int nmemb; /* Number of members in type */ + int i; /* Local index variable */ + + /* Retrieve the number of fields in the compound datatype */ + if((nmemb = H5T_get_nmembers(dtype)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get number of members from compound data type") + + /* Check for uninitialized compound datatype */ + if(nmemb == 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNINITIALIZED, FAIL, "no member is in the compound data type") + + /* Loop through all fields of compound type, setting the order */ + for(i = 0; i < nmemb; i++) + if(H5T_set_order(dtype->shared->u.compnd.memb[i].type, order) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set order for compound member") + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_set_order() */ |