diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-02-12 13:44:31 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-02-12 13:44:31 (GMT) |
commit | 7d63d5e3ff5d8de37ac28106730255cb4a6739e2 (patch) | |
tree | 7dc73206df8594d0f4f31745d64fb4dfcd00a946 /src/H5Tfields.c | |
parent | 997d4e374258c4d4bddc4754fa75155c4279f126 (diff) | |
download | hdf5-7d63d5e3ff5d8de37ac28106730255cb4a6739e2.zip hdf5-7d63d5e3ff5d8de37ac28106730255cb4a6739e2.tar.gz hdf5-7d63d5e3ff5d8de37ac28106730255cb4a6739e2.tar.bz2 |
[svn-r6395] Purpose:
Code cleanup.
Description:
Break up the ~9350 line H5T.c module into smaller pieces, which contain
code for a particular feature or support for a datatype class.
This should make the "main" H5T code (still in H5T.c) easier to support,
as well as removing some of the "minor" routines from the user applications
which don't use them (my rough estimates show about 4% reduction (~30K on
a FreeBSD machine) in optimized, staticly-linked binaries for very simple
programs)
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
FreeBSD 4.7 (sleipnir)
Misc. update:
Update MANIFEST
Diffstat (limited to 'src/H5Tfields.c')
-rw-r--r-- | src/H5Tfields.c | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/src/H5Tfields.c b/src/H5Tfields.c new file mode 100644 index 0000000..b14d6d3 --- /dev/null +++ b/src/H5Tfields.c @@ -0,0 +1,505 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Module Info: This module contains commond functionality for fields in + * enumerated & compound datatypes in the H5T interface. + */ + +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ + +#include "H5private.h" /*generic functions */ +#include "H5Eprivate.h" /*error handling */ +#include "H5Iprivate.h" /*ID functions */ +#include "H5MMprivate.h" /*memory management */ +#include "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tfields_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_fields_interface +static herr_t H5T_init_fields_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_fields_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_fields_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5T_init_iterface currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5T_init_fields_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_fields_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_fields_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_nmembers + * + * Purpose: Determines how many members TYPE_ID has. The type must be + * either a compound data type or an enumeration data type. + * + * Return: Success: Number of members defined in the data type. + * + * Failure: Negative + * + * Errors: + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with enumeration data types. + *------------------------------------------------------------------------- + */ +int +H5Tget_nmembers(hid_t type_id) +{ + H5T_t *dt = NULL; + int ret_value; + + FUNC_ENTER_API(H5Tget_num_members, FAIL); + H5TRACE1("Is","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + if((ret_value = H5T_get_nmembers(dt))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot return member number"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_nmembers + * + * Purpose: Private function for H5Tget_nmembers. Determines how many + * members DTYPE has. The type must be either a compound data + * type or an enumeration data type. + * + * Return: Success: Number of members defined in the data type. + * + * Failure: Negative + * + * Errors: + * + * Programmer: Raymond Lu + * October 8, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5T_get_nmembers(const H5T_t *dt) +{ + int ret_value; + + FUNC_ENTER_NOAPI(H5T_get_nmembers, FAIL); + + assert(dt); + + if (H5T_COMPOUND==dt->type) + ret_value = dt->u.compnd.nmembs; + else if (H5T_ENUM==dt->type) + ret_value = dt->u.enumer.nmembs; + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "operation not supported for type class"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_name + * + * Purpose: Returns the name of a member of a compound or enumeration + * data type. Members are stored in no particular order with + * numbers 0 through N-1 where N is the value returned by + * H5Tget_nmembers(). + * + * Return: Success: Ptr to a string allocated with malloc(). The + * caller is responsible for freeing the string. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with enumeration data types. + *------------------------------------------------------------------------- + */ +char * +H5Tget_member_name(hid_t type_id, int membno) +{ + H5T_t *dt = NULL; + char *ret_value; + + FUNC_ENTER_API(H5Tget_member_name, NULL); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + + if((ret_value = H5T_get_member_name(dt, membno))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get member name"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_member_name + * + * Purpose: Private function for H5Tget_member_name. Returns the name + * of a member of a compound or enumeration data type. Members + * are stored in no particular order with numbers 0 through + * N-1 where N is the value returned by H5Tget_nmembers(). + * + * Return: Success: Ptr to a string allocated with malloc(). The + * caller is responsible for freeing the string. + * + * Failure: NULL + * + * Programmer: Raymond Lu + * October 9, 2002 + * + * Modifications: + *------------------------------------------------------------------------- + */ +char * +H5T_get_member_name(H5T_t *dt, int membno) +{ + char *ret_value; + + FUNC_ENTER_NOAPI(H5T_get_member_name, NULL); + + assert(dt); + + switch (dt->type) { + case H5T_COMPOUND: + if (membno<0 || membno>=dt->u.compnd.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid member number"); + ret_value = H5MM_xstrdup(dt->u.compnd.memb[membno].name); + break; + + case H5T_ENUM: + if (membno<0 || membno>=dt->u.enumer.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid member number"); + ret_value = H5MM_xstrdup(dt->u.enumer.name[membno]); + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "operation not supported for type class"); + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_index + * + * Purpose: Returns the index of a member in a compound or enumeration + * data type by given name.Members are stored in no particular + * order with numbers 0 through N-1 where N is the value + * returned by H5Tget_nmembers(). + * + * Return: Success: index of the member if exists. + * Failure: -1. + * + * Programmer: Raymond Lu + * Thursday, April 4, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Tget_member_index(hid_t type_id, const char *name) +{ + H5T_t *dt = NULL; + int ret_value=FAIL; + int nmembs, i; + + FUNC_ENTER_API(H5Tget_member_index, FAIL); + H5TRACE2("Is","is",type_id,name); + + /* Check arguments */ + assert(name); + if(NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + /* Locate member by name */ + switch (dt->type) { + case H5T_COMPOUND: + nmembs = dt->u.compnd.nmembs; + for(i=0; i<nmembs; i++) { + if(!HDstrcmp(dt->u.compnd.memb[i].name, name)) + HGOTO_DONE(i); + } + break; + case H5T_ENUM: + nmembs = dt->u.enumer.nmembs; + for(i=0; i<nmembs; i++) { + if(!HDstrcmp(dt->u.enumer.name[i], name)) + HGOTO_DONE(i); + } + break; + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "operation not supported for this type"); + } + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_sort_value + * + * Purpose: Sorts the members of a compound data type by their offsets; + * sorts the members of an enum type by their values. This even + * works for locked data types since it doesn't change the value + * of the type. MAP is an optional parallel integer array which + * is also swapped along with members of DT. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_sort_value(H5T_t *dt, int *map) +{ + int i, j, nmembs; + size_t size; + hbool_t swapped; + uint8_t tbuf[32]; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_sort_value, FAIL); + + /* Check args */ + assert(dt); + assert(H5T_COMPOUND==dt->type || H5T_ENUM==dt->type); + + /* Use a bubble sort because we can short circuit */ + if (H5T_COMPOUND==dt->type) { + if (H5T_SORT_VALUE!=dt->u.compnd.sorted) { + dt->u.compnd.sorted = H5T_SORT_VALUE; + nmembs = dt->u.compnd.nmembs; + for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (dt->u.compnd.memb[j].offset > + dt->u.compnd.memb[j+1].offset) { + H5T_cmemb_t tmp = dt->u.compnd.memb[j]; + dt->u.compnd.memb[j] = dt->u.compnd.memb[j+1]; + dt->u.compnd.memb[j+1] = tmp; + if (map) { + int x = map[j]; + map[j] = map[j+1]; + map[j+1] = x; + } + swapped = TRUE; + } + } + } +#ifndef NDEBUG + /* I never trust a sort :-) -RPM */ + for (i=0; i<nmembs-1; i++) { + assert(dt->u.compnd.memb[i].offset < + dt->u.compnd.memb[i+1].offset); + } +#endif + } + } else if (H5T_ENUM==dt->type) { + if (H5T_SORT_VALUE!=dt->u.enumer.sorted) { + dt->u.enumer.sorted = H5T_SORT_VALUE; + nmembs = dt->u.enumer.nmembs; + size = dt->size; + assert(size<=sizeof(tbuf)); + for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDmemcmp(dt->u.enumer.value+j*size, + dt->u.enumer.value+(j+1)*size, + size)>0) { + /* Swap names */ + char *tmp = dt->u.enumer.name[j]; + dt->u.enumer.name[j] = dt->u.enumer.name[j+1]; + dt->u.enumer.name[j+1] = tmp; + + /* Swap values */ + HDmemcpy(tbuf, dt->u.enumer.value+j*size, size); + HDmemcpy(dt->u.enumer.value+j*size, + dt->u.enumer.value+(j+1)*size, size); + HDmemcpy(dt->u.enumer.value+(j+1)*size, tbuf, size); + + /* Swap map */ + if (map) { + int x = map[j]; + map[j] = map[j+1]; + map[j+1] = x; + } + + swapped = TRUE; + } + } + } +#ifndef NDEBUG + /* I never trust a sort :-) -RPM */ + for (i=0; i<nmembs-1; i++) { + assert(HDmemcmp(dt->u.enumer.value+i*size, + dt->u.enumer.value+(i+1)*size, + size)<0); + } +#endif + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_sort_name + * + * Purpose: Sorts members of a compound or enumeration data type by their + * names. This even works for locked data types since it doesn't + * change the value of the types. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, January 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_sort_name(H5T_t *dt, int *map) +{ + int i, j, nmembs; + size_t size; + hbool_t swapped; + uint8_t tbuf[32]; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_sort_name, FAIL); + + /* Check args */ + assert(dt); + assert(H5T_COMPOUND==dt->type || H5T_ENUM==dt->type); + + /* Use a bubble sort because we can short circuit */ + if (H5T_COMPOUND==dt->type) { + if (H5T_SORT_NAME!=dt->u.compnd.sorted) { + dt->u.compnd.sorted = H5T_SORT_NAME; + nmembs = dt->u.compnd.nmembs; + for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt->u.compnd.memb[j].name, + dt->u.compnd.memb[j+1].name)>0) { + H5T_cmemb_t tmp = dt->u.compnd.memb[j]; + dt->u.compnd.memb[j] = dt->u.compnd.memb[j+1]; + dt->u.compnd.memb[j+1] = tmp; + swapped = TRUE; + if (map) { + int x = map[j]; + map[j] = map[j+1]; + map[j+1] = x; + } + } + } + } +#ifndef NDEBUG + /* I never trust a sort :-) -RPM */ + for (i=0; i<nmembs-1; i++) { + assert(HDstrcmp(dt->u.compnd.memb[i].name, + dt->u.compnd.memb[i+1].name)<0); + } +#endif + } + } else if (H5T_ENUM==dt->type) { + if (H5T_SORT_NAME!=dt->u.enumer.sorted) { + dt->u.enumer.sorted = H5T_SORT_NAME; + nmembs = dt->u.enumer.nmembs; + size = dt->size; + assert(size<=sizeof(tbuf)); + for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt->u.enumer.name[j], + dt->u.enumer.name[j+1])>0) { + /* Swap names */ + char *tmp = dt->u.enumer.name[j]; + dt->u.enumer.name[j] = dt->u.enumer.name[j+1]; + dt->u.enumer.name[j+1] = tmp; + + /* Swap values */ + HDmemcpy(tbuf, dt->u.enumer.value+j*size, size); + HDmemcpy(dt->u.enumer.value+j*size, + dt->u.enumer.value+(j+1)*size, size); + HDmemcpy(dt->u.enumer.value+(j+1)*size, tbuf, size); + + /* Swap map */ + if (map) { + int x = map[j]; + map[j] = map[j+1]; + map[j+1] = x; + } + + swapped = TRUE; + } + } + } +#ifndef NDEBUG + /* I never trust a sort :-) -RPM */ + for (i=0; i<nmembs-1; i++) + assert(HDstrcmp(dt->u.enumer.name[i], dt->u.enumer.name[i+1])<0); +#endif + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + |