diff options
-rw-r--r-- | MANIFEST | 15 | ||||
-rw-r--r-- | src/H5T.c | 4108 | ||||
-rw-r--r-- | src/H5Tarray.c | 343 | ||||
-rw-r--r-- | src/H5Tbit.c | 34 | ||||
-rw-r--r-- | src/H5Tcommit.c | 206 | ||||
-rw-r--r-- | src/H5Tcompound.c | 512 | ||||
-rw-r--r-- | src/H5Tconv.c | 37 | ||||
-rw-r--r-- | src/H5Tcset.c | 159 | ||||
-rw-r--r-- | src/H5Tenum.c | 582 | ||||
-rw-r--r-- | src/H5Tfields.c | 505 | ||||
-rw-r--r-- | src/H5Tfixed.c | 182 | ||||
-rw-r--r-- | src/H5Tfloat.c | 447 | ||||
-rw-r--r-- | src/H5Tnative.c | 761 | ||||
-rw-r--r-- | src/H5Toffset.c | 258 | ||||
-rw-r--r-- | src/H5Topaque.c | 139 | ||||
-rw-r--r-- | src/H5Torder.c | 148 | ||||
-rw-r--r-- | src/H5Tpad.c | 151 | ||||
-rw-r--r-- | src/H5Tpkg.h | 23 | ||||
-rw-r--r-- | src/H5Tprecis.c | 266 | ||||
-rw-r--r-- | src/H5Tprivate.h | 40 | ||||
-rw-r--r-- | src/H5Tstrpad.c | 171 | ||||
-rw-r--r-- | src/H5Tvlen.c | 146 | ||||
-rw-r--r-- | src/Makefile.in | 7 |
23 files changed, 5087 insertions, 4153 deletions
@@ -909,11 +909,26 @@ ./src/H5ST.c ./src/H5STprivate.h ./src/H5T.c +./src/H5Tarray.c ./src/H5Tbit.c +./src/H5Tcommit.c +./src/H5Tcompound.c ./src/H5Tconv.c +./src/H5Tcset.c +./src/H5Tenum.c +./src/H5Tfields.c +./src/H5Tfixed.c +./src/H5Tfloat.c +./src/H5Tnative.c +./src/H5Toffset.c +./src/H5Topaque.c +./src/H5Torder.c +./src/H5Tpad.c ./src/H5Tpkg.h +./src/H5Tprecis.c ./src/H5Tprivate.h ./src/H5Tpublic.h +./src/H5Tstrpad.c ./src/H5Tvlen.c ./src/H5TB.c ./src/H5TBprivate.h @@ -1,33 +1,41 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* - * Copyright (C) 1998-2001 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Tuesday, March 31, 1998 + * Module Info: This module contains most of the "core" functionality of + * the H5T interface, including the API initialization code, etc. + * Many routines that are infrequently used, or are specialized for + * one particular datatype class are in another module. */ #define H5T_PACKAGE /*suppress error about including H5Tpkg */ #include "H5private.h" /*generic functions */ #include "H5Dprivate.h" /*datasets (for H5Tcopy) */ -#include "H5Iprivate.h" /*ID functions */ #include "H5Eprivate.h" /*error handling */ #include "H5FLprivate.h" /*Free Lists */ #include "H5Gprivate.h" /*groups */ -#include "H5HGprivate.h" /*global heap */ +#include "H5Iprivate.h" /*ID functions */ #include "H5MMprivate.h" /*memory management */ #include "H5Pprivate.h" /* Property Lists */ -#include "H5Sprivate.h" /*data space */ #include "H5Tpkg.h" /*data-type functions */ #define PABLO_MASK H5T_mask -#define H5T_COMPND_INC 64 /*typical max numb of members per struct */ - /* Interface initialization */ static int interface_initialize_g = 0; #define INTERFACE_INIT H5T_init_interface -static herr_t H5T_init_interface(void); /* * Predefined data types. These are initialized at runtime in H5Tinit.c and @@ -222,9 +230,6 @@ static struct { /* The overflow handler */ H5T_overflow_t H5T_overflow_g = NULL; -/* Local static functions */ -static herr_t H5T_print_stats(H5T_path_t *path, int *nprint/*in,out*/); - /* Declare the free list for H5T_t's */ H5FL_DEFINE(H5T_t); @@ -232,9 +237,12 @@ H5FL_DEFINE(H5T_t); H5FL_DEFINE(H5T_path_t); /* Static local functions */ +static H5T_t *H5T_open(H5G_entry_t *loc, const char *name, hid_t dxpl_id); +static herr_t H5T_print_stats(H5T_path_t *path, int *nprint/*in,out*/); +static herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, + H5T_t *dst, H5T_conv_t func, hid_t dxpl_id); static herr_t H5T_register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_conv_t func, hid_t dxpl_id); -static H5T_t * H5T_vlen_create(H5T_t *base); /*------------------------------------------------------------------------- @@ -278,7 +286,7 @@ DESCRIPTION Initializes any interface-specific data or routines. --------------------------------------------------------------------------*/ -static herr_t +herr_t H5T_init_interface(void) { H5T_t *native_schar=NULL; /* Datatype structure for native signed char */ @@ -2126,85 +2134,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Tcommit - * - * Purpose: Save a transient data type to a file and turn the type handle - * into a named, immutable type. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, June 1, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tcommit(hid_t loc_id, const char *name, hid_t type_id) -{ - H5G_entry_t *loc = NULL; - H5T_t *type = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tcommit, FAIL); - H5TRACE3("e","isi",loc_id,name,type_id); - - /* Check arguments */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); - if (NULL==(type=H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - - /* Commit the type */ - if (H5T_commit (loc, name, type, H5AC_dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit data type"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tcommitted - * - * Purpose: Determines if a data type is committed or not. - * - * Return: Success: TRUE if committed, FALSE otherwise. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Thursday, June 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5Tcommitted(hid_t type_id) -{ - H5T_t *type = NULL; - htri_t ret_value; /* Return value */ - - FUNC_ENTER_API(H5Tcommitted, FAIL); - H5TRACE1("b","i",type_id); - - /* Check arguments */ - if (NULL==(type=H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - - /* Set return value */ - ret_value= (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5Tcopy * * Purpose: Copies a data type. The resulting data type is not locked. @@ -2642,696 +2571,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Tget_native_type - * - * Purpose: High-level API to return the native type of a datatype. - * The native type is chosen by matching the size and class of - * querried datatype from the following native premitive - * datatypes: - * H5T_NATIVE_CHAR H5T_NATIVE_UCHAR - * H5T_NATIVE_SHORT H5T_NATIVE_USHORT - * H5T_NATIVE_INT H5T_NATIVE_UINT - * H5T_NATIVE_LONG H5T_NATIVE_ULONG - * H5T_NATIVE_LLONG H5T_NATIVE_ULLONG - * - * H5T_NATIVE_FLOAT - * H5T_NATIVE_DOUBLE - * H5T_NATIVE_LDOUBLE - * - * Compound, array, enum, and VL types all choose among these - * types for theire members. Time, Bifield, Opaque, Reference - * types are only copy out. - * - * Return: Success: Returns the native data type if successful. - * - * Failure: negative - * - * Programmer: Raymond Lu - * Oct 3, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction) -{ - H5T_t *dt; /* Datatype to create native datatype from */ - H5T_t *new_dt=NULL; /* Datatype for native datatype created */ - size_t comp_size=0; /* Compound datatype's size */ - hid_t ret_value; /* Return value */ - - FUNC_ENTER_API(H5Tget_native_type, FAIL); - H5TRACE1("z","i",type_id); - - /* check argument */ - if(NULL==(dt=H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - - if(direction!=H5T_DIR_DEFAULT && direction!=H5T_DIR_ASCEND - && direction!=H5T_DIR_DESCEND) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not valid direction value"); - - if((new_dt = H5T_get_native_type(dt, direction, NULL, NULL, &comp_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type"); - - if((ret_value=H5I_register(H5I_DATATYPE, new_dt)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type"); - -done: - /* Error cleanup */ - if(ret_value<0) { - if(new_dt) - H5T_close(new_dt); - } /* end if */ - - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_native_type - * - * Purpose: Returns the native type of a datatype. - * - * Return: Success: Returns the native data type if successful. - * - * Failure: negative - * - * Programmer: Raymond Lu - * Oct 3, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t* H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) -{ - H5T_t *dt; /* Datatype to make native */ - H5T_class_t h5_class; /* Class of datatype to make native */ - size_t size; /* Size of datatype to make native */ - int nmemb; /* Number of members in compound & enum types */ - H5T_t *super_type; /* Super type of VL, array and enum datatypes */ - H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ - H5T_t *new_type=NULL; /* New native datatype */ - int i; /* Local index variable */ - H5T_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_get_native_type, NULL); - - assert(dtype); - - if((h5_class = H5T_get_class(dtype))<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class"); - - if((size = H5T_get_size(dtype))==0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size"); - - switch(h5_class) { - case H5T_INTEGER: - { - H5T_sign_t sign; /* Signedness of integer type */ - - if((sign = H5T_get_sign(dtype))==H5T_SGN_ERROR) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid signess"); - - if((ret_value = H5T_get_native_integer(size, sign, direction, struct_align, offset, comp_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer type"); - } - break; - - case H5T_FLOAT: - if((ret_value = H5T_get_native_float(size, direction, struct_align, offset, comp_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - - break; - - case H5T_STRING: - { - size_t align; - size_t pointer_size; - - if(H5T_is_variable_str(dtype)) { - if(NULL==(dt=H5I_object(H5T_C_S1))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); - if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - if(H5T_set_size(ret_value, H5T_VARIABLE)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot set size"); - - /* Update size, offset and compound alignment for parent. */ - align = H5T_POINTER_COMP_ALIGN_g; - pointer_size = sizeof(char*); - - if(H5T_cmp_offset(comp_size, offset, pointer_size, 1, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - - } else { - /*size_t char_size;*/ - - if(NULL==(dt=H5I_object(H5T_NATIVE_UCHAR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); - if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - if(H5T_set_size(ret_value, size)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot set size"); - - /* Update size, offset and compound alignment for parent. */ - align = H5T_NATIVE_SCHAR_COMP_ALIGN_g; - - if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - - } - } - break; - - /* These three types don't need to compute compound field information since they - * can't be used as field. */ - case H5T_TIME: - case H5T_BITFIELD: - case H5T_OPAQUE: - if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - - break; - case H5T_REFERENCE: - { - size_t align; - size_t ref_size; - int not_equal; - - if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - - /* Decide if the data type is object or dataset region reference. */ - if(NULL==(dt=H5I_object(H5T_STD_REF_OBJ_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); - not_equal = H5T_cmp(ret_value, dt); - - /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { - align = H5T_HOBJREF_COMP_ALIGN_g; - ref_size = sizeof(hobj_ref_t); - } else { - align = H5T_HDSETREGREF_COMP_ALIGN_g; - ref_size = sizeof(hdset_reg_ref_t); - } - - if(H5T_cmp_offset(comp_size, offset, ref_size, 1, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - } - break; - - case H5T_COMPOUND: - { - H5T_t *memb_type; /* Datatype of member */ - H5T_t **memb_list; /* List of compound member IDs */ - size_t *memb_offset; /* List of member offsets in compound type, including member size and alignment */ - size_t children_size=0;/* Total size of compound members */ - size_t children_st_align=0; /* The max alignment among compound members. This'll be the compound alignment */ - char **comp_mname; /* List of member names in compound type */ - - if((nmemb = H5T_get_nmembers(dtype))<=0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "compound data type doesn't have any member"); - - if((memb_list = (H5T_t**)H5MM_malloc(nmemb*sizeof(H5T_t*)))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - if((memb_offset = (size_t*)H5MM_calloc(nmemb*sizeof(size_t)))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - if((comp_mname = (char**)H5MM_malloc(nmemb*sizeof(char*)))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - - /* Construct child compound type and retrieve a list of their IDs, offsets, total size, and alignment for compound type. */ - for(i=0; i<nmemb; i++) { - if((memb_type = H5T_get_member_type(dtype, i))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed"); - - if((comp_mname[i] = H5T_get_member_name(dtype, i))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed"); - - if((memb_list[i] = H5T_get_native_type(memb_type, direction, &children_st_align, &(memb_offset[i]), &children_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member identifier retrieval failed"); - - if(H5T_close(memb_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - } - - /* The alignment for whole compound type */ - if(children_st_align && children_size % children_st_align) { - memb_offset[nmemb-1] += children_size % children_st_align; - children_size += children_size % children_st_align; - } - - /* Construct new compound type based on native type */ - if((new_type=H5T_create(H5T_COMPOUND, children_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot create a compound type"); - - /* Insert members for the new compound type */ - for(i=0; i<nmemb; i++) { - if(H5T_insert(new_type, comp_mname[i], memb_offset[i], memb_list[i])<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member to compound datatype"); - } - - /* Update size, offset and compound alignment for parent. */ - if(offset) - *offset = *comp_size; - if(struct_align && *struct_align < children_st_align) - *struct_align = children_st_align; - *comp_size += children_size; - - /* Close member data type */ - for(i=0; i<nmemb; i++) { - if(H5T_close(memb_list[i])<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - /* Free member names in list */ - H5MM_xfree(comp_mname[i]); - } - - /* Free lists for members */ - H5MM_xfree(memb_list); - H5MM_xfree(memb_offset); - H5MM_xfree(comp_mname); - - ret_value = new_type; - } - break; - - case H5T_ENUM: - { - char *memb_name; /* Enum's member name */ - void *memb_value; /* Enum's member value */ - - /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer. */ - - /* Retrieve base type for enumarate type */ - if((super_type=H5T_get_super(dtype))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get base type for enumarate type"); - if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed"); - - /* Allocate room for the enum values */ - if((memb_value = H5MM_malloc(H5T_get_size(super_type)))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - - /* Close super type */ - if(H5T_close(super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - /* Construct new enum type based on native type */ - if((new_type=H5T_enum_create(nat_super_type))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type"); - - /* Retrieve member info and insert members into new enum type */ - if((nmemb = H5T_get_nmembers(dtype))<=0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "enumarate data type doesn't have any member"); - for(i=0; i<nmemb; i++) { - if((memb_name=H5T_get_member_name(dtype, i))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name"); - if(H5T_get_member_value(dtype, i, memb_value)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value"); - if(H5T_enum_insert(new_type, memb_name, memb_value)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member"); - H5MM_xfree(memb_name); - } - H5MM_xfree(memb_value); - - /* Close base type */ - if(H5T_close(nat_super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - ret_value = new_type; - } - break; - - case H5T_ARRAY: - { - int array_rank; /* Array's rank */ - hsize_t *dims = NULL; /* Dimension sizes for array */ - hsize_t nelems = 1; - size_t super_offset=0; - size_t super_size=0; - size_t super_align=0; - - /* Retrieve dimension information for array data type */ - if((array_rank=H5T_get_array_ndims(dtype))<=0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension rank"); - if((dims = (hsize_t*)H5MM_malloc(array_rank*sizeof(hsize_t)))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - if(H5T_get_array_dims(dtype, dims, NULL)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension size"); - - /* Retrieve base type for array type */ - if((super_type=H5T_get_super(dtype))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for enumarate type"); - if((nat_super_type = H5T_get_native_type(super_type, direction, &super_align, - &super_offset, &super_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed"); - - /* Close super type */ - if(H5T_close(super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - /* Create a new array type based on native type */ - if((new_type=H5T_array_create(nat_super_type, array_rank, dims, NULL))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create array type"); - - /* Close base type */ - if(H5T_close(nat_super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - for(i=0; i<array_rank; i++) - nelems *= dims[i]; - H5_CHECK_OVERFLOW(nelems,hsize_t,size_t); - if(H5T_cmp_offset(comp_size, offset, super_size, (size_t)nelems, super_align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - - H5MM_xfree(dims); - ret_value = new_type; - } - break; - - case H5T_VLEN: - { - size_t vl_align = 0; - size_t vl_size = 0; - size_t super_size=0; - - /* Retrieve base type for array type */ - if((super_type=H5T_get_super(dtype))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for enumarate type"); - /* Don't need alignment, offset information if this VL isn't a field of compound type. If it - * is, go to a few steps below to compute the information directly. */ - if((nat_super_type = H5T_get_native_type(super_type, direction, NULL, NULL, &super_size))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed"); - - /* Close super type */ - if(H5T_close(super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - /* Create a new array type based on native type */ - if((new_type=H5T_vlen_create(nat_super_type))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create VL type"); - - /* Close base type */ - if(H5T_close(nat_super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - - /* Update size, offset and compound alignment for parent compound type directly. */ - vl_align = H5T_HVL_COMP_ALIGN_g; - vl_size = sizeof(hvl_t); - - if(H5T_cmp_offset(comp_size, offset, vl_size, 1, vl_align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - - ret_value = new_type; - } - break; - - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "data type doesn't match any native type"); - } - -done: - /* Error cleanup */ - if(ret_value==NULL) { - if(new_type) - H5T_close(new_type); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_native_integer - * - * Purpose: Returns the native integer type of a datatype. - * - * Return: Success: Returns the native data type if successful. - * - * Failure: negative - * - * Programmer: Raymond Lu - * Oct 3, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t* H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t direction, - size_t *struct_align, size_t *offset, size_t *comp_size) -{ - H5T_t *dt; /* Appropriate native datatype to copy */ - hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ - size_t align=0; /* Alignment necessary for native datatype */ - enum match_type { /* The different kinds of integers we can match */ - H5T_NATIVE_INT_MATCH_CHAR, - H5T_NATIVE_INT_MATCH_SHORT, - H5T_NATIVE_INT_MATCH_INT, - H5T_NATIVE_INT_MATCH_LONG, - H5T_NATIVE_INT_MATCH_LLONG, - H5T_NATIVE_INT_MATCH_UNKNOWN - } match=H5T_NATIVE_INT_MATCH_UNKNOWN; - H5T_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); - - assert(size>0); - - if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { - if(size==sizeof(char)) - match=H5T_NATIVE_INT_MATCH_CHAR; - else if(size==sizeof(short)) - match=H5T_NATIVE_INT_MATCH_SHORT; - else if(size==sizeof(int)) - match=H5T_NATIVE_INT_MATCH_INT; - else if(size==sizeof(long)) - match=H5T_NATIVE_INT_MATCH_LONG; - else if(size==sizeof(long_long)) - match=H5T_NATIVE_INT_MATCH_LLONG; - else /* If no native type matches the querried datatype, simply choose the type of biggest size. */ - match=H5T_NATIVE_INT_MATCH_LLONG; - } else if(direction == H5T_DIR_DESCEND) { - if(size==sizeof(long_long)) - match=H5T_NATIVE_INT_MATCH_LLONG; - else if(size==sizeof(long)) - match=H5T_NATIVE_INT_MATCH_LONG; - else if(size==sizeof(int)) - match=H5T_NATIVE_INT_MATCH_INT; - else if(size==sizeof(short)) - match=H5T_NATIVE_INT_MATCH_SHORT; - else if(size==sizeof(char)) - match=H5T_NATIVE_INT_MATCH_CHAR; - else /* If no native type matches the querried datatype, simple choose the type of smallest size. */ - match=H5T_NATIVE_INT_MATCH_CHAR; - } - - /* Set the appropriate native datatype information */ - switch(match) { - case H5T_NATIVE_INT_MATCH_CHAR: - if(sign==H5T_SGN_2) - tid = H5T_NATIVE_SCHAR; - else - tid = H5T_NATIVE_UCHAR; - - align = H5T_NATIVE_SCHAR_COMP_ALIGN_g; - break; - - case H5T_NATIVE_INT_MATCH_SHORT: - if(sign==H5T_SGN_2) - tid = H5T_NATIVE_SHORT; - else - tid = H5T_NATIVE_USHORT; - - align = H5T_NATIVE_SHORT_COMP_ALIGN_g; - break; - - case H5T_NATIVE_INT_MATCH_INT: - if(sign==H5T_SGN_2) - tid = H5T_NATIVE_INT; - else - tid = H5T_NATIVE_UINT; - - align = H5T_NATIVE_INT_COMP_ALIGN_g; - break; - - case H5T_NATIVE_INT_MATCH_LONG: - if(sign==H5T_SGN_2) - tid = H5T_NATIVE_LONG; - else - tid = H5T_NATIVE_ULONG; - - align = H5T_NATIVE_LONG_COMP_ALIGN_g; - break; - - case H5T_NATIVE_INT_MATCH_LLONG: - if(sign==H5T_SGN_2) - tid = H5T_NATIVE_LLONG; - else - tid = H5T_NATIVE_ULLONG; - - align = H5T_NATIVE_LLONG_COMP_ALIGN_g; - break; - - default: - assert(0 && "Unknown native integer match!"); - break; - } /* end switch */ - - /* Create new native type */ - assert(tid>=0); - if(NULL==(dt=H5I_object(tid))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); - if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - - /* compute size and offset of compound type member. */ - if(H5T_cmp_offset(comp_size, offset, size, 1, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_native_float - * - * Purpose: Returns the native floatt type of a datatype. - * - * Return: Success: Returns the native data type if successful. - * - * Failure: negative - * - * Programmer: Raymond Lu - * Oct 3, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t* H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) -{ - H5T_t *dt=NULL; /* Appropriate native datatype to copy */ - hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ - size_t align=0; /* Alignment necessary for native datatype */ - enum match_type { /* The different kinds of floating point types we can match */ - H5T_NATIVE_FLOAT_MATCH_FLOAT, - H5T_NATIVE_FLOAT_MATCH_DOUBLE, - H5T_NATIVE_FLOAT_MATCH_LDOUBLE, - H5T_NATIVE_FLOAT_MATCH_UNKNOWN - } match=H5T_NATIVE_FLOAT_MATCH_UNKNOWN; - H5T_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); - - assert(size>0); - - if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { - if(size==sizeof(float)) - match=H5T_NATIVE_FLOAT_MATCH_FLOAT; - else if(size==sizeof(double)) - match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; - else if(size==sizeof(long double)) - match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; - else /* If not match, return the biggest datatype */ - match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; - } else { - if(size==sizeof(long double)) - match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; - else if(size==sizeof(double)) - match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; - else if(size==sizeof(float)) - match=H5T_NATIVE_FLOAT_MATCH_FLOAT; - else - match=H5T_NATIVE_FLOAT_MATCH_FLOAT; - } - - /* Set the appropriate native floating point information */ - switch(match) { - case H5T_NATIVE_FLOAT_MATCH_FLOAT: - tid = H5T_NATIVE_FLOAT; - align = H5T_NATIVE_FLOAT_COMP_ALIGN_g; - break; - - case H5T_NATIVE_FLOAT_MATCH_DOUBLE: - tid = H5T_NATIVE_DOUBLE; - align = H5T_NATIVE_DOUBLE_COMP_ALIGN_g; - break; - - case H5T_NATIVE_FLOAT_MATCH_LDOUBLE: - tid = H5T_NATIVE_LDOUBLE; - align = H5T_NATIVE_LDOUBLE_COMP_ALIGN_g; - break; - - default: - assert(0 && "Unknown native floating-point match!"); - break; - } /* end switch */ - - /* Create new native type */ - assert(tid>=0); - if(NULL==(dt=H5I_object(tid))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); - if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); - - /* compute offset of compound type member. */ - if(H5T_cmp_offset(comp_size, offset, size, 1, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_cmp_offset - * - * Purpose: This function is only for convenience. It computes the - * compound type size, offset of the member being considered - * and the alignment for the whole compound type. - * - * Return: Success: Non-negative value. - * - * Failure: Negative value. - * - * Programmer: Raymond Lu - * December 10, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, - size_t nelems, size_t align, size_t *struct_align) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5T_cmp_offset, FAIL); - - if(offset && comp_size) { - if(align>1 && *comp_size%align) { - /* Add alignment value */ - *offset = *comp_size + (align - *comp_size%align); - *comp_size += (align - *comp_size%align); - } else - *offset = *comp_size; - - /* compute size of compound type member. */ - *comp_size += nelems*elem_size; - } - - if(struct_align && *struct_align < align) - *struct_align = align; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5Tget_size * * Purpose: Determines the total size of a data type in bytes. @@ -3431,1839 +2670,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Tget_order - * - * Purpose: Returns the byte order of a data type. - * - * Return: Success: A byte order constant - * - * Failure: H5T_ORDER_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -H5T_order_t -H5Tget_order(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_order_t ret_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 data type"); - - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY ==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); - - /* Order */ - assert(H5T_is_atomic(dt)); - ret_value = dt->u.atomic.order; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_order - * - * Purpose: Sets the byte order for a data type. - * - * 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 data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_order(hid_t type_id, H5T_order_t order) -{ - H5T_t *dt = NULL; - 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 data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (order < 0 || order > H5T_ORDER_NONE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order"); - if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); - - /* Commit */ - assert(H5T_is_atomic(dt)); - dt->u.atomic.order = order; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_precision - * - * Purpose: Gets the precision of a data type. The precision is - * the number of significant bits which, unless padding is - * present, is 8 times larger than the value returned by - * H5Tget_size(). - * - * Return: Success: Number of significant bits - * - * Failure: 0 (all atomic types have at least one - * significant bit) - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -size_t -H5Tget_precision(hid_t type_id) -{ - H5T_t *dt = NULL; - size_t ret_value; - - FUNC_ENTER_API(H5Tget_precision, 0); - H5TRACE1("z","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for specified data type"); - - /* Precision */ - assert(H5T_is_atomic(dt)); - ret_value = dt->u.atomic.prec; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_precision - * - * Purpose: Sets the precision of a data type. The precision is - * the number of significant bits which, unless padding is - * present, is 8 times larger than the value returned by - * H5Tget_size(). - * - * If the precision is increased then the offset is decreased - * and then the size is increased to insure that significant - * bits do not "hang over" the edge of the data type. - * - * The precision property of strings is read-only. - * - * When decreasing the precision of a floating point type, set - * the locations and sizes of the sign, mantissa, and exponent - * fields first. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Moved real work to a private function. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_precision(hid_t type_id, size_t prec) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_precision, FAIL); - H5TRACE2("e","iz",type_id,prec); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (prec <= 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "precision must be positive"); - if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - - /* Do the work */ - if (H5T_set_precision(dt, prec)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set precision"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_offset - * - * Purpose: Retrieves the bit offset of the first significant bit. The - * signficant bits of an atomic datum can be offset from the - * beginning of the memory for that datum by an amount of - * padding. The `offset' property specifies the number of bits - * of padding that appear to the "right of" the value. That is, - * if we have a 32-bit datum with 16-bits of precision having - * the value 0x1122 then it will be layed out in memory as (from - * small byte address toward larger byte addresses): - * - * Big Big Little Little - * Endian Endian Endian Endian - * offset=0 offset=16 offset=0 offset=16 - * - * 0: [ pad] [0x11] [0x22] [ pad] - * 1: [ pad] [0x22] [0x11] [ pad] - * 2: [0x11] [ pad] [ pad] [0x22] - * 3: [0x22] [ pad] [ pad] [0x11] - * - * Return: Success: The offset (non-negative) - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -int -H5Tget_offset(hid_t type_id) -{ - H5T_t *dt = NULL; - int ret_value; - - FUNC_ENTER_API(H5Tget_offset, -1); - 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 an atomic data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); - - /* Offset */ - assert(H5T_is_atomic(dt)); - ret_value = (int)dt->u.atomic.offset; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_offset - * - * Purpose: Sets the bit offset of the first significant bit. The - * signficant bits of an atomic datum can be offset from the - * beginning of the memory for that datum by an amount of - * padding. The `offset' property specifies the number of bits - * of padding that appear to the "right of" the value. That is, - * if we have a 32-bit datum with 16-bits of precision having - * the value 0x1122 then it will be layed out in memory as (from - * small byte address toward larger byte addresses): - * - * Big Big Little Little - * Endian Endian Endian Endian - * offset=0 offset=16 offset=0 offset=16 - * - * 0: [ pad] [0x11] [0x22] [ pad] - * 1: [ pad] [0x22] [0x11] [ pad] - * 2: [0x11] [ pad] [ pad] [0x22] - * 3: [0x22] [ pad] [ pad] [0x11] - * - * If the offset is incremented then the total size is - * incremented also if necessary to prevent significant bits of - * the value from hanging over the edge of the data type. - * - * The offset of an H5T_STRING cannot be set to anything but - * zero. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Moved real work to a private function. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_offset(hid_t type_id, size_t offset) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_offset, FAIL); - H5TRACE2("e","iz",type_id,offset); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (H5T_STRING == dt->type && offset != 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset must be zero for this type"); - if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - - /* Do the real work */ - if (H5T_set_offset(dt, offset)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set offset"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_pad - * - * Purpose: Gets the least significant pad type and the most significant - * pad type and returns their values through the LSB and MSB - * arguments, either of which may be the null pointer. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tget_pad, FAIL); - H5TRACE3("e","ixx",type_id,lsb,msb); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); - - /* Get values */ - assert(H5T_is_atomic(dt)); - if (lsb) - *lsb = dt->u.atomic.lsb_pad; - if (msb) - *msb = dt->u.atomic.msb_pad; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_pad - * - * Purpose: Sets the LSB and MSB pad types. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_pad, FAIL); - H5TRACE3("e","iTpTp",type_id,lsb,msb); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (lsb < 0 || lsb >= H5T_NPAD || msb < 0 || msb >= H5T_NPAD) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pad type"); - if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); - - /* Commit */ - assert(H5T_is_atomic(dt)); - dt->u.atomic.lsb_pad = lsb; - dt->u.atomic.msb_pad = msb; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_sign - * - * Purpose: Retrieves the sign type for an integer type. - * - * Return: Success: The sign type. - * - * Failure: H5T_SGN_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - *------------------------------------------------------------------------- - */ -H5T_sign_t -H5Tget_sign(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_sign_t ret_value; - - FUNC_ENTER_API(H5Tget_sign, H5T_SGN_ERROR); - H5TRACE1("Ts","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_SGN_ERROR, "not an integer data type"); - - ret_value = H5T_get_sign(dt); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_sign - * - * Purpose: Private function for H5Tget_sign. Retrieves the sign type - * for an integer type. - * - * Return: Success: The sign type. - * - * Failure: H5T_SGN_ERROR (Negative) - * - * Programmer: Raymond Lu - * October 8, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_sign_t -H5T_get_sign(H5T_t *dt) -{ - H5T_sign_t ret_value; - - FUNC_ENTER_NOAPI(H5T_get_sign, H5T_SGN_ERROR); - - assert(dt); - - /* Defer to parent */ - while(dt->parent) - dt = dt->parent; - - /* Check args */ - if (H5T_INTEGER!=dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_SGN_ERROR, "operation not defined for data type class"); - - /* Sign */ - ret_value = dt->u.atomic.u.i.sign; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - - -/*------------------------------------------------------------------------- - * Function: H5Tset_sign - * - * Purpose: Sets the sign property for an integer. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_sign(hid_t type_id, H5T_sign_t sign) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_sign, FAIL); - H5TRACE2("e","iTs",type_id,sign); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (sign < 0 || sign >= H5T_NSGN) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type"); - if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_INTEGER!=dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - dt->u.atomic.u.i.sign = sign; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_fields - * - * Purpose: Returns information about the locations of the various bit - * fields of a floating point data type. The field positions - * are bit positions in the significant region of the data type. - * Bits are numbered with the least significant bit number zero. - * - * Any (or even all) of the arguments can be null pointers. - * - * Return: Success: Non-negative, field locations and sizes are - * returned through the arguments. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - *------------------------------------------------------------------------- - */ -herr_t -H5Tget_fields(hid_t type_id, size_t *spos/*out*/, - size_t *epos/*out*/, size_t *esize/*out*/, - size_t *mpos/*out*/, size_t *msize/*out*/) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tget_fields, FAIL); - H5TRACE6("e","ixxxxx",type_id,spos,epos,esize,mpos,msize); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Get values */ - if (spos) *spos = dt->u.atomic.u.f.sign; - if (epos) *epos = dt->u.atomic.u.f.epos; - if (esize) *esize = dt->u.atomic.u.f.esize; - if (mpos) *mpos = dt->u.atomic.u.f.mpos; - if (msize) *msize = dt->u.atomic.u.f.msize; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_fields - * - * Purpose: Sets the locations and sizes of the various floating point - * bit fields. The field positions are bit positions in the - * significant region of the data type. Bits are numbered with - * the least significant bit number zero. - * - * Fields are not allowed to extend beyond the number of bits of - * precision, nor are they allowed to overlap with one another. - * - * 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 data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize, - size_t mpos, size_t msize) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_fields, FAIL); - H5TRACE6("e","izzzzz",type_id,spos,epos,esize,mpos,msize); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - if (epos + esize > dt->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent bit field size/location is invalid"); - if (mpos + msize > dt->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mantissa bit field size/location is invalid"); - if (spos >= dt->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign location is not valid"); - - /* Check for overlap */ - if (spos >= epos && spos < epos + esize) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within exponent field"); - if (spos >= mpos && spos < mpos + msize) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within mantissa field"); - if ((mpos < epos && mpos + msize > epos) || - (epos < mpos && epos + esize > mpos)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent and mantissa fields overlap"); - - /* Commit */ - dt->u.atomic.u.f.sign = spos; - dt->u.atomic.u.f.epos = epos; - dt->u.atomic.u.f.mpos = mpos; - dt->u.atomic.u.f.esize = esize; - dt->u.atomic.u.f.msize = msize; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_ebias - * - * Purpose: Retrieves the exponent bias of a floating-point type. - * - * Return: Success: The bias - * - * Failure: 0 - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - *------------------------------------------------------------------------- - */ -size_t -H5Tget_ebias(hid_t type_id) -{ - H5T_t *dt = NULL; - size_t ret_value; - - FUNC_ENTER_API(H5Tget_ebias, 0); - H5TRACE1("z","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for data type class"); - - /* bias */ - H5_ASSIGN_OVERFLOW(ret_value,dt->u.atomic.u.f.ebias,uint64_t,size_t); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_ebias - * - * Purpose: Sets the exponent bias of a floating-point type. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_ebias(hid_t type_id, size_t ebias) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_ebias, FAIL); - H5TRACE2("e","iz",type_id,ebias); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - dt->u.atomic.u.f.ebias = ebias; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_norm - * - * Purpose: Returns the mantisssa normalization of a floating-point data - * type. - * - * Return: Success: Normalization ID - * - * Failure: H5T_NORM_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -H5T_norm_t -H5Tget_norm(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_norm_t ret_value; - - FUNC_ENTER_API(H5Tget_norm, H5T_NORM_ERROR); - H5TRACE1("Tn","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_NORM_ERROR, "operation not defined for data type class"); - - /* norm */ - ret_value = dt->u.atomic.u.f.norm; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_norm - * - * Purpose: Sets the mantissa normalization method for a floating point - * data type. - * - * 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 data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_norm(hid_t type_id, H5T_norm_t norm) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_norm, FAIL); - H5TRACE2("e","iTn",type_id,norm); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (norm < 0 || norm > H5T_NORM_NONE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - dt->u.atomic.u.f.norm = norm; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_inpad - * - * Purpose: If any internal bits of a floating point type are unused - * (that is, those significant bits which are not part of the - * sign, exponent, or mantissa) then they will be filled - * according to the value of this property. - * - * Return: Success: The internal padding type. - * - * Failure: H5T_PAD_ERROR (Negative) - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -H5T_pad_t -H5Tget_inpad(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_pad_t ret_value; - - FUNC_ENTER_API(H5Tget_inpad, H5T_PAD_ERROR); - H5TRACE1("Tp","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_PAD_ERROR, "not a data type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_PAD_ERROR, "operation not defined for data type class"); - - /* pad */ - ret_value = dt->u.atomic.u.f.pad; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_inpad - * - * Purpose: If any internal bits of a floating point type are unused - * (that is, those significant bits which are not part of the - * sign, exponent, or mantissa) then they will be filled - * according to the value of this property. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_inpad(hid_t type_id, H5T_pad_t pad) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_inpad, FAIL); - H5TRACE2("e","iTp",type_id,pad); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (pad < 0 || pad >= H5T_NPAD) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal internal pad type"); - if (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_FLOAT != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - dt->u.atomic.u.f.pad = pad; - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_cset - * - * Purpose: HDF5 is able to distinguish between character sets of - * different nationalities and to convert between them to the - * extent possible. - * - * Return: Success: The character set of an H5T_STRING type. - * - * Failure: H5T_CSET_ERROR (Negative) - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -H5T_cset_t -H5Tget_cset(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_cset_t ret_value; - - FUNC_ENTER_API(H5Tget_cset, H5T_CSET_ERROR); - H5TRACE1("Tc","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR, "not a data type"); - /* Don't see any reason for this. Causes problem for variable-length - * string. -SLU (& QAK) */ - /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ - if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_CSET_ERROR, "operation not defined for data type class"); - - /* result */ - if(H5T_STRING == dt->type) - ret_value = dt->u.atomic.u.s.cset; - else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) - ret_value = dt->u.vlen.cset; - else - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_CSET_ERROR, "can't get cset info"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_cset - * - * Purpose: HDF5 is able to distinguish between character sets of - * different nationalities and to convert between them to the - * extent possible. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works with derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_cset(hid_t type_id, H5T_cset_t cset) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_cset, FAIL); - H5TRACE2("e","iTc",type_id,cset); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (cset < 0 || cset >= H5T_NCSET) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal character set type"); - /* Don't see any reason for this. Causes problem for variable-length - * string. -SLU (& QAK) */ - /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ - if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - if(H5T_STRING == dt->type) - dt->u.atomic.u.s.cset = cset; - else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) - dt->u.vlen.cset = cset; - else - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't set cset info"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_strpad - * - * Purpose: The method used to store character strings differs with the - * programming language: C usually null terminates strings while - * Fortran left-justifies and space-pads strings. This property - * defines the storage mechanism for the string. - * - * Return: Success: The character set of an H5T_STRING type. - * - * Failure: H5T_STR_ERROR (Negative) - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -H5T_str_t -H5Tget_strpad(hid_t type_id) -{ - H5T_t *dt = NULL; - H5T_str_t ret_value; - - FUNC_ENTER_API(H5Tget_strpad, H5T_STR_ERROR); - H5TRACE1("Tz","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_STR_ERROR, "not a data type"); - /* Don't see any reason for this. Causes problem for variable-length - * string. -SLU (& QAK) */ - /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ - if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_STR_ERROR, "operation not defined for data type class"); - - /* result */ - if(H5T_STRING == dt->type) - ret_value = dt->u.atomic.u.s.pad; - else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) - ret_value = dt->u.vlen.pad; - else - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR, "can't get strpad info"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tset_strpad - * - * Purpose: The method used to store character strings differs with the - * programming language: C usually null terminates strings while - * Fortran left-justifies and space-pads strings. This property - * defines the storage mechanism for the string. - * - * When converting from a long string to a short string if the - * short string is H5T_STR_NULLPAD or H5T_STR_SPACEPAD then the - * string is simply truncated; otherwise if the short string is - * H5T_STR_NULLTERM it will be truncated and a null terminator - * is appended. - * - * When converting from a short string to a long string, the - * long string is padded on the end by appending nulls or - * spaces. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, January 9, 1998 - * - * Modifications: - * Robb Matzke, 22 Dec 1998 - * Also works for derived data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tset_strpad(hid_t type_id, H5T_str_t strpad) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_strpad, FAIL); - H5TRACE2("e","iTz",type_id,strpad); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (strpad < 0 || strpad >= H5T_NSTR) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal string pad type"); - /* Don't see any reason for this. Causes problem for variable-length - * string. -SLU (& QAK) */ - /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ - if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - - /* Commit */ - if(H5T_STRING == dt->type) - dt->u.atomic.u.s.pad = strpad; - else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) - dt->u.vlen.pad = strpad; - else - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR, "can't set strpad info"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * 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 i - * 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: H5Tget_member_offset - * - * Purpose: Returns the byte offset of the beginning of a member with - * respect to the beginning of the compound data type datum. - * - * Return: Success: Byte offset. - * - * Failure: Zero. Zero is a valid offset, but this - * function will fail only if a call to - * H5Tget_member_dims() fails with the same - * arguments. - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5Tget_member_offset(hid_t type_id, int membno) -{ - H5T_t *dt = NULL; - size_t ret_value; - - FUNC_ENTER_API(H5Tget_member_offset, 0); - H5TRACE2("z","iIs",type_id,membno); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound data type"); - if (membno < 0 || membno >= dt->u.compnd.nmembs) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid member number"); - - /* Value */ - ret_value = H5T_get_member_offset(dt, membno); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_member_offset - * - * Purpose: Private function for H5Tget_member_offset. Returns the byte - * offset of the beginning of a member with respect to the i - * beginning of the compound data type datum. - * - * Return: Success: Byte offset. - * - * Failure: Zero. Zero is a valid offset, but this - * function will fail only if a call to - * H5Tget_member_dims() fails with the same - * arguments. - * - * Programmer: Raymond Lu - * October 8, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5T_get_member_offset(H5T_t *dt, int membno) -{ - size_t ret_value; - - FUNC_ENTER_NOAPI(H5T_get_member_offset, 0); - - assert(dt); - assert(membno >= 0 && membno < dt->u.compnd.nmembs); - - /* Value */ - ret_value = dt->u.compnd.memb[membno].offset; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tget_member_class - * - * Purpose: Returns the datatype class of a member of a compound datatype. - * - * Return: Success: Non-negative - * - * Failure: H5T_NO_CLASS - * - * Programmer: Quincey Koziol - * Thursday, November 9, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_class_t -H5Tget_member_class(hid_t type_id, int membno) -{ - H5T_t *dt = NULL; - H5T_class_t ret_value; - - FUNC_ENTER_API(H5Tget_member_class, H5T_NO_CLASS); - H5TRACE2("Tt","iIs",type_id,membno); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound data type"); - if (membno < 0 || membno >= dt->u.compnd.nmembs) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number"); - - /* Value */ - ret_value = dt->u.compnd.memb[membno].type->type; - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Tget_member_class() */ - - - -/*------------------------------------------------------------------------- - * Function: H5Tget_member_type - * - * Purpose: Returns the data type of the specified member. The caller - * should invoke H5Tclose() to release resources associated with - * the type. - * - * Return: Success: An OID of a copy of the member data type; - * modifying the returned data type does not - * modify the member type. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * - * Robb Matzke, 4 Jun 1998 - * If the member type is a named type then this function returns a - * handle to the re-opened named type. - * - *------------------------------------------------------------------------- - */ -hid_t -H5Tget_member_type(hid_t type_id, int membno) -{ - H5T_t *dt = NULL, *memb_dt = NULL; - hid_t ret_value; - - FUNC_ENTER_API(H5Tget_member_type, FAIL); - H5TRACE2("i","iIs",type_id,membno); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - if (membno < 0 || membno >= dt->u.compnd.nmembs) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); - if ((memb_dt=H5T_get_member_type(dt, membno))==NULL) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to retrieve member type"); - if ((ret_value = H5I_register(H5I_DATATYPE, memb_dt)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable register data type atom"); - -done: - if(ret_value<0) { - if(memb_dt!=NULL) - H5T_close(memb_dt); - } /* end if */ - - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_member_type - * - * Purpose: Private function for H5Tget_member_type. Returns the data - * type of the specified member. - * - * Return: Success: A copy of the member data type; - * modifying the returned data type does not - * modify the member type. - * - * Failure: NULL - * - * Programmer: Raymond Lu - * October 8, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t * -H5T_get_member_type(H5T_t *dt, int membno) -{ - H5T_t *ret_value = NULL; - - FUNC_ENTER_NOAPI(H5T_get_member_type, NULL); - - assert(dt); - assert(membno >=0 && membno < dt->u.compnd.nmembs); - - /* Copy data type into an atom */ - if (NULL == (ret_value = H5T_copy(dt->u.compnd.memb[membno].type, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member data type"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - - -/*------------------------------------------------------------------------- - * Function: H5Tinsert - * - * Purpose: Adds another member to the compound data type PARENT_ID. The - * new member has a NAME which must be unique within the - * compound data type. The OFFSET argument defines the start of - * the member in an instance of the compound data type, and - * MEMBER_ID is the type of the new member. - * - * Return: Success: Non-negative, the PARENT_ID compound data - * type is modified to include a copy of the - * member type MEMBER_ID. - * - * Failure: Negative - * - * Errors: - * - * Programmer: Robb Matzke - * Monday, December 8, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id) -{ - H5T_t *parent = NULL; /*the compound parent data type */ - H5T_t *member = NULL; /*the atomic member type */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tinsert, FAIL); - H5TRACE4("e","iszi",parent_id,name,offset,member_id); - - /* Check args */ - if (parent_id==member_id) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't insert compound datatype within itself"); - if (NULL == (parent = H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_COMPOUND != parent->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - if (H5T_STATE_TRANSIENT!=parent->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name"); - if (NULL == (member = H5I_object_verify(member_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - - /* Insert */ - if (H5T_insert(parent, name, offset, member) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tpack - * - * Purpose: Recursively removes padding from within a compound data type - * to make it more efficient (space-wise) to store that data. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tpack(hid_t type_id) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tpack, FAIL); - H5TRACE1("e","i",type_id); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only"); - - /* Pack */ - if (H5T_pack(dt) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound data type"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tenum_create - * - * Purpose: Create a new enumeration data type based on the specified - * TYPE, which must be an integer type. - * - * Return: Success: ID of new enumeration data type - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Tuesday, December 22, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t -H5Tenum_create(hid_t parent_id) -{ - H5T_t *parent = NULL; /*base integer data type */ - H5T_t *dt = NULL; /*new enumeration data type */ - hid_t ret_value; /*return value */ - - FUNC_ENTER_API(H5Tenum_create, FAIL); - H5TRACE1("i","i",parent_id); - - /* Check args */ - if (NULL==(parent=H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_INTEGER!=parent->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type"); - - /* Build new type */ - if((dt=H5T_enum_create(parent))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "cannot create enum type"); - /* Atomize the type */ - if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type atom"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_enum_create - * - * Purpose: Private function for H5Tenum_create. Create a new - * enumeration data type based on the specified - * TYPE, which must be an integer type. - * - * Return: Success: new enumeration data type - * - * Failure: NULL - * - * Programmer: Raymond Lu - * October 9, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t * -H5T_enum_create(H5T_t *parent) -{ - H5T_t *ret_value; /*new enumeration data type */ - - FUNC_ENTER_NOAPI(H5T_enum_create, NULL); - - assert(parent); - - /* Build new type */ - if (NULL==(ret_value = H5FL_CALLOC(H5T_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - ret_value->type = H5T_ENUM; - ret_value->parent = H5T_copy(parent, H5T_COPY_ALL); - assert(ret_value->parent); - ret_value->size = ret_value->parent->size; - ret_value->ent.header = HADDR_UNDEF; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - - -/*------------------------------------------------------------------------- - * Function: H5Tenum_insert - * - * Purpose: Insert a new enumeration data type member into an enumeration - * type. TYPE is the enumeration type, NAME is the name of the - * new member, and VALUE points to the value of the new member. - * The NAME and VALUE must both be unique within the TYPE. VALUE - * points to data which is of the data type defined when the - * enumeration type was created. - * - * Return: Success: non-negative - * - * Failure: negative - * - * Programmer: Robb Matzke - * Wednesday, December 23, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tenum_insert(hid_t type, const char *name, void *value) -{ - H5T_t *dt=NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tenum_insert, FAIL); - H5TRACE3("e","isx",type,name,value); - - /* Check args */ - if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_ENUM!=dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); - if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value specified"); - - /* Do work */ - if (H5T_enum_insert(dt, name, value)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert new enumeration member"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5Tget_super * * Purpose: Returns the type from which TYPE is derived. In the case of @@ -5344,362 +2750,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Tget_member_value - * - * Purpose: Return the value for an enumeration data type member. - * - * Return: Success: non-negative with the member value copied - * into the memory pointed to by VALUE. - * - * Failure: negative, VALUE memory is undefined. - * - * Programmer: Robb Matzke - * Wednesday, December 23, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tget_member_value(hid_t type, int membno, void *value/*out*/) -{ - H5T_t *dt=NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tget_member_value, FAIL); - H5TRACE3("e","iIsx",type,membno,value); - - if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_ENUM!=dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); - if (membno<0 || membno>=dt->u.enumer.nmembs) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); - if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null value buffer"); - - if (H5T_get_member_value(dt, membno, value)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get member value"); -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_get_member_value - * - * Purpose: Private function for H5T_get_member_value. Return the - * value for an enumeration data type member. - * - * Return: Success: non-negative with the member value copied - * into the memory pointed to by VALUE. - * - * Failure: negative, VALUE memory is undefined. - * - * Programmer: Raymond Lu - * October 9, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_get_member_value(H5T_t *dt, int membno, void *value/*out*/) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_get_member_value, FAIL); - - assert(dt); - assert(value); - - HDmemcpy(value, dt->u.enumer.value + membno*dt->size, dt->size); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - - -/*------------------------------------------------------------------------- - * Function: H5Tenum_nameof - * - * Purpose: Finds the symbol name that corresponds to the specified VALUE - * of an enumeration data type TYPE. At most SIZE characters of - * the symbol name are copied into the NAME buffer. If the - * entire symbol anem and null terminator do not fit in the NAME - * buffer then as many characters as possible are copied (not - * null terminated) and the function fails. - * - * Return: Success: Non-negative. - * - * Failure: Negative, first character of NAME is set to - * null if SIZE allows it. - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tenum_nameof(hid_t type, void *value, char *name/*out*/, size_t size) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tenum_nameof, FAIL); - H5TRACE4("e","ixxz",type,value,name,size); - - /* Check args */ - if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_ENUM!=dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); - if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value supplied"); - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name buffer supplied"); - - if (NULL==H5T_enum_nameof(dt, value, name, size)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "nameof query failed"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tenum_valueof - * - * Purpose: Finds the value that corresponds to the specified NAME f an - * enumeration TYPE. The VALUE argument should be at least as - * large as the value of H5Tget_size(type) in order to hold the - * result. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/) -{ - H5T_t *dt = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tenum_valueof, FAIL); - H5TRACE3("e","isx",type,name,value); - - /* Check args */ - if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_ENUM!=dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); - if (!value) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value buffer"); - - if (H5T_enum_valueof(dt, name, value)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "valueof query failed"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_vlen_create - * - * Purpose: Create a new variable-length data type based on the specified - * BASE_TYPE. - * - * Return: Success: new VL data type - * - * Failure: NULL - * - * Programmer: Quincey Koziol - * Tuesday, November 20, 2001 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5T_t * -H5T_vlen_create(H5T_t *base) -{ - H5T_t *dt = NULL; /*new VL data type */ - H5T_t *ret_value; /*return value */ - - FUNC_ENTER_NOINIT(H5T_vlen_create); - - /* Check args */ - assert(base); - - /* Build new type */ - if (NULL==(dt = H5FL_CALLOC(H5T_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - dt->ent.header = HADDR_UNDEF; - dt->type = H5T_VLEN; - - /* - * Force conversions (i.e. memory to memory conversions should duplicate - * data, not point to the same VL sequences) - */ - dt->force_conv = TRUE; - dt->parent = H5T_copy(base, H5T_COPY_ALL); - - /* This is a sequence, not a string */ - dt->u.vlen.type = H5T_VLEN_SEQUENCE; - - /* Set up VL information */ - if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); - - /* Set return value */ - ret_value=dt; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tvlen_create - * - * Purpose: Create a new variable-length data type based on the specified - * BASE_TYPE. - * - * Return: Success: ID of new VL data type - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Thursday, May 20, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t -H5Tvlen_create(hid_t base_id) -{ - H5T_t *base = NULL; /*base data type */ - H5T_t *dt = NULL; /*new data type */ - hid_t ret_value; /*return value */ - - FUNC_ENTER_API(H5Tvlen_create, FAIL); - H5TRACE1("i","i",base_id); - - /* Check args */ - if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); - - /* Create up VL datatype */ - if ((dt=H5T_vlen_create(base))==NULL) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location"); - - /* Atomize the type */ - if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * 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; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Tset_tag, FAIL); - H5TRACE2("e","is",type_id,tag); - - /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); - if (H5T_OPAQUE!=dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an opaque data type"); - if (!tag) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no tag"); - - /* Commit */ - H5MM_xfree(dt->u.opaque.tag); - dt->u.opaque.tag = H5MM_strdup(tag); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- - * 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; - - FUNC_ENTER_API(H5Tget_tag, 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 (dt->parent) - dt = dt->parent; /*defer to parent*/ - if (H5T_OPAQUE != dt->type) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "operation not defined for data type class"); - - /* result */ - if (NULL==(ret_value=H5MM_strdup(dt->u.opaque.tag))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - -done: - FUNC_LEAVE_API(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5T_register * * Purpose: Register a hard or soft conversion function for a data type @@ -5937,7 +2987,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_conv_t func, hid_t dxpl_id) { @@ -6236,6 +3286,7 @@ done: *------------------------------------------------------------------------- */ + /*------------------------------------------------------------------------- * Function: H5T_create * @@ -6379,7 +3430,7 @@ done: * *------------------------------------------------------------------------- */ -H5T_t * +static H5T_t * H5T_open (H5G_entry_t *loc, const char *name, hid_t dxpl_id) { H5T_t *dt; @@ -6678,74 +3729,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_commit - * - * Purpose: Commit a type, giving it a name and causing it to become - * immutable. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, June 1, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id) -{ - H5F_t *file = NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_commit, FAIL); - - assert (loc); - assert (name && *name); - assert (type); - - /* - * Check arguments. We cannot commit an immutable type because H5Tclose() - * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing - * a named type should always succeed. - */ - if (H5T_STATE_NAMED==type->state || H5T_STATE_OPEN==type->state) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is already committed"); - if (H5T_STATE_IMMUTABLE==type->state) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is immutable"); - - /* Check for a "sensible" datatype to store on disk */ - if(H5T_is_sensible(type)!=TRUE) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible"); - - /* Find the insertion file */ - if (NULL==(file=H5G_insertion_file(loc, name, dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to find insertion point"); - - /* - * Create the object header and open it for write access. Insert the data - * type message and then give the object header a name. - */ - if (H5O_create (file, dxpl_id, 64, &(type->ent))<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create data type object header"); - if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, 1, type, dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message"); - if (H5G_insert (loc, name, &(type->ent), dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to name data type"); - type->state = H5T_STATE_OPEN; - -done: - if (ret_value<0) { - if ((type->state==H5T_STATE_TRANSIENT || type->state==H5T_STATE_RDONLY) && H5F_addr_defined(type->ent.header)) { - H5O_close(&(type->ent)); - type->ent.header = HADDR_UNDEF; - } - } - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5T_lock * * Purpose: Lock a transient data type making it read-only. If IMMUTABLE @@ -6792,7 +3775,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_release + * Function: H5T_free * * Purpose: Frees all memory associated with a datatype, but does not * free the H5T_t structure (which should be done in H5T_close). @@ -6940,7 +3923,8 @@ H5T_is_atomic(const H5T_t *dt) assert(dt); - if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type && H5T_OPAQUE!=dt->type && H5T_ARRAY!=dt->type) + if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type && + H5T_OPAQUE!=dt->type && H5T_ARRAY!=dt->type) ret_value = TRUE; else ret_value = FALSE; @@ -7133,753 +4117,6 @@ H5T_get_size(const H5T_t *dt) /*------------------------------------------------------------------------- - * Function: H5T_set_precision - * - * Purpose: Sets the precision of a data type. The precision is - * the number of significant bits which, unless padding is - * present, is 8 times larger than the value returned by - * H5Tget_size(). - * - * If the precision is increased then the offset is decreased - * and then the size is increased to insure that significant - * bits do not "hang over" the edge of the data type. - * - * The precision property of strings is read-only. - * - * When decreasing the precision of a floating point type, set - * the locations and sizes of the sign, mantissa, and exponent - * fields first. - * - * 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 data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_set_precision(H5T_t *dt, size_t prec) -{ - size_t offset, size; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_set_precision, FAIL); - - /* Check args */ - assert(dt); - assert(prec>0); - assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs); - - if (dt->parent) { - if (H5T_set_precision(dt->parent, prec)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set precision for base type"); - dt->size = dt->parent->size; - } else { - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); - } else if (H5T_ENUM==dt->type) { - /*nothing*/ - } else if (H5T_is_atomic(dt)) { - /* Adjust the offset and size */ - offset = dt->u.atomic.offset; - size = dt->size; - if (prec > 8*size) - offset = 0; - else if (offset+prec > 8 * size) offset = 8 * size - prec; - if (prec > 8*size) - size = (prec+7) / 8; - - /* Check that things are still kosher */ - switch (dt->type) { - case H5T_INTEGER: - case H5T_TIME: - case H5T_BITFIELD: - /* nothing to check */ - break; - - case H5T_STRING: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "precision for this type is read-only"); - - case H5T_FLOAT: - /* - * The sign, mantissa, and exponent fields should be adjusted - * first when decreasing the precision of a floating point - * type. - */ - if (dt->u.atomic.u.f.sign >= prec || - dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec || - dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first"); - } - break; - - default: - assert("not implemented yet" && 0); - } - - /* Commit */ - dt->size = size; - if (H5T_is_atomic(dt)) { - dt->u.atomic.offset = offset; - dt->u.atomic.prec = prec; - } - } - } - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_set_offset - * - * Purpose: Sets the bit offset of the first significant bit. The - * signficant bits of an atomic datum can be offset from the - * beginning of the memory for that datum by an amount of - * padding. The `offset' property specifies the number of bits - * of padding that appear to the "right of" the value. That is, - * if we have a 32-bit datum with 16-bits of precision having - * the value 0x1122 then it will be layed out in memory as (from - * small byte address toward larger byte addresses): - * - * Big Big Little Little - * Endian Endian Endian Endian - * offset=0 offset=16 offset=0 offset=16 - * - * 0: [ pad] [0x11] [0x22] [ pad] - * 1: [ pad] [0x22] [0x11] [ pad] - * 2: [0x11] [ pad] [ pad] [0x22] - * 3: [0x22] [ pad] [ pad] [0x11] - * - * If the offset is incremented then the total size is - * incremented also if necessary to prevent significant bits of - * the value from hanging over the edge of the data type. - * - * The offset of an H5T_STRING cannot be set to anything but - * zero. - * - * 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 data types. - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_set_offset(H5T_t *dt, size_t offset) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_set_offset, FAIL); - - /* Check args */ - assert(dt); - assert(H5T_STRING!=dt->type || 0==offset); - assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs); - - if (dt->parent) { - if (H5T_set_offset(dt->parent, offset)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set offset for base type"); - dt->size = dt->parent->size; - } else { - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); - } else if (H5T_ENUM==dt->type) { - /*nothing*/ - } else { - if (offset+dt->u.atomic.prec > 8*dt->size) { - dt->size = (offset + dt->u.atomic.prec + 7) / 8; - } - dt->u.atomic.offset = offset; - } - } - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_insert - * - * Purpose: Adds a new MEMBER to the compound data type PARENT. The new - * member will have a NAME that is unique within PARENT and an - * instance of PARENT will have the member begin at byte offset - * OFFSET from the beginning. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, December 8, 1997 - * - * Modifications: - * Took out arrayness parameters - QAK, 10/6/00 - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) -{ - int idx, i; - size_t total_size; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_insert, FAIL); - - /* check args */ - assert(parent && H5T_COMPOUND == parent->type); - assert(H5T_STATE_TRANSIENT==parent->state); - assert(member); - assert(name && *name); - - /* Does NAME already exist in PARENT? */ - for (i=0; i<parent->u.compnd.nmembs; i++) { - if (!HDstrcmp(parent->u.compnd.memb[i].name, name)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique"); - } - - /* Does the new member overlap any existing member ? */ - total_size=member->size; - for (i=0; i<parent->u.compnd.nmembs; i++) { - if ((offset <= parent->u.compnd.memb[i].offset && - offset + total_size > parent->u.compnd.memb[i].offset) || - (parent->u.compnd.memb[i].offset <= offset && - parent->u.compnd.memb[i].offset + - parent->u.compnd.memb[i].size > offset)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member"); - } - - /* Does the new member overlap the end of the compound type? */ - if(offset+total_size>parent->size) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type"); - - /* Increase member array if necessary */ - if (parent->u.compnd.nmembs >= parent->u.compnd.nalloc) { - size_t na = parent->u.compnd.nalloc + H5T_COMPND_INC; - H5T_cmemb_t *x = H5MM_realloc (parent->u.compnd.memb, - na * sizeof(H5T_cmemb_t)); - - if (!x) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - parent->u.compnd.nalloc = (int)na; - parent->u.compnd.memb = x; - } - - /* Add member to end of member array */ - idx = parent->u.compnd.nmembs; - parent->u.compnd.memb[idx].name = H5MM_xstrdup(name); - parent->u.compnd.memb[idx].offset = offset; - parent->u.compnd.memb[idx].size = total_size; - parent->u.compnd.memb[idx].type = H5T_copy (member, H5T_COPY_ALL); - - parent->u.compnd.sorted = H5T_SORT_NONE; - parent->u.compnd.nmembs++; - - /* - * Set the "force conversion" flag if VL datatype fields exist in this type - * or any component types - */ - if(member->type==H5T_VLEN || member->force_conv==TRUE) - parent->force_conv=TRUE; - - /* Set the flag for this compound type, if the field is an array */ - if(member->type==H5T_ARRAY) - parent->u.compnd.has_array=TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_pack - * - * Purpose: Recursively packs a compound data type by removing padding - * bytes. This is done in place (that is, destructively). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_pack(H5T_t *dt) -{ - int i; - size_t offset; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_pack, FAIL); - - assert(dt); - - if (H5T_COMPOUND == dt->type) { - assert(H5T_STATE_TRANSIENT==dt->state); - - /* Recursively pack the members */ - for (i=0; i<dt->u.compnd.nmembs; i++) { - if (H5T_pack(dt->u.compnd.memb[i].type) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound data type"); - } - - /* Remove padding between members */ - H5T_sort_value(dt, NULL); - for (i=0, offset=0; i<dt->u.compnd.nmembs; i++) { - dt->u.compnd.memb[i].offset = offset; - offset += dt->u.compnd.memb[i].size; - } - - /* Change total size */ - dt->size = MAX(1, offset); - } - -done: - FUNC_LEAVE_NOAPI(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); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_enum_insert - * - * Purpose: Insert a new member having a NAME and VALUE into an - * enumeration data TYPE. The NAME and VALUE must both be - * unique. The VALUE points to data of the data type defined for - * the enumeration base type. - * - * Return: Success: non-negative - * - * Failure: negative - * - * Programmer: Robb Matzke - * Wednesday, December 23, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_enum_insert(H5T_t *dt, const char *name, void *value) -{ - int i; - char **names=NULL; - uint8_t *values=NULL; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_enum_insert, FAIL); - - assert(dt); - assert(name && *name); - assert(value); - - /* The name and value had better not already exist */ - for (i=0; i<dt->u.enumer.nmembs; i++) { - if (!HDstrcmp(dt->u.enumer.name[i], name)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "name redefinition"); - if (!HDmemcmp(dt->u.enumer.value+i*dt->size, value, dt->size)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "value redefinition"); - } - - /* Increase table sizes */ - if (dt->u.enumer.nmembs >= dt->u.enumer.nalloc) { - int n = MAX(32, 2*dt->u.enumer.nalloc); - if (NULL==(names=H5MM_realloc(dt->u.enumer.name, n*sizeof(char*)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - dt->u.enumer.name = names; - - if (NULL==(values=H5MM_realloc(dt->u.enumer.value, n*dt->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - dt->u.enumer.value = values; - dt->u.enumer.nalloc = n; - } - - /* Insert new member at end of member arrays */ - dt->u.enumer.sorted = H5T_SORT_NONE; - i = dt->u.enumer.nmembs++; - dt->u.enumer.name[i] = H5MM_xstrdup(name); - HDmemcpy(dt->u.enumer.value+i*dt->size, value, dt->size); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_enum_nameof - * - * Purpose: Finds the symbol name that corresponds the the specified - * VALUE of an enumeration data type DT. At most SIZE characters - * of the symbol name are copied into the NAME buffer. If the - * entire symbol name and null terminator do not fit in the NAME - * buffer then as many characters as possible are copied and the - * function returns failure. - * - * If NAME is the null pointer and SIZE is zero then enough - * space is allocated to hold the result and a pointer to that - * memory is returned. - * - * Return: Success: Pointer to NAME - * - * Failure: NULL, name[0] is set to null. - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -char * -H5T_enum_nameof(H5T_t *dt, void *value, char *name/*out*/, size_t size) -{ - int lt, md, rt; /*indices for binary search */ - int cmp=(-1); /*comparison result */ - char *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_enum_nameof, NULL); - - /* Check args */ - assert(dt && H5T_ENUM==dt->type); - assert(value); - assert(name || 0==size); - if (name && size>0) *name = '\0'; - - /* Sanity check */ - if (dt->u.enumer.nmembs == 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "datatype has no members"); - - /* Do a binary search over the values to find the correct one */ - H5T_sort_value(dt, NULL); - lt = 0; - rt = dt->u.enumer.nmembs; - md = -1; - - while (lt<rt) { - md = (lt+rt)/2; - cmp = HDmemcmp(value, dt->u.enumer.value+md*dt->size, dt->size); - if (cmp<0) { - rt = md; - } else if (cmp>0) { - lt = md+1; - } else { - break; - } - } - /* Value was not yet defined. This fixes bug # 774, 2002/06/05 EIP */ - if (cmp!=0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "value is currently not defined"); - - /* Save result name */ - if (!name && NULL==(name=H5MM_malloc(HDstrlen(dt->u.enumer.name[md])+1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDstrncpy(name, dt->u.enumer.name[md], size); - if (HDstrlen(dt->u.enumer.name[md])>=size) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, NULL, "name has been truncated"); - - /* Set return value */ - ret_value=name; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5T_enum_valueof - * - * Purpose: Finds the value that corresponds the the specified symbol - * NAME of an enumeration data type DT and copy it to the VALUE - * result buffer. The VALUE should be allocated by the caller to - * be large enough for the result. - * - * Return: Success: Non-negative, value stored in VALUE. - * - * Failure: Negative, VALUE is undefined. - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/) -{ - int lt, md, rt; /*indices for binary search */ - int cmp=(-1); /*comparison result */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5T_enum_valueof, FAIL); - - /* Check args */ - assert(dt && H5T_ENUM==dt->type); - assert(name && *name); - assert(value); - - /* Sanity check */ - if (dt->u.enumer.nmembs == 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "datatype has no members"); - - /* Do a binary search over the names to find the correct one */ - H5T_sort_name(dt, NULL); - lt = 0; - rt = dt->u.enumer.nmembs; - md = -1; - - while (lt<rt) { - md = (lt+rt)/2; - cmp = HDstrcmp(name, dt->u.enumer.name[md]); - if (cmp<0) { - rt = md; - } else if (cmp>0) { - lt = md+1; - } else { - break; - } - } - /* Value was not yet defined. This fixes bug # 774, 2002/06/05 EIP */ - if (cmp!=0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "string doesn't exist in the enumeration type"); - - HDmemcpy(value, dt->u.enumer.value+md*dt->size, dt->size); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5T_cmp * * Purpose: Compares two data types. @@ -8737,291 +4974,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Tarray_create - * - * Purpose: Create a new array data type based on the specified BASE_TYPE. - * The type is an array with NDIMS dimensionality and the size of the - * array is DIMS. The total member size should be relatively small. - * PERM is currently unimplemented and unused, but is designed to contain - * the dimension permutation from C order. - * Array datatypes are currently limited to H5S_MAX_RANK number of - * dimensions and must have the number of dimensions set greater than - * 0. (i.e. 0 > ndims <= H5S_MAX_RANK) All dimensions sizes must be greater - * than 0 also. - * - * Return: Success: ID of new array data type - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Thursday, Oct 26, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t -H5Tarray_create(hid_t base_id, int ndims, const hsize_t dim[/* ndims */], - const int perm[/* ndims */]) -{ - H5T_t *base = NULL; /* base data type */ - H5T_t *dt = NULL; /* new array data type */ - int i; /* local index variable */ - hid_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Tarray_create, FAIL); - H5TRACE4("i","iIs*h*Is",base_id,ndims,dim,perm); - - /* Check args */ - if (ndims<1 || ndims>H5S_MAX_RANK) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimensionality"); - if (ndims>0 && !dim) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); - for(i=0; i<ndims; i++) - if(!(dim[i]>0)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero-sized dimension specified"); - if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); - - /* Create the actual array datatype */ - if ((dt=H5T_array_create(base,ndims,dim,perm))==NULL) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create datatype"); - - /* Atomize the type */ - if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Tarray_create */ - - -/*------------------------------------------------------------------------- - * Function: H5T_array_create - * - * Purpose: Internal routine to create a new array data type based on the - * specified BASE_TYPE. The type is an array with NDIMS dimensionality - * and the size of the array is DIMS. PERM is currently unimplemented - * and unused, but is designed to contain the dimension permutation from - * C order. Array datatypes are currently limited to H5S_MAX_RANK number - * of * dimensions. - * - * Return: Success: ID of new array data type - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Thursday, Oct 26, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_t * -H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */], - const int perm[/* ndims */]) -{ - H5T_t *ret_value = NULL; /*new array data type */ - int i; /* local index variable */ - - FUNC_ENTER_NOAPI(H5T_array_create, NULL); - - assert(base); - assert(ndims>0 && ndims<=H5S_MAX_RANK); - assert(dim); - - /* Build new type */ - if (NULL==(ret_value = H5FL_CALLOC(H5T_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - - ret_value->ent.header = HADDR_UNDEF; - ret_value->type = H5T_ARRAY; - - /* Copy the base type of the array */ - ret_value->parent = H5T_copy(base, H5T_COPY_ALL); - - /* Set the array parameters */ - ret_value->u.array.ndims = ndims; - - /* Copy the array dimensions & compute the # of elements in the array */ - for(i=0, ret_value->u.array.nelem=1; i<ndims; i++) { - H5_ASSIGN_OVERFLOW(ret_value->u.array.dim[i],dim[i],hsize_t,size_t); - ret_value->u.array.nelem *= (size_t)dim[i]; - } /* end for */ - - /* Copy the dimension permutations */ - for(i=0; i<ndims; i++) - ret_value->u.array.perm[i] = perm ? perm[i] : i; - - /* Set the array's size (number of elements * element datatype's size) */ - ret_value->size = ret_value->parent->size * ret_value->u.array.nelem; - - /* - * Set the "force conversion" flag if a VL base datatype is used or - * or if any components of the base datatype are VL types. - */ - if(base->type==H5T_VLEN || base->force_conv==TRUE) - ret_value->force_conv=TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5T_array_create */ - - -/*------------------------------------------------------------------------- - * Function: H5Tget_array_ndims - * - * Purpose: Query the number of dimensions for an array datatype. - * - * Return: Success: Number of dimensions of the array datatype - * Failure: Negative - * - * Programmer: Quincey Koziol - * Monday, November 6, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5Tget_array_ndims(hid_t type_id) -{ - H5T_t *dt = NULL; /* pointer to array data type */ - int ret_value; /* return value */ - - FUNC_ENTER_API(H5Tget_array_ndims, 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 datatype object"); - if(dt->type!=H5T_ARRAY) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); - - /* Retrieve the number of dimensions */ - ret_value = H5T_get_array_ndims(dt); - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Tget_array_ndims */ - - -/*------------------------------------------------------------------------- - * Function: H5T_get_array_ndims - * - * Purpose: Private function for H5T_get_array_ndims. Query the number - * of dimensions for an array datatype. - * - * Return: Success: Number of dimensions of the array datatype - * Failure: Negative - * - * Programmer: Raymond Lu - * October 10, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5T_get_array_ndims(H5T_t *dt) -{ - int ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5T_get_array_ndims, FAIL); - - assert(dt); - assert(dt->type==H5T_ARRAY); - - /* Retrieve the number of dimensions */ - ret_value=dt->u.array.ndims; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5T_get_array_ndims */ - - -/*------------------------------------------------------------------------- - * Function: H5Tget_array_dims - * - * Purpose: Query the sizes of dimensions for an array datatype. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Monday, November 6, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]) -{ - H5T_t *dt = NULL; /* pointer to array data type */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Tget_array_dims, FAIL); - H5TRACE3("e","i*h*Is",type_id,dims,perm); - - /* Check args */ - if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object"); - if(dt->type!=H5T_ARRAY) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); - - /* Retrieve the sizes of the dimensions */ - if(H5T_get_array_dims(dt, dims, perm)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes"); -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Tget_array_dims */ - - -/*------------------------------------------------------------------------- - * Function: H5T_get_array_dims - * - * Purpose: Private function for H5T_get_array_dims. Query the sizes - * of dimensions for an array datatype. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Raymond Lu - * October 10, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]) -{ - herr_t ret_value = SUCCEED; /* return value */ - int i; /* Local index variable */ - - FUNC_ENTER_NOAPI(H5T_get_array_dims, FAIL); - - assert(dt); - assert(dt->type==H5T_ARRAY); - - /* Retrieve the sizes of the dimensions */ - if(dims) - for(i=0; i<dt->u.array.ndims; i++) - dims[i]=dt->u.array.dim[i]; - - /* Retrieve the dimension permutations */ - if(perm) - for(i=0; i<dt->u.array.ndims; i++) - perm[i]=dt->u.array.perm[i]; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5T_get_array_dims */ - - - -/*------------------------------------------------------------------------- * Function: H5T_is_sensible * * Purpose: Determines if a data type is sensible to store on disk diff --git a/src/H5Tarray.c b/src/H5Tarray.c new file mode 100644 index 0000000..a9b2d10 --- /dev/null +++ b/src/H5Tarray.c @@ -0,0 +1,343 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for array datatypes in + * the H5T interface. + */ + +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ + +#include "H5private.h" /*generic functions */ +#include "H5Eprivate.h" /*error handling */ +#include "H5FLprivate.h" /*Free Lists */ +#include "H5Iprivate.h" /*ID functions */ +#include "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tarray_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_array_interface +static herr_t H5T_init_array_interface(void); + +/* Declare extern the free list for H5T_t's */ +H5FL_EXTERN(H5T_t); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_array_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_array_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_array_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_array_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_array_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tarray_create + * + * Purpose: Create a new array data type based on the specified BASE_TYPE. + * The type is an array with NDIMS dimensionality and the size of the + * array is DIMS. The total member size should be relatively small. + * PERM is currently unimplemented and unused, but is designed to contain + * the dimension permutation from C order. + * Array datatypes are currently limited to H5S_MAX_RANK number of + * dimensions and must have the number of dimensions set greater than + * 0. (i.e. 0 > ndims <= H5S_MAX_RANK) All dimensions sizes must be greater + * than 0 also. + * + * Return: Success: ID of new array data type + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, Oct 26, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tarray_create(hid_t base_id, int ndims, const hsize_t dim[/* ndims */], + const int perm[/* ndims */]) +{ + H5T_t *base = NULL; /* base data type */ + H5T_t *dt = NULL; /* new array data type */ + int i; /* local index variable */ + hid_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Tarray_create, FAIL); + H5TRACE4("i","iIs*h*Is",base_id,ndims,dim,perm); + + /* Check args */ + if (ndims<1 || ndims>H5S_MAX_RANK) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimensionality"); + if (ndims>0 && !dim) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); + for(i=0; i<ndims; i++) + if(!(dim[i]>0)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero-sized dimension specified"); + if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); + + /* Create the actual array datatype */ + if ((dt=H5T_array_create(base,ndims,dim,perm))==NULL) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create datatype"); + + /* Atomize the type */ + if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Tarray_create */ + + +/*------------------------------------------------------------------------- + * Function: H5T_array_create + * + * Purpose: Internal routine to create a new array data type based on the + * specified BASE_TYPE. The type is an array with NDIMS dimensionality + * and the size of the array is DIMS. PERM is currently unimplemented + * and unused, but is designed to contain the dimension permutation from + * C order. Array datatypes are currently limited to H5S_MAX_RANK number + * of * dimensions. + * + * Return: Success: ID of new array data type + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, Oct 26, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */], + const int perm[/* ndims */]) +{ + H5T_t *ret_value = NULL; /*new array data type */ + int i; /* local index variable */ + + FUNC_ENTER_NOAPI(H5T_array_create, NULL); + + assert(base); + assert(ndims>0 && ndims<=H5S_MAX_RANK); + assert(dim); + + /* Build new type */ + if (NULL==(ret_value = H5FL_CALLOC(H5T_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + ret_value->ent.header = HADDR_UNDEF; + ret_value->type = H5T_ARRAY; + + /* Copy the base type of the array */ + ret_value->parent = H5T_copy(base, H5T_COPY_ALL); + + /* Set the array parameters */ + ret_value->u.array.ndims = ndims; + + /* Copy the array dimensions & compute the # of elements in the array */ + for(i=0, ret_value->u.array.nelem=1; i<ndims; i++) { + H5_ASSIGN_OVERFLOW(ret_value->u.array.dim[i],dim[i],hsize_t,size_t); + ret_value->u.array.nelem *= (size_t)dim[i]; + } /* end for */ + + /* Copy the dimension permutations */ + for(i=0; i<ndims; i++) + ret_value->u.array.perm[i] = perm ? perm[i] : i; + + /* Set the array's size (number of elements * element datatype's size) */ + ret_value->size = ret_value->parent->size * ret_value->u.array.nelem; + + /* + * Set the "force conversion" flag if a VL base datatype is used or + * or if any components of the base datatype are VL types. + */ + if(base->type==H5T_VLEN || base->force_conv==TRUE) + ret_value->force_conv=TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5T_array_create */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_array_ndims + * + * Purpose: Query the number of dimensions for an array datatype. + * + * Return: Success: Number of dimensions of the array datatype + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Tget_array_ndims(hid_t type_id) +{ + H5T_t *dt = NULL; /* pointer to array data type */ + int ret_value; /* return value */ + + FUNC_ENTER_API(H5Tget_array_ndims, 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 datatype object"); + if(dt->type!=H5T_ARRAY) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); + + /* Retrieve the number of dimensions */ + ret_value = H5T_get_array_ndims(dt); + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Tget_array_ndims */ + + +/*------------------------------------------------------------------------- + * Function: H5T_get_array_ndims + * + * Purpose: Private function for H5T_get_array_ndims. Query the number + * of dimensions for an array datatype. + * + * Return: Success: Number of dimensions of the array datatype + * Failure: Negative + * + * Programmer: Raymond Lu + * October 10, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5T_get_array_ndims(H5T_t *dt) +{ + int ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5T_get_array_ndims, FAIL); + + assert(dt); + assert(dt->type==H5T_ARRAY); + + /* Retrieve the number of dimensions */ + ret_value=dt->u.array.ndims; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5T_get_array_ndims */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_array_dims + * + * Purpose: Query the sizes of dimensions for an array datatype. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]) +{ + H5T_t *dt = NULL; /* pointer to array data type */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Tget_array_dims, FAIL); + H5TRACE3("e","i*h*Is",type_id,dims,perm); + + /* Check args */ + if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object"); + if(dt->type!=H5T_ARRAY) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); + + /* Retrieve the sizes of the dimensions */ + if(H5T_get_array_dims(dt, dims, perm)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes"); +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Tget_array_dims */ + + +/*------------------------------------------------------------------------- + * Function: H5T_get_array_dims + * + * Purpose: Private function for H5T_get_array_dims. Query the sizes + * of dimensions for an array datatype. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Raymond Lu + * October 10, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]) +{ + herr_t ret_value = SUCCEED; /* return value */ + int i; /* Local index variable */ + + FUNC_ENTER_NOAPI(H5T_get_array_dims, FAIL); + + assert(dt); + assert(dt->type==H5T_ARRAY); + + /* Retrieve the sizes of the dimensions */ + if(dims) + for(i=0; i<dt->u.array.ndims; i++) + dims[i]=dt->u.array.dim[i]; + + /* Retrieve the dimension permutations */ + if(perm) + for(i=0; i<dt->u.array.ndims; i++) + perm[i]=dt->u.array.perm[i]; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5T_get_array_dims */ + diff --git a/src/H5Tbit.c b/src/H5Tbit.c index ad716d3..ece0d51 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -1,23 +1,33 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* - * Copyright (C) 1998-2001 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Wednesday, June 10, 1998 - * - * Purpose: Operations on bit vectors. A bit vector is an array of bytes + * Module Info: Operations on bit vectors. A bit vector is an array of bytes * with the least-significant bits in the first byte. That is, * the bytes are in little-endian order. */ + #define H5T_PACKAGE /*suppress error about including H5Tpkg */ -#include "H5private.h" -#include "H5Eprivate.h" -#include "H5Iprivate.h" -#include "H5Tpkg.h" +#include "H5private.h" /*generic functions */ +#include "H5Eprivate.h" /*error handling */ +#include "H5Iprivate.h" /*ID functions */ +#include "H5Tpkg.h" /*data-type functions */ -/* Interface initialization */ #define PABLO_MASK H5Tbit_mask + +/* Interface initialization */ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c new file mode 100644 index 0000000..6619392 --- /dev/null +++ b/src/H5Tcommit.c @@ -0,0 +1,206 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for committing datatypes + * to a file for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tcommit_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_commit_interface +static herr_t H5T_init_commit_interface(void); + + +/* Static local functions */ +static herr_t H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_commit_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_commit_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_commit_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_commit_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_commit_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tcommit + * + * Purpose: Save a transient data type to a file and turn the type handle + * into a named, immutable type. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, June 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tcommit(hid_t loc_id, const char *name, hid_t type_id) +{ + H5G_entry_t *loc = NULL; + H5T_t *type = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tcommit, FAIL); + H5TRACE3("e","isi",loc_id,name,type_id); + + /* Check arguments */ + if (NULL==(loc=H5G_loc (loc_id))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); + if (!name || !*name) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + if (NULL==(type=H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + /* Commit the type */ + if (H5T_commit (loc, name, type, H5AC_dxpl_id)<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit data type"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_commit + * + * Purpose: Commit a type, giving it a name and causing it to become + * immutable. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, June 1, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id) +{ + H5F_t *file = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_commit, FAIL); + + assert (loc); + assert (name && *name); + assert (type); + + /* + * Check arguments. We cannot commit an immutable type because H5Tclose() + * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing + * a named type should always succeed. + */ + if (H5T_STATE_NAMED==type->state || H5T_STATE_OPEN==type->state) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is already committed"); + if (H5T_STATE_IMMUTABLE==type->state) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is immutable"); + + /* Check for a "sensible" datatype to store on disk */ + if(H5T_is_sensible(type)!=TRUE) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible"); + + /* Find the insertion file */ + if (NULL==(file=H5G_insertion_file(loc, name, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to find insertion point"); + + /* + * Create the object header and open it for write access. Insert the data + * type message and then give the object header a name. + */ + if (H5O_create (file, dxpl_id, 64, &(type->ent))<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create data type object header"); + if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, 1, type, dxpl_id)<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message"); + if (H5G_insert (loc, name, &(type->ent), dxpl_id)<0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to name data type"); + type->state = H5T_STATE_OPEN; + +done: + if (ret_value<0) { + if ((type->state==H5T_STATE_TRANSIENT || type->state==H5T_STATE_RDONLY) && H5F_addr_defined(type->ent.header)) { + H5O_close(&(type->ent)); + type->ent.header = HADDR_UNDEF; + } + } + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tcommitted + * + * Purpose: Determines if a data type is committed or not. + * + * Return: Success: TRUE if committed, FALSE otherwise. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, June 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5Tcommitted(hid_t type_id) +{ + H5T_t *type = NULL; + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Tcommitted, FAIL); + H5TRACE1("b","i",type_id); + + /* Check arguments */ + if (NULL==(type=H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + /* Set return value */ + ret_value= (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state); + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c new file mode 100644 index 0000000..8326ffe --- /dev/null +++ b/src/H5Tcompound.c @@ -0,0 +1,512 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for 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 H5Tcompound_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_compound_interface +static herr_t H5T_init_compound_interface(void); + +/* Local macros */ +#define H5T_COMPND_INC 64 /*typical max numb of members per struct */ + +/* Static local functions */ +static size_t H5T_get_member_offset(H5T_t *dt, int membno); +static herr_t H5T_pack(H5T_t *dt); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_compound_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_compound_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_compound_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_compound_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_compound_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_offset + * + * Purpose: Returns the byte offset of the beginning of a member with + * respect to the beginning of the compound data type datum. + * + * Return: Success: Byte offset. + * + * Failure: Zero. Zero is a valid offset, but this + * function will fail only if a call to + * H5Tget_member_dims() fails with the same + * arguments. + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_member_offset(hid_t type_id, int membno) +{ + H5T_t *dt = NULL; + size_t ret_value; + + FUNC_ENTER_API(H5Tget_member_offset, 0); + H5TRACE2("z","iIs",type_id,membno); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound data type"); + if (membno < 0 || membno >= dt->u.compnd.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid member number"); + + /* Value */ + ret_value = H5T_get_member_offset(dt, membno); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_member_offset + * + * Purpose: Private function for H5Tget_member_offset. Returns the byte + * offset of the beginning of a member with respect to the i + * beginning of the compound data type datum. + * + * Return: Success: Byte offset. + * + * Failure: Zero. Zero is a valid offset, but this + * function will fail only if a call to + * H5Tget_member_dims() fails with the same + * arguments. + * + * Programmer: Raymond Lu + * October 8, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static size_t +H5T_get_member_offset(H5T_t *dt, int membno) +{ + size_t ret_value; + + FUNC_ENTER_NOAPI(H5T_get_member_offset, 0); + + assert(dt); + assert(membno >= 0 && membno < dt->u.compnd.nmembs); + + /* Value */ + ret_value = dt->u.compnd.memb[membno].offset; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_class + * + * Purpose: Returns the datatype class of a member of a compound datatype. + * + * Return: Success: Non-negative + * + * Failure: H5T_NO_CLASS + * + * Programmer: Quincey Koziol + * Thursday, November 9, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_class_t +H5Tget_member_class(hid_t type_id, int membno) +{ + H5T_t *dt = NULL; + H5T_class_t ret_value; + + FUNC_ENTER_API(H5Tget_member_class, H5T_NO_CLASS); + H5TRACE2("Tt","iIs",type_id,membno); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound data type"); + if (membno < 0 || membno >= dt->u.compnd.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number"); + + /* Value */ + ret_value = dt->u.compnd.memb[membno].type->type; + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Tget_member_class() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_type + * + * Purpose: Returns the data type of the specified member. The caller + * should invoke H5Tclose() to release resources associated with + * the type. + * + * Return: Success: An OID of a copy of the member data type; + * modifying the returned data type does not + * modify the member type. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + * Robb Matzke, 4 Jun 1998 + * If the member type is a named type then this function returns a + * handle to the re-opened named type. + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tget_member_type(hid_t type_id, int membno) +{ + H5T_t *dt = NULL, *memb_dt = NULL; + hid_t ret_value; + + FUNC_ENTER_API(H5Tget_member_type, FAIL); + H5TRACE2("i","iIs",type_id,membno); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + if (membno < 0 || membno >= dt->u.compnd.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); + if ((memb_dt=H5T_get_member_type(dt, membno))==NULL) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to retrieve member type"); + if ((ret_value = H5I_register(H5I_DATATYPE, memb_dt)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable register data type atom"); + +done: + if(ret_value<0) { + if(memb_dt!=NULL) + H5T_close(memb_dt); + } /* end if */ + + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_member_type + * + * Purpose: Private function for H5Tget_member_type. Returns the data + * type of the specified member. + * + * Return: Success: A copy of the member data type; + * modifying the returned data type does not + * modify the member type. + * + * Failure: NULL + * + * Programmer: Raymond Lu + * October 8, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5T_get_member_type(H5T_t *dt, int membno) +{ + H5T_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(H5T_get_member_type, NULL); + + assert(dt); + assert(membno >=0 && membno < dt->u.compnd.nmembs); + + /* Copy data type into an atom */ + if (NULL == (ret_value = H5T_copy(dt->u.compnd.memb[membno].type, H5T_COPY_REOPEN))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member data type"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tinsert + * + * Purpose: Adds another member to the compound data type PARENT_ID. The + * new member has a NAME which must be unique within the + * compound data type. The OFFSET argument defines the start of + * the member in an instance of the compound data type, and + * MEMBER_ID is the type of the new member. + * + * Return: Success: Non-negative, the PARENT_ID compound data + * type is modified to include a copy of the + * member type MEMBER_ID. + * + * Failure: Negative + * + * Errors: + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id) +{ + H5T_t *parent = NULL; /*the compound parent data type */ + H5T_t *member = NULL; /*the atomic member type */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tinsert, FAIL); + H5TRACE4("e","iszi",parent_id,name,offset,member_id); + + /* Check args */ + if (parent_id==member_id) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't insert compound datatype within itself"); + if (NULL == (parent = H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_COMPOUND != parent->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + if (H5T_STATE_TRANSIENT!=parent->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name"); + if (NULL == (member = H5I_object_verify(member_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + /* Insert */ + if (H5T_insert(parent, name, offset, member) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tpack + * + * Purpose: Recursively removes padding from within a compound data type + * to make it more efficient (space-wise) to store that data. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tpack(hid_t type_id) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tpack, FAIL); + H5TRACE1("e","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only"); + + /* Pack */ + if (H5T_pack(dt) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound data type"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_insert + * + * Purpose: Adds a new MEMBER to the compound data type PARENT. The new + * member will have a NAME that is unique within PARENT and an + * instance of PARENT will have the member begin at byte offset + * OFFSET from the beginning. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * Took out arrayness parameters - QAK, 10/6/00 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) +{ + int idx, i; + size_t total_size; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_insert, FAIL); + + /* check args */ + assert(parent && H5T_COMPOUND == parent->type); + assert(H5T_STATE_TRANSIENT==parent->state); + assert(member); + assert(name && *name); + + /* Does NAME already exist in PARENT? */ + for (i=0; i<parent->u.compnd.nmembs; i++) { + if (!HDstrcmp(parent->u.compnd.memb[i].name, name)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique"); + } + + /* Does the new member overlap any existing member ? */ + total_size=member->size; + for (i=0; i<parent->u.compnd.nmembs; i++) { + if ((offset <= parent->u.compnd.memb[i].offset && + offset + total_size > parent->u.compnd.memb[i].offset) || + (parent->u.compnd.memb[i].offset <= offset && + parent->u.compnd.memb[i].offset + + parent->u.compnd.memb[i].size > offset)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member"); + } + + /* Does the new member overlap the end of the compound type? */ + if(offset+total_size>parent->size) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type"); + + /* Increase member array if necessary */ + if (parent->u.compnd.nmembs >= parent->u.compnd.nalloc) { + size_t na = parent->u.compnd.nalloc + H5T_COMPND_INC; + H5T_cmemb_t *x = H5MM_realloc (parent->u.compnd.memb, + na * sizeof(H5T_cmemb_t)); + + if (!x) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + parent->u.compnd.nalloc = (int)na; + parent->u.compnd.memb = x; + } + + /* Add member to end of member array */ + idx = parent->u.compnd.nmembs; + parent->u.compnd.memb[idx].name = H5MM_xstrdup(name); + parent->u.compnd.memb[idx].offset = offset; + parent->u.compnd.memb[idx].size = total_size; + parent->u.compnd.memb[idx].type = H5T_copy (member, H5T_COPY_ALL); + + parent->u.compnd.sorted = H5T_SORT_NONE; + parent->u.compnd.nmembs++; + + /* + * Set the "force conversion" flag if VL datatype fields exist in this type + * or any component types + */ + if(member->type==H5T_VLEN || member->force_conv==TRUE) + parent->force_conv=TRUE; + + /* Set the flag for this compound type, if the field is an array */ + if(member->type==H5T_ARRAY) + parent->u.compnd.has_array=TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_pack + * + * Purpose: Recursively packs a compound data type by removing padding + * bytes. This is done in place (that is, destructively). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_pack(H5T_t *dt) +{ + int i; + size_t offset; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_pack, FAIL); + + assert(dt); + + if (H5T_COMPOUND == dt->type) { + assert(H5T_STATE_TRANSIENT==dt->state); + + /* Recursively pack the members */ + for (i=0; i<dt->u.compnd.nmembs; i++) { + if (H5T_pack(dt->u.compnd.memb[i].type) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound data type"); + } + + /* Remove padding between members */ + H5T_sort_value(dt, NULL); + for (i=0, offset=0; i<dt->u.compnd.nmembs; i++) { + dt->u.compnd.memb[i].offset = offset; + offset += dt->u.compnd.memb[i].size; + } + + /* Change total size */ + dt->size = MAX(1, offset); + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + diff --git a/src/H5Tconv.c b/src/H5Tconv.c index c2a9691..5f195d1 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1,21 +1,32 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* - * Copyright (C) 1998-2001 Spizella Software - * All rights reserved. - * - * Programmer: Robb Matzke <robb@arborea.spizella.com> - * Tuesday, January 13, 1998 - * - * Purpose: Data type conversions. + * Module Info: Data type conversions for the H5T interface. */ + #define H5T_PACKAGE /*suppress error about including H5Tpkg */ -#define PABLO_MASK H5Tconv_mask -#include "H5Iprivate.h" -#include "H5Eprivate.h" +#include "H5private.h" /*generic functions */ +#include "H5Eprivate.h" /*error handling */ #include "H5FLprivate.h" /*Free Lists */ -#include "H5MMprivate.h" -#include "H5Pprivate.h" -#include "H5Tpkg.h" +#include "H5Iprivate.h" /*ID functions */ +#include "H5MMprivate.h" /*memory management */ +#include "H5Pprivate.h" /* Property Lists */ +#include "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tconv_mask /* Conversion data for H5T_conv_struct() */ typedef struct H5T_conv_struct_t { diff --git a/src/H5Tcset.c b/src/H5Tcset.c new file mode 100644 index 0000000..0ddfe23 --- /dev/null +++ b/src/H5Tcset.c @@ -0,0 +1,159 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the character set (cset) for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tcset_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_cset_interface +static herr_t H5T_init_cset_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_cset_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_cset_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_cset_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_cset_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_cset_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_cset + * + * Purpose: HDF5 is able to distinguish between character sets of + * different nationalities and to convert between them to the + * extent possible. + * + * Return: Success: The character set of an H5T_STRING type. + * + * Failure: H5T_CSET_ERROR (Negative) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +H5T_cset_t +H5Tget_cset(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_cset_t ret_value; + + FUNC_ENTER_API(H5Tget_cset, H5T_CSET_ERROR); + H5TRACE1("Tc","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR, "not a data type"); + /* Don't see any reason for this. Causes problem for variable-length + * string. -SLU (& QAK) */ + /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ + if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_CSET_ERROR, "operation not defined for data type class"); + + /* result */ + if(H5T_STRING == dt->type) + ret_value = dt->u.atomic.u.s.cset; + else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) + ret_value = dt->u.vlen.cset; + else + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_CSET_ERROR, "can't get cset info"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_cset + * + * Purpose: HDF5 is able to distinguish between character sets of + * different nationalities and to convert between them to the + * extent possible. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_cset(hid_t type_id, H5T_cset_t cset) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_cset, FAIL); + H5TRACE2("e","iTc",type_id,cset); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (cset < 0 || cset >= H5T_NCSET) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal character set type"); + /* Don't see any reason for this. Causes problem for variable-length + * string. -SLU (& QAK) */ + /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ + if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + if(H5T_STRING == dt->type) + dt->u.atomic.u.s.cset = cset; + else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) + dt->u.vlen.cset = cset; + else + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't set cset info"); + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tenum.c b/src/H5Tenum.c new file mode 100644 index 0000000..dcd7ff7 --- /dev/null +++ b/src/H5Tenum.c @@ -0,0 +1,582 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for enumerated datatypes + * in the H5T interface. + */ + +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ + +#include "H5private.h" /*generic functions */ +#include "H5Eprivate.h" /*error handling */ +#include "H5FLprivate.h" /*Free Lists */ +#include "H5Iprivate.h" /*ID functions */ +#include "H5MMprivate.h" /*memory management */ +#include "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tenum_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_enum_interface +static herr_t H5T_init_enum_interface(void); + +/* Declare extern the free list for H5T_t's */ +H5FL_EXTERN(H5T_t); + +/* Static local functions */ +static char *H5T_enum_nameof(H5T_t *dt, void *value, char *name/*out*/, + size_t size); +static herr_t H5T_enum_valueof(H5T_t *dt, const char *name, + void *value/*out*/); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_enum_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_enum_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_enum_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_enum_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_enum_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tenum_create + * + * Purpose: Create a new enumeration data type based on the specified + * TYPE, which must be an integer type. + * + * Return: Success: ID of new enumeration data type + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Tuesday, December 22, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tenum_create(hid_t parent_id) +{ + H5T_t *parent = NULL; /*base integer data type */ + H5T_t *dt = NULL; /*new enumeration data type */ + hid_t ret_value; /*return value */ + + FUNC_ENTER_API(H5Tenum_create, FAIL); + H5TRACE1("i","i",parent_id); + + /* Check args */ + if (NULL==(parent=H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_INTEGER!=parent->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type"); + + /* Build new type */ + if((dt=H5T_enum_create(parent))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "cannot create enum type"); + /* Atomize the type */ + if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type atom"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_enum_create + * + * Purpose: Private function for H5Tenum_create. Create a new + * enumeration data type based on the specified + * TYPE, which must be an integer type. + * + * Return: Success: new enumeration data type + * + * Failure: NULL + * + * Programmer: Raymond Lu + * October 9, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5T_enum_create(H5T_t *parent) +{ + H5T_t *ret_value; /*new enumeration data type */ + + FUNC_ENTER_NOAPI(H5T_enum_create, NULL); + + assert(parent); + + /* Build new type */ + if (NULL==(ret_value = H5FL_CALLOC(H5T_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + ret_value->type = H5T_ENUM; + ret_value->parent = H5T_copy(parent, H5T_COPY_ALL); + assert(ret_value->parent); + ret_value->size = ret_value->parent->size; + ret_value->ent.header = HADDR_UNDEF; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tenum_insert + * + * Purpose: Insert a new enumeration data type member into an enumeration + * type. TYPE is the enumeration type, NAME is the name of the + * new member, and VALUE points to the value of the new member. + * The NAME and VALUE must both be unique within the TYPE. VALUE + * points to data which is of the data type defined when the + * enumeration type was created. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tenum_insert(hid_t type, const char *name, void *value) +{ + H5T_t *dt=NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tenum_insert, FAIL); + H5TRACE3("e","isx",type,name,value); + + /* Check args */ + if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_ENUM!=dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + if (!value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value specified"); + + /* Do work */ + if (H5T_enum_insert(dt, name, value)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert new enumeration member"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_enum_insert + * + * Purpose: Insert a new member having a NAME and VALUE into an + * enumeration data TYPE. The NAME and VALUE must both be + * unique. The VALUE points to data of the data type defined for + * the enumeration base type. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_enum_insert(H5T_t *dt, const char *name, void *value) +{ + int i; + char **names=NULL; + uint8_t *values=NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_enum_insert, FAIL); + + assert(dt); + assert(name && *name); + assert(value); + + /* The name and value had better not already exist */ + for (i=0; i<dt->u.enumer.nmembs; i++) { + if (!HDstrcmp(dt->u.enumer.name[i], name)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "name redefinition"); + if (!HDmemcmp(dt->u.enumer.value+i*dt->size, value, dt->size)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "value redefinition"); + } + + /* Increase table sizes */ + if (dt->u.enumer.nmembs >= dt->u.enumer.nalloc) { + int n = MAX(32, 2*dt->u.enumer.nalloc); + if (NULL==(names=H5MM_realloc(dt->u.enumer.name, n*sizeof(char*)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + dt->u.enumer.name = names; + + if (NULL==(values=H5MM_realloc(dt->u.enumer.value, n*dt->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + dt->u.enumer.value = values; + dt->u.enumer.nalloc = n; + } + + /* Insert new member at end of member arrays */ + dt->u.enumer.sorted = H5T_SORT_NONE; + i = dt->u.enumer.nmembs++; + dt->u.enumer.name[i] = H5MM_xstrdup(name); + HDmemcpy(dt->u.enumer.value+i*dt->size, value, dt->size); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_value + * + * Purpose: Return the value for an enumeration data type member. + * + * Return: Success: non-negative with the member value copied + * into the memory pointed to by VALUE. + * + * Failure: negative, VALUE memory is undefined. + * + * Programmer: Robb Matzke + * Wednesday, December 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_member_value(hid_t type, int membno, void *value/*out*/) +{ + H5T_t *dt=NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tget_member_value, FAIL); + H5TRACE3("e","iIsx",type,membno,value); + + if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_ENUM!=dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + if (membno<0 || membno>=dt->u.enumer.nmembs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); + if (!value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null value buffer"); + + if (H5T_get_member_value(dt, membno, value)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get member value"); +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_member_value + * + * Purpose: Private function for H5T_get_member_value. Return the + * value for an enumeration data type member. + * + * Return: Success: non-negative with the member value copied + * into the memory pointed to by VALUE. + * + * Failure: negative, VALUE memory is undefined. + * + * Programmer: Raymond Lu + * October 9, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_get_member_value(H5T_t *dt, int membno, void *value/*out*/) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_get_member_value, FAIL); + + assert(dt); + assert(value); + + HDmemcpy(value, dt->u.enumer.value + membno*dt->size, dt->size); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + + +/*------------------------------------------------------------------------- + * Function: H5Tenum_nameof + * + * Purpose: Finds the symbol name that corresponds to the specified VALUE + * of an enumeration data type TYPE. At most SIZE characters of + * the symbol name are copied into the NAME buffer. If the + * entire symbol anem and null terminator do not fit in the NAME + * buffer then as many characters as possible are copied (not + * null terminated) and the function fails. + * + * Return: Success: Non-negative. + * + * Failure: Negative, first character of NAME is set to + * null if SIZE allows it. + * + * Programmer: Robb Matzke + * Monday, January 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tenum_nameof(hid_t type, void *value, char *name/*out*/, size_t size) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tenum_nameof, FAIL); + H5TRACE4("e","ixxz",type,value,name,size); + + /* Check args */ + if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_ENUM!=dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); + if (!value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value supplied"); + if (!name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name buffer supplied"); + + if (NULL==H5T_enum_nameof(dt, value, name, size)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "nameof query failed"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_enum_nameof + * + * Purpose: Finds the symbol name that corresponds the the specified + * VALUE of an enumeration data type DT. At most SIZE characters + * of the symbol name are copied into the NAME buffer. If the + * entire symbol name and null terminator do not fit in the NAME + * buffer then as many characters as possible are copied and the + * function returns failure. + * + * If NAME is the null pointer and SIZE is zero then enough + * space is allocated to hold the result and a pointer to that + * memory is returned. + * + * Return: Success: Pointer to NAME + * + * Failure: NULL, name[0] is set to null. + * + * Programmer: Robb Matzke + * Monday, January 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static char * +H5T_enum_nameof(H5T_t *dt, void *value, char *name/*out*/, size_t size) +{ + int lt, md, rt; /*indices for binary search */ + int cmp=(-1); /*comparison result */ + char *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_enum_nameof, NULL); + + /* Check args */ + assert(dt && H5T_ENUM==dt->type); + assert(value); + assert(name || 0==size); + if (name && size>0) *name = '\0'; + + /* Sanity check */ + if (dt->u.enumer.nmembs == 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "datatype has no members"); + + /* Do a binary search over the values to find the correct one */ + H5T_sort_value(dt, NULL); + lt = 0; + rt = dt->u.enumer.nmembs; + md = -1; + + while (lt<rt) { + md = (lt+rt)/2; + cmp = HDmemcmp(value, dt->u.enumer.value+md*dt->size, dt->size); + if (cmp<0) { + rt = md; + } else if (cmp>0) { + lt = md+1; + } else { + break; + } + } + /* Value was not yet defined. This fixes bug # 774, 2002/06/05 EIP */ + if (cmp!=0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "value is currently not defined"); + + /* Save result name */ + if (!name && NULL==(name=H5MM_malloc(HDstrlen(dt->u.enumer.name[md])+1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDstrncpy(name, dt->u.enumer.name[md], size); + if (HDstrlen(dt->u.enumer.name[md])>=size) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, NULL, "name has been truncated"); + + /* Set return value */ + ret_value=name; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tenum_valueof + * + * Purpose: Finds the value that corresponds to the specified NAME f an + * enumeration TYPE. The VALUE argument should be at least as + * large as the value of H5Tget_size(type) in order to hold the + * result. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, January 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tenum_valueof, FAIL); + H5TRACE3("e","isx",type,name,value); + + /* Check args */ + if (NULL==(dt=H5I_object_verify(type,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_ENUM!=dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an enumeration data type"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + if (!value) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no value buffer"); + + if (H5T_enum_valueof(dt, name, value)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "valueof query failed"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_enum_valueof + * + * Purpose: Finds the value that corresponds the the specified symbol + * NAME of an enumeration data type DT and copy it to the VALUE + * result buffer. The VALUE should be allocated by the caller to + * be large enough for the result. + * + * Return: Success: Non-negative, value stored in VALUE. + * + * Failure: Negative, VALUE is undefined. + * + * Programmer: Robb Matzke + * Monday, January 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/) +{ + int lt, md, rt; /*indices for binary search */ + int cmp=(-1); /*comparison result */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_enum_valueof, FAIL); + + /* Check args */ + assert(dt && H5T_ENUM==dt->type); + assert(name && *name); + assert(value); + + /* Sanity check */ + if (dt->u.enumer.nmembs == 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "datatype has no members"); + + /* Do a binary search over the names to find the correct one */ + H5T_sort_name(dt, NULL); + lt = 0; + rt = dt->u.enumer.nmembs; + md = -1; + + while (lt<rt) { + md = (lt+rt)/2; + cmp = HDstrcmp(name, dt->u.enumer.name[md]); + if (cmp<0) { + rt = md; + } else if (cmp>0) { + lt = md+1; + } else { + break; + } + } + /* Value was not yet defined. This fixes bug # 774, 2002/06/05 EIP */ + if (cmp!=0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "string doesn't exist in the enumeration type"); + + HDmemcpy(value, dt->u.enumer.value+md*dt->size, dt->size); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + 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); +} + diff --git a/src/H5Tfixed.c b/src/H5Tfixed.c new file mode 100644 index 0000000..fbcc1b0 --- /dev/null +++ b/src/H5Tfixed.c @@ -0,0 +1,182 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for fixed-point (i.e. + * integer) 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tfixed_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_fixed_interface +static herr_t H5T_init_fixed_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_fixed_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_fixed_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_fixed_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_fixed_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_fixed_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_sign + * + * Purpose: Retrieves the sign type for an integer type. + * + * Return: Success: The sign type. + * + * Failure: H5T_SGN_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + *------------------------------------------------------------------------- + */ +H5T_sign_t +H5Tget_sign(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_sign_t ret_value; + + FUNC_ENTER_API(H5Tget_sign, H5T_SGN_ERROR); + H5TRACE1("Ts","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_SGN_ERROR, "not an integer data type"); + + ret_value = H5T_get_sign(dt); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_sign + * + * Purpose: Private function for H5Tget_sign. Retrieves the sign type + * for an integer type. + * + * Return: Success: The sign type. + * + * Failure: H5T_SGN_ERROR (Negative) + * + * Programmer: Raymond Lu + * October 8, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_sign_t +H5T_get_sign(H5T_t *dt) +{ + H5T_sign_t ret_value; + + FUNC_ENTER_NOAPI(H5T_get_sign, H5T_SGN_ERROR); + + assert(dt); + + /* Defer to parent */ + while(dt->parent) + dt = dt->parent; + + /* Check args */ + if (H5T_INTEGER!=dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_SGN_ERROR, "operation not defined for data type class"); + + /* Sign */ + ret_value = dt->u.atomic.u.i.sign; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + + +/*------------------------------------------------------------------------- + * Function: H5Tset_sign + * + * Purpose: Sets the sign property for an integer. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_sign(hid_t type_id, H5T_sign_t sign) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_sign, FAIL); + H5TRACE2("e","iTs",type_id,sign); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (sign < 0 || sign >= H5T_NSGN) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type"); + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_INTEGER!=dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + dt->u.atomic.u.i.sign = sign; + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tfloat.c b/src/H5Tfloat.c new file mode 100644 index 0000000..a0ecac1 --- /dev/null +++ b/src/H5Tfloat.c @@ -0,0 +1,447 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for floating-point + * 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tfloat_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_float_interface +static herr_t H5T_init_float_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_float_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_float_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_float_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_float_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_float_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_fields + * + * Purpose: Returns information about the locations of the various bit + * fields of a floating point data type. The field positions + * are bit positions in the significant region of the data type. + * Bits are numbered with the least significant bit number zero. + * + * Any (or even all) of the arguments can be null pointers. + * + * Return: Success: Non-negative, field locations and sizes are + * returned through the arguments. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_fields(hid_t type_id, size_t *spos/*out*/, + size_t *epos/*out*/, size_t *esize/*out*/, + size_t *mpos/*out*/, size_t *msize/*out*/) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tget_fields, FAIL); + H5TRACE6("e","ixxxxx",type_id,spos,epos,esize,mpos,msize); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Get values */ + if (spos) *spos = dt->u.atomic.u.f.sign; + if (epos) *epos = dt->u.atomic.u.f.epos; + if (esize) *esize = dt->u.atomic.u.f.esize; + if (mpos) *mpos = dt->u.atomic.u.f.mpos; + if (msize) *msize = dt->u.atomic.u.f.msize; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_fields + * + * Purpose: Sets the locations and sizes of the various floating point + * bit fields. The field positions are bit positions in the + * significant region of the data type. Bits are numbered with + * the least significant bit number zero. + * + * Fields are not allowed to extend beyond the number of bits of + * precision, nor are they allowed to overlap with one another. + * + * 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 data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize, + size_t mpos, size_t msize) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_fields, FAIL); + H5TRACE6("e","izzzzz",type_id,spos,epos,esize,mpos,msize); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + if (epos + esize > dt->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent bit field size/location is invalid"); + if (mpos + msize > dt->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mantissa bit field size/location is invalid"); + if (spos >= dt->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign location is not valid"); + + /* Check for overlap */ + if (spos >= epos && spos < epos + esize) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within exponent field"); + if (spos >= mpos && spos < mpos + msize) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within mantissa field"); + if ((mpos < epos && mpos + msize > epos) || + (epos < mpos && epos + esize > mpos)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent and mantissa fields overlap"); + + /* Commit */ + dt->u.atomic.u.f.sign = spos; + dt->u.atomic.u.f.epos = epos; + dt->u.atomic.u.f.mpos = mpos; + dt->u.atomic.u.f.esize = esize; + dt->u.atomic.u.f.msize = msize; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_ebias + * + * Purpose: Retrieves the exponent bias of a floating-point type. + * + * Return: Success: The bias + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + *------------------------------------------------------------------------- + */ +size_t +H5Tget_ebias(hid_t type_id) +{ + H5T_t *dt = NULL; + size_t ret_value; + + FUNC_ENTER_API(H5Tget_ebias, 0); + H5TRACE1("z","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for data type class"); + + /* bias */ + H5_ASSIGN_OVERFLOW(ret_value,dt->u.atomic.u.f.ebias,uint64_t,size_t); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_ebias + * + * Purpose: Sets the exponent bias of a floating-point type. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_ebias(hid_t type_id, size_t ebias) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_ebias, FAIL); + H5TRACE2("e","iz",type_id,ebias); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + dt->u.atomic.u.f.ebias = ebias; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_norm + * + * Purpose: Returns the mantisssa normalization of a floating-point data + * type. + * + * Return: Success: Normalization ID + * + * Failure: H5T_NORM_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +H5T_norm_t +H5Tget_norm(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_norm_t ret_value; + + FUNC_ENTER_API(H5Tget_norm, H5T_NORM_ERROR); + H5TRACE1("Tn","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_NORM_ERROR, "operation not defined for data type class"); + + /* norm */ + ret_value = dt->u.atomic.u.f.norm; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_norm + * + * Purpose: Sets the mantissa normalization method for a floating point + * data type. + * + * 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 data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_norm(hid_t type_id, H5T_norm_t norm) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_norm, FAIL); + H5TRACE2("e","iTn",type_id,norm); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (norm < 0 || norm > H5T_NORM_NONE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + dt->u.atomic.u.f.norm = norm; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_inpad + * + * Purpose: If any internal bits of a floating point type are unused + * (that is, those significant bits which are not part of the + * sign, exponent, or mantissa) then they will be filled + * according to the value of this property. + * + * Return: Success: The internal padding type. + * + * Failure: H5T_PAD_ERROR (Negative) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +H5T_pad_t +H5Tget_inpad(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_pad_t ret_value; + + FUNC_ENTER_API(H5Tget_inpad, H5T_PAD_ERROR); + H5TRACE1("Tp","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_PAD_ERROR, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_PAD_ERROR, "operation not defined for data type class"); + + /* pad */ + ret_value = dt->u.atomic.u.f.pad; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_inpad + * + * Purpose: If any internal bits of a floating point type are unused + * (that is, those significant bits which are not part of the + * sign, exponent, or mantissa) then they will be filled + * according to the value of this property. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_inpad(hid_t type_id, H5T_pad_t pad) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_inpad, FAIL); + H5TRACE2("e","iTp",type_id,pad); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (pad < 0 || pad >= H5T_NPAD) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal internal pad type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_FLOAT != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + dt->u.atomic.u.f.pad = pad; + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tnative.c b/src/H5Tnative.c new file mode 100644 index 0000000..fab2014 --- /dev/null +++ b/src/H5Tnative.c @@ -0,0 +1,761 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for querying + * a "native" datatype for 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 H5Tnative_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_native_interface +static herr_t H5T_init_native_interface(void); + +/* Static local functions */ +static H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction, + size_t *struct_align, size_t *offset, size_t *comp_size); +static H5T_t *H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t direction, + size_t *struct_align, size_t *offset, size_t *comp_size); +static H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction, + size_t *struct_align, size_t *offset, size_t *comp_size); +static herr_t H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, + size_t nelems, size_t align, size_t *struct_align); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_native_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_native_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_native_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_native_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_native_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_native_type + * + * Purpose: High-level API to return the native type of a datatype. + * The native type is chosen by matching the size and class of + * querried datatype from the following native premitive + * datatypes: + * H5T_NATIVE_CHAR H5T_NATIVE_UCHAR + * H5T_NATIVE_SHORT H5T_NATIVE_USHORT + * H5T_NATIVE_INT H5T_NATIVE_UINT + * H5T_NATIVE_LONG H5T_NATIVE_ULONG + * H5T_NATIVE_LLONG H5T_NATIVE_ULLONG + * + * H5T_NATIVE_FLOAT + * H5T_NATIVE_DOUBLE + * H5T_NATIVE_LDOUBLE + * + * Compound, array, enum, and VL types all choose among these + * types for theire members. Time, Bifield, Opaque, Reference + * types are only copy out. + * + * Return: Success: Returns the native data type if successful. + * + * Failure: negative + * + * Programmer: Raymond Lu + * Oct 3, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tget_native_type(hid_t type_id, H5T_direction_t direction) +{ + H5T_t *dt; /* Datatype to create native datatype from */ + H5T_t *new_dt=NULL; /* Datatype for native datatype created */ + size_t comp_size=0; /* Compound datatype's size */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Tget_native_type, FAIL); + H5TRACE1("z","i",type_id); + + /* check argument */ + if(NULL==(dt=H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + + if(direction!=H5T_DIR_DEFAULT && direction!=H5T_DIR_ASCEND + && direction!=H5T_DIR_DESCEND) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not valid direction value"); + + if((new_dt = H5T_get_native_type(dt, direction, NULL, NULL, &comp_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type"); + + if((ret_value=H5I_register(H5I_DATATYPE, new_dt)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type"); + +done: + /* Error cleanup */ + if(ret_value<0) { + if(new_dt) + H5T_close(new_dt); + } /* end if */ + + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_native_type + * + * Purpose: Returns the native type of a datatype. + * + * Return: Success: Returns the native data type if successful. + * + * Failure: negative + * + * Programmer: Raymond Lu + * Oct 3, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_t* +H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) +{ + H5T_t *dt; /* Datatype to make native */ + H5T_class_t h5_class; /* Class of datatype to make native */ + size_t size; /* Size of datatype to make native */ + int nmemb; /* Number of members in compound & enum types */ + H5T_t *super_type; /* Super type of VL, array and enum datatypes */ + H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ + H5T_t *new_type=NULL; /* New native datatype */ + int i; /* Local index variable */ + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_get_native_type, NULL); + + assert(dtype); + + if((h5_class = H5T_get_class(dtype))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class"); + + if((size = H5T_get_size(dtype))==0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size"); + + switch(h5_class) { + case H5T_INTEGER: + { + H5T_sign_t sign; /* Signedness of integer type */ + + if((sign = H5T_get_sign(dtype))==H5T_SGN_ERROR) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid signess"); + + if((ret_value = H5T_get_native_integer(size, sign, direction, struct_align, offset, comp_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer type"); + } + break; + + case H5T_FLOAT: + if((ret_value = H5T_get_native_float(size, direction, struct_align, offset, comp_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + + break; + + case H5T_STRING: + { + size_t align; + size_t pointer_size; + + if(H5T_is_variable_str(dtype)) { + if(NULL==(dt=H5I_object(H5T_C_S1))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + if(H5T_set_size(ret_value, H5T_VARIABLE)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot set size"); + + /* Update size, offset and compound alignment for parent. */ + align = H5T_POINTER_COMP_ALIGN_g; + pointer_size = sizeof(char*); + + if(H5T_cmp_offset(comp_size, offset, pointer_size, 1, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + + } else { + /*size_t char_size;*/ + + if(NULL==(dt=H5I_object(H5T_NATIVE_UCHAR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + if(H5T_set_size(ret_value, size)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot set size"); + + /* Update size, offset and compound alignment for parent. */ + align = H5T_NATIVE_SCHAR_COMP_ALIGN_g; + + if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + + } + } + break; + + /* These three types don't need to compute compound field information since they + * can't be used as field. */ + case H5T_TIME: + case H5T_BITFIELD: + case H5T_OPAQUE: + if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + + break; + case H5T_REFERENCE: + { + size_t align; + size_t ref_size; + int not_equal; + + if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + + /* Decide if the data type is object or dataset region reference. */ + if(NULL==(dt=H5I_object(H5T_STD_REF_OBJ_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + not_equal = H5T_cmp(ret_value, dt); + + /* Update size, offset and compound alignment for parent. */ + if(!not_equal) { + align = H5T_HOBJREF_COMP_ALIGN_g; + ref_size = sizeof(hobj_ref_t); + } else { + align = H5T_HDSETREGREF_COMP_ALIGN_g; + ref_size = sizeof(hdset_reg_ref_t); + } + + if(H5T_cmp_offset(comp_size, offset, ref_size, 1, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + } + break; + + case H5T_COMPOUND: + { + H5T_t *memb_type; /* Datatype of member */ + H5T_t **memb_list; /* List of compound member IDs */ + size_t *memb_offset; /* List of member offsets in compound type, including member size and alignment */ + size_t children_size=0;/* Total size of compound members */ + size_t children_st_align=0; /* The max alignment among compound members. This'll be the compound alignment */ + char **comp_mname; /* List of member names in compound type */ + + if((nmemb = H5T_get_nmembers(dtype))<=0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "compound data type doesn't have any member"); + + if((memb_list = (H5T_t**)H5MM_malloc(nmemb*sizeof(H5T_t*)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + if((memb_offset = (size_t*)H5MM_calloc(nmemb*sizeof(size_t)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + if((comp_mname = (char**)H5MM_malloc(nmemb*sizeof(char*)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + + /* Construct child compound type and retrieve a list of their IDs, offsets, total size, and alignment for compound type. */ + for(i=0; i<nmemb; i++) { + if((memb_type = H5T_get_member_type(dtype, i))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed"); + + if((comp_mname[i] = H5T_get_member_name(dtype, i))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed"); + + if((memb_list[i] = H5T_get_native_type(memb_type, direction, &children_st_align, &(memb_offset[i]), &children_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member identifier retrieval failed"); + + if(H5T_close(memb_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + } + + /* The alignment for whole compound type */ + if(children_st_align && children_size % children_st_align) { + memb_offset[nmemb-1] += children_size % children_st_align; + children_size += children_size % children_st_align; + } + + /* Construct new compound type based on native type */ + if((new_type=H5T_create(H5T_COMPOUND, children_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot create a compound type"); + + /* Insert members for the new compound type */ + for(i=0; i<nmemb; i++) { + if(H5T_insert(new_type, comp_mname[i], memb_offset[i], memb_list[i])<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member to compound datatype"); + } + + /* Update size, offset and compound alignment for parent. */ + if(offset) + *offset = *comp_size; + if(struct_align && *struct_align < children_st_align) + *struct_align = children_st_align; + *comp_size += children_size; + + /* Close member data type */ + for(i=0; i<nmemb; i++) { + if(H5T_close(memb_list[i])<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + /* Free member names in list */ + H5MM_xfree(comp_mname[i]); + } + + /* Free lists for members */ + H5MM_xfree(memb_list); + H5MM_xfree(memb_offset); + H5MM_xfree(comp_mname); + + ret_value = new_type; + } + break; + + case H5T_ENUM: + { + char *memb_name; /* Enum's member name */ + void *memb_value; /* Enum's member value */ + + /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer. */ + + /* Retrieve base type for enumarate type */ + if((super_type=H5T_get_super(dtype))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get base type for enumarate type"); + if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed"); + + /* Allocate room for the enum values */ + if((memb_value = H5MM_malloc(H5T_get_size(super_type)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + + /* Close super type */ + if(H5T_close(super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + /* Construct new enum type based on native type */ + if((new_type=H5T_enum_create(nat_super_type))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type"); + + /* Retrieve member info and insert members into new enum type */ + if((nmemb = H5T_get_nmembers(dtype))<=0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "enumarate data type doesn't have any member"); + for(i=0; i<nmemb; i++) { + if((memb_name=H5T_get_member_name(dtype, i))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name"); + if(H5T_get_member_value(dtype, i, memb_value)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value"); + if(H5T_enum_insert(new_type, memb_name, memb_value)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member"); + H5MM_xfree(memb_name); + } + H5MM_xfree(memb_value); + + /* Close base type */ + if(H5T_close(nat_super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + ret_value = new_type; + } + break; + + case H5T_ARRAY: + { + int array_rank; /* Array's rank */ + hsize_t *dims = NULL; /* Dimension sizes for array */ + hsize_t nelems = 1; + size_t super_offset=0; + size_t super_size=0; + size_t super_align=0; + + /* Retrieve dimension information for array data type */ + if((array_rank=H5T_get_array_ndims(dtype))<=0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension rank"); + if((dims = (hsize_t*)H5MM_malloc(array_rank*sizeof(hsize_t)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + if(H5T_get_array_dims(dtype, dims, NULL)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension size"); + + /* Retrieve base type for array type */ + if((super_type=H5T_get_super(dtype))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for enumarate type"); + if((nat_super_type = H5T_get_native_type(super_type, direction, &super_align, + &super_offset, &super_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed"); + + /* Close super type */ + if(H5T_close(super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + /* Create a new array type based on native type */ + if((new_type=H5T_array_create(nat_super_type, array_rank, dims, NULL))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create array type"); + + /* Close base type */ + if(H5T_close(nat_super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + for(i=0; i<array_rank; i++) + nelems *= dims[i]; + H5_CHECK_OVERFLOW(nelems,hsize_t,size_t); + if(H5T_cmp_offset(comp_size, offset, super_size, (size_t)nelems, super_align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + + H5MM_xfree(dims); + ret_value = new_type; + } + break; + + case H5T_VLEN: + { + size_t vl_align = 0; + size_t vl_size = 0; + size_t super_size=0; + + /* Retrieve base type for array type */ + if((super_type=H5T_get_super(dtype))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for enumarate type"); + /* Don't need alignment, offset information if this VL isn't a field of compound type. If it + * is, go to a few steps below to compute the information directly. */ + if((nat_super_type = H5T_get_native_type(super_type, direction, NULL, NULL, &super_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed"); + + /* Close super type */ + if(H5T_close(super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + /* Create a new array type based on native type */ + if((new_type=H5T_vlen_create(nat_super_type))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create VL type"); + + /* Close base type */ + if(H5T_close(nat_super_type)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); + + /* Update size, offset and compound alignment for parent compound type directly. */ + vl_align = H5T_HVL_COMP_ALIGN_g; + vl_size = sizeof(hvl_t); + + if(H5T_cmp_offset(comp_size, offset, vl_size, 1, vl_align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + + ret_value = new_type; + } + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "data type doesn't match any native type"); + } + +done: + /* Error cleanup */ + if(ret_value==NULL) { + if(new_type) + H5T_close(new_type); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_native_integer + * + * Purpose: Returns the native integer type of a datatype. + * + * Return: Success: Returns the native data type if successful. + * + * Failure: negative + * + * Programmer: Raymond Lu + * Oct 3, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_t* +H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t direction, + size_t *struct_align, size_t *offset, size_t *comp_size) +{ + H5T_t *dt; /* Appropriate native datatype to copy */ + hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ + size_t align=0; /* Alignment necessary for native datatype */ + enum match_type { /* The different kinds of integers we can match */ + H5T_NATIVE_INT_MATCH_CHAR, + H5T_NATIVE_INT_MATCH_SHORT, + H5T_NATIVE_INT_MATCH_INT, + H5T_NATIVE_INT_MATCH_LONG, + H5T_NATIVE_INT_MATCH_LLONG, + H5T_NATIVE_INT_MATCH_UNKNOWN + } match=H5T_NATIVE_INT_MATCH_UNKNOWN; + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); + + assert(size>0); + + if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { + if(size==sizeof(char)) + match=H5T_NATIVE_INT_MATCH_CHAR; + else if(size==sizeof(short)) + match=H5T_NATIVE_INT_MATCH_SHORT; + else if(size==sizeof(int)) + match=H5T_NATIVE_INT_MATCH_INT; + else if(size==sizeof(long)) + match=H5T_NATIVE_INT_MATCH_LONG; + else if(size==sizeof(long_long)) + match=H5T_NATIVE_INT_MATCH_LLONG; + else /* If no native type matches the querried datatype, simply choose the type of biggest size. */ + match=H5T_NATIVE_INT_MATCH_LLONG; + } else if(direction == H5T_DIR_DESCEND) { + if(size==sizeof(long_long)) + match=H5T_NATIVE_INT_MATCH_LLONG; + else if(size==sizeof(long)) + match=H5T_NATIVE_INT_MATCH_LONG; + else if(size==sizeof(int)) + match=H5T_NATIVE_INT_MATCH_INT; + else if(size==sizeof(short)) + match=H5T_NATIVE_INT_MATCH_SHORT; + else if(size==sizeof(char)) + match=H5T_NATIVE_INT_MATCH_CHAR; + else /* If no native type matches the querried datatype, simple choose the type of smallest size. */ + match=H5T_NATIVE_INT_MATCH_CHAR; + } + + /* Set the appropriate native datatype information */ + switch(match) { + case H5T_NATIVE_INT_MATCH_CHAR: + if(sign==H5T_SGN_2) + tid = H5T_NATIVE_SCHAR; + else + tid = H5T_NATIVE_UCHAR; + + align = H5T_NATIVE_SCHAR_COMP_ALIGN_g; + break; + + case H5T_NATIVE_INT_MATCH_SHORT: + if(sign==H5T_SGN_2) + tid = H5T_NATIVE_SHORT; + else + tid = H5T_NATIVE_USHORT; + + align = H5T_NATIVE_SHORT_COMP_ALIGN_g; + break; + + case H5T_NATIVE_INT_MATCH_INT: + if(sign==H5T_SGN_2) + tid = H5T_NATIVE_INT; + else + tid = H5T_NATIVE_UINT; + + align = H5T_NATIVE_INT_COMP_ALIGN_g; + break; + + case H5T_NATIVE_INT_MATCH_LONG: + if(sign==H5T_SGN_2) + tid = H5T_NATIVE_LONG; + else + tid = H5T_NATIVE_ULONG; + + align = H5T_NATIVE_LONG_COMP_ALIGN_g; + break; + + case H5T_NATIVE_INT_MATCH_LLONG: + if(sign==H5T_SGN_2) + tid = H5T_NATIVE_LLONG; + else + tid = H5T_NATIVE_ULLONG; + + align = H5T_NATIVE_LLONG_COMP_ALIGN_g; + break; + + default: + assert(0 && "Unknown native integer match!"); + break; + } /* end switch */ + + /* Create new native type */ + assert(tid>=0); + if(NULL==(dt=H5I_object(tid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + + /* compute size and offset of compound type member. */ + if(H5T_cmp_offset(comp_size, offset, size, 1, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_get_native_float + * + * Purpose: Returns the native floatt type of a datatype. + * + * Return: Success: Returns the native data type if successful. + * + * Failure: negative + * + * Programmer: Raymond Lu + * Oct 3, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_t* +H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) +{ + H5T_t *dt=NULL; /* Appropriate native datatype to copy */ + hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ + size_t align=0; /* Alignment necessary for native datatype */ + enum match_type { /* The different kinds of floating point types we can match */ + H5T_NATIVE_FLOAT_MATCH_FLOAT, + H5T_NATIVE_FLOAT_MATCH_DOUBLE, + H5T_NATIVE_FLOAT_MATCH_LDOUBLE, + H5T_NATIVE_FLOAT_MATCH_UNKNOWN + } match=H5T_NATIVE_FLOAT_MATCH_UNKNOWN; + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); + + assert(size>0); + + if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { + if(size==sizeof(float)) + match=H5T_NATIVE_FLOAT_MATCH_FLOAT; + else if(size==sizeof(double)) + match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; + else if(size==sizeof(long double)) + match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; + else /* If not match, return the biggest datatype */ + match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; + } else { + if(size==sizeof(long double)) + match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; + else if(size==sizeof(double)) + match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; + else if(size==sizeof(float)) + match=H5T_NATIVE_FLOAT_MATCH_FLOAT; + else + match=H5T_NATIVE_FLOAT_MATCH_FLOAT; + } + + /* Set the appropriate native floating point information */ + switch(match) { + case H5T_NATIVE_FLOAT_MATCH_FLOAT: + tid = H5T_NATIVE_FLOAT; + align = H5T_NATIVE_FLOAT_COMP_ALIGN_g; + break; + + case H5T_NATIVE_FLOAT_MATCH_DOUBLE: + tid = H5T_NATIVE_DOUBLE; + align = H5T_NATIVE_DOUBLE_COMP_ALIGN_g; + break; + + case H5T_NATIVE_FLOAT_MATCH_LDOUBLE: + tid = H5T_NATIVE_LDOUBLE; + align = H5T_NATIVE_LDOUBLE_COMP_ALIGN_g; + break; + + default: + assert(0 && "Unknown native floating-point match!"); + break; + } /* end switch */ + + /* Create new native type */ + assert(tid>=0); + if(NULL==(dt=H5I_object(tid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); + + /* compute offset of compound type member. */ + if(H5T_cmp_offset(comp_size, offset, size, 1, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_cmp_offset + * + * Purpose: This function is only for convenience. It computes the + * compound type size, offset of the member being considered + * and the alignment for the whole compound type. + * + * Return: Success: Non-negative value. + * + * Failure: Negative value. + * + * Programmer: Raymond Lu + * December 10, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, + size_t nelems, size_t align, size_t *struct_align) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5T_cmp_offset, FAIL); + + if(offset && comp_size) { + if(align>1 && *comp_size%align) { + /* Add alignment value */ + *offset = *comp_size + (align - *comp_size%align); + *comp_size += (align - *comp_size%align); + } else + *offset = *comp_size; + + /* compute size of compound type member. */ + *comp_size += nelems*elem_size; + } + + if(struct_align && *struct_align < align) + *struct_align = align; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + diff --git a/src/H5Toffset.c b/src/H5Toffset.c new file mode 100644 index 0000000..63cffea --- /dev/null +++ b/src/H5Toffset.c @@ -0,0 +1,258 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the datatype offset for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Toffset_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_offset_interface +static herr_t H5T_init_offset_interface(void); + +/* Static local functions */ +static herr_t H5T_set_offset(H5T_t *dt, size_t offset); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_offset_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_offset_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_offset_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_offset_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_offset_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_offset + * + * Purpose: Retrieves the bit offset of the first significant bit. The + * signficant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of + * padding. The `offset' property specifies the number of bits + * of padding that appear to the "right of" the value. That is, + * if we have a 32-bit datum with 16-bits of precision having + * the value 0x1122 then it will be layed out in memory as (from + * small byte address toward larger byte addresses): + * + * Big Big Little Little + * Endian Endian Endian Endian + * offset=0 offset=16 offset=0 offset=16 + * + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * + * Return: Success: The offset (non-negative) + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +int +H5Tget_offset(hid_t type_id) +{ + H5T_t *dt = NULL; + int ret_value; + + FUNC_ENTER_API(H5Tget_offset, -1); + 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 an atomic data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); + + /* Offset */ + assert(H5T_is_atomic(dt)); + ret_value = (int)dt->u.atomic.offset; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_offset + * + * Purpose: Sets the bit offset of the first significant bit. The + * signficant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of + * padding. The `offset' property specifies the number of bits + * of padding that appear to the "right of" the value. That is, + * if we have a 32-bit datum with 16-bits of precision having + * the value 0x1122 then it will be layed out in memory as (from + * small byte address toward larger byte addresses): + * + * Big Big Little Little + * Endian Endian Endian Endian + * offset=0 offset=16 offset=0 offset=16 + * + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * + * If the offset is incremented then the total size is + * incremented also if necessary to prevent significant bits of + * the value from hanging over the edge of the data type. + * + * The offset of an H5T_STRING cannot be set to anything but + * zero. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Moved real work to a private function. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_offset(hid_t type_id, size_t offset) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_offset, FAIL); + H5TRACE2("e","iz",type_id,offset); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (H5T_STRING == dt->type && offset != 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset must be zero for this type"); + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); + + /* Do the real work */ + if (H5T_set_offset(dt, offset)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set offset"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_set_offset + * + * Purpose: Sets the bit offset of the first significant bit. The + * signficant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of + * padding. The `offset' property specifies the number of bits + * of padding that appear to the "right of" the value. That is, + * if we have a 32-bit datum with 16-bits of precision having + * the value 0x1122 then it will be layed out in memory as (from + * small byte address toward larger byte addresses): + * + * Big Big Little Little + * Endian Endian Endian Endian + * offset=0 offset=16 offset=0 offset=16 + * + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * + * If the offset is incremented then the total size is + * incremented also if necessary to prevent significant bits of + * the value from hanging over the edge of the data type. + * + * The offset of an H5T_STRING cannot be set to anything but + * zero. + * + * 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 data types. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_set_offset(H5T_t *dt, size_t offset) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_set_offset, FAIL); + + /* Check args */ + assert(dt); + assert(H5T_STRING!=dt->type || 0==offset); + assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs); + + if (dt->parent) { + if (H5T_set_offset(dt->parent, offset)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set offset for base type"); + dt->size = dt->parent->size; + } else { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); + } else if (H5T_ENUM==dt->type) { + /*nothing*/ + } else { + if (offset+dt->u.atomic.prec > 8*dt->size) { + dt->size = (offset + dt->u.atomic.prec + 7) / 8; + } + dt->u.atomic.offset = offset; + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + diff --git a/src/H5Topaque.c b/src/H5Topaque.c new file mode 100644 index 0000000..1d1fec2 --- /dev/null +++ b/src/H5Topaque.c @@ -0,0 +1,139 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for opaque + * 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 H5Topaque_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_opaque_interface +static herr_t H5T_init_opaque_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_opaque_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_opaque_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_opaque_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_opaque_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_opaque_interface() */ + + +/*------------------------------------------------------------------------- + * 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; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_tag, FAIL); + H5TRACE2("e","is",type_id,tag); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (H5T_OPAQUE!=dt->type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an opaque data type"); + if (!tag) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no tag"); + + /* Commit */ + H5MM_xfree(dt->u.opaque.tag); + dt->u.opaque.tag = H5MM_strdup(tag); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * 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; + + FUNC_ENTER_API(H5Tget_tag, 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 (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_OPAQUE != dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "operation not defined for data type class"); + + /* result */ + if (NULL==(ret_value=H5MM_strdup(dt->u.opaque.tag))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Torder.c b/src/H5Torder.c new file mode 100644 index 0000000..4e2f167 --- /dev/null +++ b/src/H5Torder.c @@ -0,0 +1,148 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the datatype byte order for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Torder_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_order_interface +static herr_t H5T_init_order_interface(void); + + +/*-------------------------------------------------------------------------- +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 + Initializes any interface-specific data or routines. (Just calls + H5T_init_iterface currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5T_init_order_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_order_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_order_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_order + * + * Purpose: Returns the byte order of a data type. + * + * Return: Success: A byte order constant + * + * Failure: H5T_ORDER_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +H5T_order_t +H5Tget_order(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_order_t ret_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 data type"); + + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY ==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); + + /* Order */ + assert(H5T_is_atomic(dt)); + ret_value = dt->u.atomic.order; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_order + * + * Purpose: Sets the byte order for a data type. + * + * 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 data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_order(hid_t type_id, H5T_order_t order) +{ + H5T_t *dt = NULL; + 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 data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (order < 0 || order > H5T_ORDER_NONE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order"); + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); + + /* Commit */ + assert(H5T_is_atomic(dt)); + dt->u.atomic.order = order; + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tpad.c b/src/H5Tpad.c new file mode 100644 index 0000000..4f69d9e --- /dev/null +++ b/src/H5Tpad.c @@ -0,0 +1,151 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the datatype padding for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tpad_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_pad_interface +static herr_t H5T_init_pad_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_pad_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_pad_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_pad_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_pad_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_pad_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_pad + * + * Purpose: Gets the least significant pad type and the most significant + * pad type and returns their values through the LSB and MSB + * arguments, either of which may be the null pointer. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tget_pad, FAIL); + H5TRACE3("e","ixx",type_id,lsb,msb); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); + + /* Get values */ + assert(H5T_is_atomic(dt)); + if (lsb) + *lsb = dt->u.atomic.lsb_pad; + if (msb) + *msb = dt->u.atomic.msb_pad; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_pad + * + * Purpose: Sets the LSB and MSB pad types. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works with derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_pad, FAIL); + H5TRACE3("e","iTpTp",type_id,lsb,msb); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (lsb < 0 || lsb >= H5T_NPAD || msb < 0 || msb >= H5T_NPAD) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pad type"); + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); + + /* Commit */ + assert(H5T_is_atomic(dt)); + dt->u.atomic.lsb_pad = lsb; + dt->u.atomic.msb_pad = msb; + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 5b4cf09..87a96cc 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -241,6 +241,28 @@ H5_DLLVAR size_t H5T_NATIVE_UINT_LEAST64_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_INT_FAST64_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_UINT_FAST64_ALIGN_g; +/* Common functions */ +H5_DLL herr_t H5T_init_interface(void); +H5_DLL H5T_t *H5T_create(H5T_class_t type, size_t size); +H5_DLL herr_t H5T_free(H5T_t *dt); +H5_DLL H5T_sign_t H5T_get_sign(H5T_t *dt); +H5_DLL H5T_t *H5T_get_super(H5T_t *dt); +H5_DLL char *H5T_get_member_name(H5T_t *dt, int membno); +H5_DLL herr_t H5T_get_member_value(H5T_t *dt, int membno, void *value); +H5_DLL H5T_t *H5T_get_member_type(H5T_t *dt, int membno); +H5_DLL int H5T_get_nmembers(const H5T_t *dt); +H5_DLL htri_t H5T_is_variable_str(H5T_t *dt); +H5_DLL htri_t H5T_is_atomic(const H5T_t *dt); +H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, + const H5T_t *member); +H5_DLL H5T_t *H5T_enum_create(H5T_t *parent); +H5_DLL herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value); +H5_DLL int H5T_get_array_ndims(H5T_t *dt); +H5_DLL herr_t H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]); +H5_DLL herr_t H5T_sort_value(H5T_t *dt, int *map); +H5_DLL herr_t H5T_sort_name(H5T_t *dt, int *map); +H5_DLL herr_t H5T_set_size(H5T_t *dt, size_t size); + /* Conversion functions */ H5_DLL herr_t H5T_conv_noop(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, size_t buf_stride, @@ -778,6 +800,7 @@ H5_DLL ssize_t H5T_bit_find(uint8_t *buf, size_t offset, size_t size, H5_DLL htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size); /* VL functions */ +H5_DLL H5T_t * H5T_vlen_create(H5T_t *base); H5_DLL hssize_t H5T_vlen_seq_mem_getlen(H5F_t *f, void *vl_addr); H5_DLL herr_t H5T_vlen_seq_mem_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, size_t len); H5_DLL herr_t H5T_vlen_seq_mem_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, void *bg_addr, hsize_t seq_len, hsize_t base_size); diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c new file mode 100644 index 0000000..60a82aa --- /dev/null +++ b/src/H5Tprecis.c @@ -0,0 +1,266 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the datatype precision for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tprecis_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_precis_interface +static herr_t H5T_init_precis_interface(void); + +/* Static local functions */ +static herr_t H5T_set_precision(H5T_t *dt, size_t prec); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_precis_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_precis_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_precis_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_precis_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_precis_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_precision + * + * Purpose: Gets the precision of a data type. The precision is + * the number of significant bits which, unless padding is + * present, is 8 times larger than the value returned by + * H5Tget_size(). + * + * Return: Success: Number of significant bits + * + * Failure: 0 (all atomic types have at least one + * significant bit) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_precision(hid_t type_id) +{ + H5T_t *dt = NULL; + size_t ret_value; + + FUNC_ENTER_API(H5Tget_precision, 0); + H5TRACE1("z","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); + if (dt->parent) + dt = dt->parent; /*defer to parent*/ + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for specified data type"); + + /* Precision */ + assert(H5T_is_atomic(dt)); + ret_value = dt->u.atomic.prec; + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_precision + * + * Purpose: Sets the precision of a data type. The precision is + * the number of significant bits which, unless padding is + * present, is 8 times larger than the value returned by + * H5Tget_size(). + * + * If the precision is increased then the offset is decreased + * and then the size is increased to insure that significant + * bits do not "hang over" the edge of the data type. + * + * The precision property of strings is read-only. + * + * When decreasing the precision of a floating point type, set + * the locations and sizes of the sign, mantissa, and exponent + * fields first. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Moved real work to a private function. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_precision(hid_t type_id, size_t prec) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_precision, FAIL); + H5TRACE2("e","iz",type_id,prec); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (prec <= 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "precision must be positive"); + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); + + /* Do the work */ + if (H5T_set_precision(dt, prec)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set precision"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_set_precision + * + * Purpose: Sets the precision of a data type. The precision is + * the number of significant bits which, unless padding is + * present, is 8 times larger than the value returned by + * H5Tget_size(). + * + * If the precision is increased then the offset is decreased + * and then the size is increased to insure that significant + * bits do not "hang over" the edge of the data type. + * + * The precision property of strings is read-only. + * + * When decreasing the precision of a floating point type, set + * the locations and sizes of the sign, mantissa, and exponent + * fields first. + * + * 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 data types. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_set_precision(H5T_t *dt, size_t prec) +{ + size_t offset, size; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_set_precision, FAIL); + + /* Check args */ + assert(dt); + assert(prec>0); + assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs); + + if (dt->parent) { + if (H5T_set_precision(dt->parent, prec)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set precision for base type"); + dt->size = dt->parent->size; + } else { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); + } else if (H5T_ENUM==dt->type) { + /*nothing*/ + } else if (H5T_is_atomic(dt)) { + /* Adjust the offset and size */ + offset = dt->u.atomic.offset; + size = dt->size; + if (prec > 8*size) + offset = 0; + else if (offset+prec > 8 * size) offset = 8 * size - prec; + if (prec > 8*size) + size = (prec+7) / 8; + + /* Check that things are still kosher */ + switch (dt->type) { + case H5T_INTEGER: + case H5T_TIME: + case H5T_BITFIELD: + /* nothing to check */ + break; + + case H5T_STRING: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "precision for this type is read-only"); + + case H5T_FLOAT: + /* + * The sign, mantissa, and exponent fields should be adjusted + * first when decreasing the precision of a floating point + * type. + */ + if (dt->u.atomic.u.f.sign >= prec || + dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec || + dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first"); + } + break; + + default: + assert("not implemented yet" && 0); + } + + /* Commit */ + dt->size = size; + if (H5T_is_atomic(dt)) { + dt->u.atomic.offset = offset; + dt->u.atomic.prec = prec; + } + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index fd35f28..82bf370 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -95,63 +95,23 @@ typedef struct { H5_DLL herr_t H5TN_init_interface(void); H5_DLL herr_t H5T_init(void); H5_DLL htri_t H5T_isa(H5G_entry_t *ent, hid_t dxpl_id); -H5_DLL H5T_t *H5T_open(H5G_entry_t *loc, const char *name, hid_t dxpl_id); H5_DLL H5T_t *H5T_open_oid(H5G_entry_t *ent, hid_t dxpl_id); -H5_DLL H5T_t *H5T_create(H5T_class_t type, size_t size); H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method); -H5_DLL herr_t H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id); H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable); -H5_DLL herr_t H5T_free(H5T_t *dt); H5_DLL herr_t H5T_close(H5T_t *dt); -H5_DLL herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, - H5T_t *dst, H5T_conv_t func, hid_t dxpl_id); -H5_DLL herr_t H5T_path_force_reinit(H5T_t *dt); H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt); H5_DLL htri_t H5T_detect_class (const H5T_t *dt, H5T_class_t cls); H5_DLL size_t H5T_get_size(const H5T_t *dt); -H5_DLL H5T_sign_t H5T_get_sign(H5T_t *dt); -H5_DLL H5T_t *H5T_get_super(H5T_t *dt); -H5_DLL char *H5T_get_member_name(H5T_t *dt, int membno); -H5_DLL herr_t H5T_get_member_value(H5T_t *dt, int membno, void *value); -H5_DLL H5T_t *H5T_get_member_type(H5T_t *dt, int membno); -H5_DLL size_t H5T_get_member_offset(H5T_t *dt, int membno); -H5_DLL int H5T_get_nmembers(const H5T_t *dt); -H5_DLL htri_t H5T_is_variable_str(H5T_t *dt); -H5_DLL H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction, - size_t *struct_align, size_t *offset, size_t *comp_size); -H5_DLL H5T_t *H5T_get_native_integer(size_t size, H5T_sign_t sign, H5T_direction_t direction, - size_t *struct_align, size_t *offset, size_t *comp_size); -H5_DLL H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction, - size_t *struct_align, size_t *offset, size_t *comp_size); -H5_DLL herr_t H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, - size_t nelems, size_t align, size_t *struct_align); H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2); -H5_DLL htri_t H5T_is_atomic(const H5T_t *dt); -H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, - const H5T_t *member); -H5_DLL H5T_t *H5T_enum_create(H5T_t *parent); -H5_DLL herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value); -H5_DLL int H5T_get_array_ndims(H5T_t *dt); -H5_DLL herr_t H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]); -H5_DLL herr_t H5T_pack(H5T_t *dt); H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE * stream); H5_DLL H5G_entry_t *H5T_entof(H5T_t *dt); H5_DLL htri_t H5T_is_immutable(H5T_t *dt); H5_DLL htri_t H5T_is_named(H5T_t *dt); H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_t func, hid_t dxpl_id); -H5_DLL herr_t H5T_sort_value(H5T_t *dt, int *map); -H5_DLL herr_t H5T_sort_name(H5T_t *dt, int *map); H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, 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_set_size(H5T_t *dt, size_t size); -H5_DLL herr_t H5T_set_precision(H5T_t *dt, size_t prec); -H5_DLL herr_t H5T_set_offset(H5T_t *dt, size_t offset); -H5_DLL char *H5T_enum_nameof(H5T_t *dt, void *value, char *name/*out*/, - size_t size); -H5_DLL herr_t H5T_enum_valueof(H5T_t *dt, const char *name, - void *value/*out*/); H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data); H5_DLL htri_t H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); diff --git a/src/H5Tstrpad.c b/src/H5Tstrpad.c new file mode 100644 index 0000000..ae8167c --- /dev/null +++ b/src/H5Tstrpad.c @@ -0,0 +1,171 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 the functionality for setting & querying + * the datatype string padding for 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 "H5Tpkg.h" /*data-type functions */ + +#define PABLO_MASK H5Tstrpad_mask + +/* Interface initialization */ +static int interface_initialize_g = 0; +#define INTERFACE_INIT H5T_init_strpad_interface +static herr_t H5T_init_strpad_interface(void); + + +/*-------------------------------------------------------------------------- +NAME + H5T_init_strpad_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_strpad_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_strpad_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_strpad_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_strpad_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_strpad + * + * Purpose: The method used to store character strings differs with the + * programming language: C usually null terminates strings while + * Fortran left-justifies and space-pads strings. This property + * defines the storage mechanism for the string. + * + * Return: Success: The character set of an H5T_STRING type. + * + * Failure: H5T_STR_ERROR (Negative) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +H5T_str_t +H5Tget_strpad(hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_str_t ret_value; + + FUNC_ENTER_API(H5Tget_strpad, H5T_STR_ERROR); + H5TRACE1("Tz","i",type_id); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_STR_ERROR, "not a data type"); + /* Don't see any reason for this. Causes problem for variable-length + * string. -SLU (& QAK) */ + /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ + if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_STR_ERROR, "operation not defined for data type class"); + + /* result */ + if(H5T_STRING == dt->type) + ret_value = dt->u.atomic.u.s.pad; + else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) + ret_value = dt->u.vlen.pad; + else + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR, "can't get strpad info"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_strpad + * + * Purpose: The method used to store character strings differs with the + * programming language: C usually null terminates strings while + * Fortran left-justifies and space-pads strings. This property + * defines the storage mechanism for the string. + * + * When converting from a long string to a short string if the + * short string is H5T_STR_NULLPAD or H5T_STR_SPACEPAD then the + * string is simply truncated; otherwise if the short string is + * H5T_STR_NULLTERM it will be truncated and a null terminator + * is appended. + * + * When converting from a short string to a long string, the + * long string is padded on the end by appending nulls or + * spaces. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * Robb Matzke, 22 Dec 1998 + * Also works for derived data types. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_strpad(hid_t type_id, H5T_str_t strpad) +{ + H5T_t *dt = NULL; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Tset_strpad, FAIL); + H5TRACE2("e","iTz",type_id,strpad); + + /* Check args */ + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + if (strpad < 0 || strpad >= H5T_NSTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal string pad type"); + /* Don't see any reason for this. Causes problem for variable-length + * string. -SLU (& QAK) */ + /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/ + if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class"); + + /* Commit */ + if(H5T_STRING == dt->type) + dt->u.atomic.u.s.pad = strpad; + else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type) + dt->u.vlen.pad = strpad; + else + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR, "can't set strpad info"); + +done: + FUNC_LEAVE_API(ret_value); +} + diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index c1f9926..fbb0d0a 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -10,29 +10,159 @@ * * ****************************************************************************/ -/* $Id$ */ +/* + * Module Info: This module contains the functionality for variable-length + * datatypes in the H5T interface. + */ #define H5T_PACKAGE /*suppress error about including H5Tpkg */ #include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Errors */ -#include "H5HGprivate.h" /* Global Heaps */ -#include "H5Iprivate.h" /* IDs */ -#include "H5Pprivate.h" /* Property Lists */ -#include "H5MMprivate.h" /* Memory Allocation */ -#include "H5Tpkg.h" /* Datatypes */ +#include "H5Eprivate.h" /* Errors */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory Allocation */ +#include "H5Pprivate.h" /* Property Lists */ +#include "H5Tpkg.h" /* Datatypes */ #define PABLO_MASK H5Tvlen_mask /* Interface initialization */ static int interface_initialize_g = 0; -#define INTERFACE_INIT NULL +#define INTERFACE_INIT H5T_init_vlen_interface +static herr_t H5T_init_vlen_interface(void); + +/* Declare extern the free list for H5T_t's */ +H5FL_EXTERN(H5T_t); /* Local functions */ static htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc); static herr_t H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *free_info); +/*-------------------------------------------------------------------------- +NAME + H5T_init_vlen_interface -- Initialize interface-specific information +USAGE + herr_t H5T_init_vlen_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_vlen_interface(void) +{ + FUNC_ENTER_NOINIT(H5T_init_vlen_interface); + + FUNC_LEAVE_NOAPI(H5T_init_interface()); +} /* H5T_init_vlen_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tvlen_create + * + * Purpose: Create a new variable-length data type based on the specified + * BASE_TYPE. + * + * Return: Success: ID of new VL data type + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tvlen_create(hid_t base_id) +{ + H5T_t *base = NULL; /*base data type */ + H5T_t *dt = NULL; /*new data type */ + hid_t ret_value; /*return value */ + + FUNC_ENTER_API(H5Tvlen_create, FAIL); + H5TRACE1("i","i",base_id); + + /* Check args */ + if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); + + /* Create up VL datatype */ + if ((dt=H5T_vlen_create(base))==NULL) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location"); + + /* Atomize the type */ + if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); + +done: + FUNC_LEAVE_API(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_vlen_create + * + * Purpose: Create a new variable-length data type based on the specified + * BASE_TYPE. + * + * Return: Success: new VL data type + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * Tuesday, November 20, 2001 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5T_vlen_create(H5T_t *base) +{ + H5T_t *dt = NULL; /*new VL data type */ + H5T_t *ret_value; /*return value */ + + FUNC_ENTER_NOINIT(H5T_vlen_create); + + /* Check args */ + assert(base); + + /* Build new type */ + if (NULL==(dt = H5FL_CALLOC(H5T_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + dt->ent.header = HADDR_UNDEF; + dt->type = H5T_VLEN; + + /* + * Force conversions (i.e. memory to memory conversions should duplicate + * data, not point to the same VL sequences) + */ + dt->force_conv = TRUE; + dt->parent = H5T_copy(base, H5T_COPY_ALL); + + /* This is a sequence, not a string */ + dt->u.vlen.type = H5T_VLEN_SEQUENCE; + + /* Set up VL information */ + if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); + + /* Set return value */ + ret_value=dt; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + /*------------------------------------------------------------------------- * Function: H5T_vlen_set_loc * diff --git a/src/Makefile.in b/src/Makefile.in index b0e622a..e8aab01 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -38,8 +38,11 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \ H5Omtime.c H5Oname.c H5Onull.c H5Opline.c H5Oplist.c H5Osdspace.c \ H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c \ H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ - H5Sselect.c H5ST.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c \ - H5TB.c H5TS.c H5V.c H5Z.c H5Zdeflate.c H5Zshuffle.c H5Zadler32.c + H5Sselect.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ + H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c H5Tfixed.c \ + H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c H5Torder.c \ + H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \ + H5Zdeflate.c H5Zshuffle.c H5Zadler32.c LIB_OBJ=$(LIB_SRC:.c=.lo) |