1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://www.hdfgroup.org/licenses.               *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*
15  * Module Info: This module contains the functionality for array datatypes in
16  *      the H5T interface.
17  */
18 
19 /****************/
20 /* Module Setup */
21 /****************/
22 
23 #include "H5Tmodule.h" /* This source code file is part of the H5T module */
24 
25 /***********/
26 /* Headers */
27 /***********/
28 #include "H5private.h"  /* Generic Functions			*/
29 #include "H5Eprivate.h" /* Error handling			*/
30 #include "H5Iprivate.h" /* IDs					*/
31 #include "H5Tpkg.h"     /* Datatypes				*/
32 
33 /****************/
34 /* Local Macros */
35 /****************/
36 
37 /******************/
38 /* Local Typedefs */
39 /******************/
40 
41 /********************/
42 /* Package Typedefs */
43 /********************/
44 
45 /********************/
46 /* Local Prototypes */
47 /********************/
48 
49 /*********************/
50 /* Public Variables */
51 /*********************/
52 
53 /*********************/
54 /* Package Variables */
55 /*********************/
56 
57 /*****************************/
58 /* Library Private Variables */
59 /*****************************/
60 
61 /*******************/
62 /* Local Variables */
63 /*******************/
64 
65 /*-------------------------------------------------------------------------
66  * Function:	H5Tarray_create2
67  *
68  * Purpose:	Create a new array datatype based on the specified BASE_TYPE.
69  *		The type is an array with NDIMS dimensionality and the size of the
70  *      array is DIMS. The total member size should be relatively small.
71  *      Array datatypes are currently limited to H5S_MAX_RANK number of
72  *      dimensions and must have the number of dimensions set greater than
73  *      0. (i.e. 0 > ndims <= H5S_MAX_RANK)  All dimensions sizes must be greater
74  *      than 0 also.
75  *
76  * Return:	Success:	ID of new array datatype
77  *		Failure:	Negative
78  *
79  * Programmer:	Quincey Koziol
80  *              Thursday, Oct 17, 2007
81  *
82  *-------------------------------------------------------------------------
83  */
84 hid_t
H5Tarray_create2(hid_t base_id,unsigned ndims,const hsize_t dim[])85 H5Tarray_create2(hid_t base_id, unsigned ndims, const hsize_t dim[/* ndims */])
86 {
87     H5T_t *  base;      /* base datatype	*/
88     H5T_t *  dt = NULL; /* new array datatype	*/
89     unsigned u;         /* local index variable */
90     hid_t    ret_value; /* return value	*/
91 
92     FUNC_ENTER_API(H5I_INVALID_HID)
93     H5TRACE3("i", "iIu*h", base_id, ndims, dim);
94 
95     /* Check args */
96     if (ndims < 1 || ndims > H5S_MAX_RANK)
97         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid dimensionality")
98     if (!dim)
99         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no dimensions specified")
100     for (u = 0; u < ndims; u++)
101         if (!(dim[u] > 0))
102             HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "zero-sized dimension specified")
103     if (NULL == (base = (H5T_t *)H5I_object_verify(base_id, H5I_DATATYPE)))
104         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an valid base datatype")
105 
106     /* Create the array datatype */
107     if (NULL == (dt = H5T__array_create(base, ndims, dim)))
108         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to create datatype")
109 
110     /* Atomize the type */
111     if ((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
112         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register datatype")
113 
114 done:
115     if (ret_value < 0)
116         if (dt && H5T_close_real(dt) < 0)
117             HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "can't release datatype")
118 
119     FUNC_LEAVE_API(ret_value)
120 } /* end H5Tarray_create2() */
121 
122 /*-------------------------------------------------------------------------
123  * Function:	H5T__array_create
124  *
125  * Purpose:	Internal routine to create a new array data type based on the
126  *      specified BASE_TYPE.  The type is an array with NDIMS dimensionality
127  *      and the size of the array is DIMS.
128  *      Array datatypes are currently limited to H5S_MAX_RANK number
129  *      of dimensions.
130  *
131  * Return:	Success:	ID of new array data type
132  *		Failure:	Negative
133  *
134  * Programmer:	Quincey Koziol
135  *              Thursday, Oct 26, 2000
136  *
137  *-------------------------------------------------------------------------
138  */
139 H5T_t *
H5T__array_create(H5T_t * base,unsigned ndims,const hsize_t dim[])140 H5T__array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/* ndims */])
141 {
142     unsigned u;                /* Local index variable */
143     H5T_t *  ret_value = NULL; /* New array data type	*/
144 
145     FUNC_ENTER_PACKAGE
146 
147     HDassert(base);
148     HDassert(ndims <= H5S_MAX_RANK);
149     HDassert(dim);
150 
151     /* Build new type */
152     if (NULL == (ret_value = H5T__alloc()))
153         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
154     ret_value->shared->type = H5T_ARRAY;
155 
156     /* Copy the base type of the array */
157     if (NULL == (ret_value->shared->parent = H5T_copy(base, H5T_COPY_ALL)))
158         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy base datatype")
159 
160     /* Set the array parameters */
161     ret_value->shared->u.array.ndims = ndims;
162 
163     /* Copy the array dimensions & compute the # of elements in the array */
164     for (u = 0, ret_value->shared->u.array.nelem = 1; u < ndims; u++) {
165         H5_CHECKED_ASSIGN(ret_value->shared->u.array.dim[u], size_t, dim[u], hsize_t);
166         ret_value->shared->u.array.nelem *= (size_t)dim[u];
167     } /* end for */
168 
169     /* Set the array's size (number of elements * element datatype's size) */
170     ret_value->shared->size = ret_value->shared->parent->shared->size * ret_value->shared->u.array.nelem;
171 
172     /* Set the "force conversion" flag if the base datatype indicates */
173     if (base->shared->force_conv == TRUE)
174         ret_value->shared->force_conv = TRUE;
175 
176     /* Array datatypes need a later version of the datatype object header message */
177     ret_value->shared->version = MAX(base->shared->version, H5O_DTYPE_VERSION_2);
178 
179 done:
180     FUNC_LEAVE_NOAPI(ret_value)
181 } /* end H5T__array_create */
182 
183 /*-------------------------------------------------------------------------
184  * Function:	H5Tget_array_ndims
185  *
186  * Purpose:	Query the number of dimensions for an array datatype.
187  *
188  * Return:	Success:	Number of dimensions of the array datatype
189  *		Failure:	Negative
190  *
191  * Programmer:	Quincey Koziol
192  *              Monday, November 6, 2000
193  *
194  *-------------------------------------------------------------------------
195  */
196 int
H5Tget_array_ndims(hid_t type_id)197 H5Tget_array_ndims(hid_t type_id)
198 {
199     H5T_t *dt;        /* pointer to array datatype	*/
200     int    ret_value; /* return value			*/
201 
202     FUNC_ENTER_API(FAIL)
203     H5TRACE1("Is", "i", type_id);
204 
205     /* Check args */
206     if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
207         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
208     if (dt->shared->type != H5T_ARRAY)
209         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
210 
211     /* Retrieve the number of dimensions */
212     ret_value = H5T__get_array_ndims(dt);
213 
214 done:
215     FUNC_LEAVE_API(ret_value)
216 } /* end H5Tget_array_ndims */
217 
218 /*-------------------------------------------------------------------------
219  * Function:	H5T__get_array_ndims
220  *
221  * Purpose:	Private function for H5T__get_array_ndims.  Query the number
222  *              of dimensions for an array datatype.
223  *
224  * Return:	Success:	Number of dimensions of the array datatype
225  *		Failure:	Negative
226  *
227  * Programmer:	Raymond Lu
228  *              October 10, 2002
229  *
230  *-------------------------------------------------------------------------
231  */
232 int
H5T__get_array_ndims(const H5T_t * dt)233 H5T__get_array_ndims(const H5T_t *dt)
234 {
235     FUNC_ENTER_PACKAGE_NOERR
236 
237     HDassert(dt);
238     HDassert(dt->shared->type == H5T_ARRAY);
239 
240     /* Retrieve the number of dimensions */
241     FUNC_LEAVE_NOAPI((int)dt->shared->u.array.ndims)
242 } /* end H5T__get_array_ndims */
243 
244 /*-------------------------------------------------------------------------
245  * Function:	H5Tget_array_dims2
246  *
247  * Purpose:	Query the sizes of dimensions for an array datatype.
248  *
249  * Return:	Success:	Number of dimensions of the array type
250  *		Failure:	Negative
251  *
252  * Programmer:	Quincey Koziol
253  *              Thursday, October 17, 2007
254  *
255  *-------------------------------------------------------------------------
256  */
257 int
H5Tget_array_dims2(hid_t type_id,hsize_t dims[])258 H5Tget_array_dims2(hid_t type_id, hsize_t dims[])
259 {
260     H5T_t *dt;        /* pointer to array data type	*/
261     int    ret_value; /* return value			*/
262 
263     FUNC_ENTER_API(FAIL)
264     H5TRACE2("Is", "i*h", type_id, dims);
265 
266     /* Check args */
267     if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
268         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
269     if (dt->shared->type != H5T_ARRAY)
270         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
271 
272     /* Retrieve the sizes of the dimensions */
273     if ((ret_value = H5T__get_array_dims(dt, dims)) < 0)
274         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes")
275 done:
276     FUNC_LEAVE_API(ret_value)
277 } /* end H5Tget_array_dims2() */
278 
279 /*-------------------------------------------------------------------------
280  * Function:	H5T__get_array_dims
281  *
282  * Purpose:	Private function for H5T__get_array_dims.  Query the sizes
283  *              of dimensions for an array datatype.
284  *
285  * Return:	Success:	Number of dimensions of the array type
286  *		Failure:	Negative
287  *
288  * Programmer:  Raymond Lu
289  *              October 10, 2002
290  *
291  *-------------------------------------------------------------------------
292  */
293 int
H5T__get_array_dims(const H5T_t * dt,hsize_t dims[])294 H5T__get_array_dims(const H5T_t *dt, hsize_t dims[])
295 {
296     unsigned u; /* Local index variable */
297 
298     FUNC_ENTER_PACKAGE_NOERR
299 
300     HDassert(dt);
301     HDassert(dt->shared->type == H5T_ARRAY);
302 
303     /* Retrieve the sizes of the dimensions */
304     if (dims)
305         for (u = 0; u < dt->shared->u.array.ndims; u++)
306             dims[u] = dt->shared->u.array.dim[u];
307 
308     /* Pass along the array rank as the return value */
309     FUNC_LEAVE_NOAPI((int)dt->shared->u.array.ndims)
310 } /* end H5T__get_array_dims */
311 
312 #ifndef H5_NO_DEPRECATED_SYMBOLS
313 
314 /*-------------------------------------------------------------------------
315  * Function:	H5Tarray_create1
316  *
317  * Purpose:	Create a new array datatype based on the specified BASE_TYPE.
318  *		The type is an array with NDIMS dimensionality and the size of the
319  *      array is DIMS. The total member size should be relatively small.
320  *      Array datatypes are currently limited to H5S_MAX_RANK number of
321  *      dimensions and must have the number of dimensions set greater than
322  *      0. (i.e. 0 > ndims <= H5S_MAX_RANK)  All dimensions sizes must be greater
323  *      than 0 also.
324  *
325  * Return:	Success:	ID of new array datatype
326  *		Failure:	Negative
327  *
328  * Programmer:	Quincey Koziol
329  *              Thursday, Oct 26, 2000
330  *
331  *-------------------------------------------------------------------------
332  */
333 hid_t
H5Tarray_create1(hid_t base_id,int ndims,const hsize_t dim[],const int H5_ATTR_UNUSED perm[])334 H5Tarray_create1(hid_t base_id, int ndims, const hsize_t dim[/* ndims */],
335                  const int H5_ATTR_UNUSED perm[/* ndims */])
336 {
337     H5T_t *  base;      /* base datatype	*/
338     H5T_t *  dt = NULL; /* new array datatype	*/
339     unsigned u;         /* local index variable */
340     hid_t    ret_value; /* return value	*/
341 
342     FUNC_ENTER_API(H5I_INVALID_HID)
343     H5TRACE4("i", "iIs*h*Is", base_id, ndims, dim, perm);
344 
345     /* Check args */
346     if (ndims < 1 || ndims > H5S_MAX_RANK)
347         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid dimensionality")
348     if (!dim)
349         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no dimensions specified")
350     for (u = 0; u < (unsigned)ndims; u++)
351         if (!(dim[u] > 0))
352             HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "zero-sized dimension specified")
353     if (NULL == (base = (H5T_t *)H5I_object_verify(base_id, H5I_DATATYPE)))
354         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an valid base datatype")
355 
356     /* Create the array datatype */
357     if (NULL == (dt = H5T__array_create(base, (unsigned)ndims, dim)))
358         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to create datatype")
359 
360     /* Atomize the type */
361     if ((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
362         HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register datatype")
363 
364 done:
365     if (ret_value < 0)
366         if (dt && H5T_close_real(dt) < 0)
367             HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "can't release datatype")
368 
369     FUNC_LEAVE_API(ret_value)
370 } /* end H5Tarray_create1() */
371 
372 /*-------------------------------------------------------------------------
373  * Function:	H5Tget_array_dims1
374  *
375  * Purpose:	Query the sizes of dimensions for an array datatype.
376  *
377  * Return:	Success:	Number of dimensions of the array type
378  *		Failure:	Negative
379  *
380  * Programmer:	Quincey Koziol
381  *              Monday, November 6, 2000
382  *
383  *-------------------------------------------------------------------------
384  */
385 int
H5Tget_array_dims1(hid_t type_id,hsize_t dims[],int H5_ATTR_UNUSED perm[])386 H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int H5_ATTR_UNUSED perm[])
387 {
388     H5T_t *dt;        /* Array datatype to query	*/
389     int    ret_value; /* return value			*/
390 
391     FUNC_ENTER_API(FAIL)
392     H5TRACE3("Is", "i*h*Is", type_id, dims, perm);
393 
394     /* Check args */
395     if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
396         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object")
397     if (dt->shared->type != H5T_ARRAY)
398         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype")
399 
400     /* Retrieve the sizes of the dimensions */
401     if ((ret_value = H5T__get_array_dims(dt, dims)) < 0)
402         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes")
403 
404 done:
405     FUNC_LEAVE_API(ret_value)
406 } /* end H5Tget_array_dims1() */
407 #endif /* H5_NO_DEPRECATED_SYMBOLS */
408