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://support.hdfgroup.org/ftp/HDF5/releases.  *
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 floating-point
16  *      datatypes in the H5T interface.
17  */
18 
19 #define H5T_PACKAGE		/*suppress error about including H5Tpkg	  */
20 
21 /* Interface initialization */
22 #define H5_INTERFACE_INIT_FUNC	H5T_init_float_interface
23 
24 
25 #include "H5private.h"		/*generic functions			  */
26 #include "H5Eprivate.h"		/*error handling			  */
27 #include "H5Iprivate.h"		/*ID functions		   		  */
28 #include "H5Tpkg.h"		/*data-type functions			  */
29 
30 
31 /*--------------------------------------------------------------------------
32 NAME
33    H5T_init_float_interface -- Initialize interface-specific information
34 USAGE
35     herr_t H5T_init_float_interface()
36 
37 RETURNS
38     Non-negative on success/Negative on failure
39 DESCRIPTION
40     Initializes any interface-specific data or routines.  (Just calls
41     H5T_init_iterface currently).
42 
43 --------------------------------------------------------------------------*/
44 static herr_t
H5T_init_float_interface(void)45 H5T_init_float_interface(void)
46 {
47     FUNC_ENTER_NOAPI_NOINIT_NOERR
48 
49     FUNC_LEAVE_NOAPI(H5T_init())
50 } /* H5T_init_float_interface() */
51 
52 
53 /*-------------------------------------------------------------------------
54  * Function:	H5Tget_fields
55  *
56  * Purpose:	Returns information about the locations of the various bit
57  *		fields of a floating point datatype.  The field positions
58  *		are bit positions in the significant region of the datatype.
59  *		Bits are numbered with the least significant bit number zero.
60  *
61  *		Any (or even all) of the arguments can be null pointers.
62  *
63  * Return:	Success:	Non-negative, field locations and sizes are
64  *				returned through the arguments.
65  *
66  *		Failure:	Negative
67  *
68  * Programmer:	Robb Matzke
69  *		Wednesday, January  7, 1998
70  *
71  *-------------------------------------------------------------------------
72  */
73 herr_t
H5Tget_fields(hid_t type_id,size_t * spos,size_t * epos,size_t * esize,size_t * mpos,size_t * msize)74 H5Tget_fields(hid_t type_id, size_t *spos/*out*/, size_t *epos/*out*/,
75 size_t *esize/*out*/, size_t *mpos/*out*/, size_t *msize/*out*/)
76 {
77     H5T_t	*dt;                    /* Datatype */
78     herr_t      ret_value = SUCCEED;    /* Return value */
79 
80     FUNC_ENTER_API(FAIL)
81     H5TRACE6("e", "ixxxxx", type_id, spos, epos, esize, mpos, msize);
82 
83     /* Check args */
84     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
85 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
86     while(dt->shared->parent)
87         dt = dt->shared->parent; /*defer to parent*/
88     if(H5T_FLOAT != dt->shared->type)
89         HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "operation not defined for datatype class")
90 
91     /* Get values */
92     if(spos)
93         *spos = dt->shared->u.atomic.u.f.sign;
94     if(epos)
95         *epos = dt->shared->u.atomic.u.f.epos;
96     if(esize)
97         *esize = dt->shared->u.atomic.u.f.esize;
98     if(mpos)
99         *mpos = dt->shared->u.atomic.u.f.mpos;
100     if(msize)
101         *msize = dt->shared->u.atomic.u.f.msize;
102 
103 done:
104     FUNC_LEAVE_API(ret_value)
105 } /* end H5Tget_fields() */
106 
107 
108 /*-------------------------------------------------------------------------
109  * Function:	H5Tset_fields
110  *
111  * Purpose:	Sets the locations and sizes of the various floating point
112  *		bit fields.  The field positions are bit positions in the
113  *		significant region of the datatype.  Bits are numbered with
114  *		the least significant bit number zero.
115  *
116  *		Fields are not allowed to extend beyond the number of bits of
117  *		precision, nor are they allowed to overlap with one another.
118  *
119  * Return:	Non-negative on success/Negative on failure
120  *
121  * Programmer:	Robb Matzke
122  *		Wednesday, January  7, 1998
123  *
124  *-------------------------------------------------------------------------
125  */
126 herr_t
H5Tset_fields(hid_t type_id,size_t spos,size_t epos,size_t esize,size_t mpos,size_t msize)127 H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
128     size_t mpos, size_t msize)
129 {
130     H5T_t	*dt;                    /* Datatype */
131     herr_t      ret_value = SUCCEED;    /* Return value */
132 
133     FUNC_ENTER_API(FAIL)
134     H5TRACE6("e", "izzzzz", type_id, spos, epos, esize, mpos, msize);
135 
136     /* Check args */
137     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
138 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
139     if(H5T_STATE_TRANSIENT != dt->shared->state)
140 	HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only")
141     while(dt->shared->parent)
142         dt = dt->shared->parent; /*defer to parent*/
143     if(H5T_FLOAT != dt->shared->type)
144 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "operation not defined for datatype class")
145     if(epos + esize > dt->shared->u.atomic.prec)
146 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent bit field size/location is invalid")
147     if(mpos + msize > dt->shared->u.atomic.prec)
148 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mantissa bit field size/location is invalid")
149     if(spos >= dt->shared->u.atomic.prec)
150 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign location is not valid")
151 
152     /* Check for overlap */
153     if(spos >= epos && spos < epos + esize)
154 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within exponent field")
155     if(spos >= mpos && spos < mpos + msize)
156 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sign bit appears within mantissa field")
157     if((mpos < epos && mpos + msize > epos) || (epos < mpos && epos + esize > mpos))
158 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "exponent and mantissa fields overlap")
159 
160     /* Commit */
161     dt->shared->u.atomic.u.f.sign = spos;
162     dt->shared->u.atomic.u.f.epos = epos;
163     dt->shared->u.atomic.u.f.mpos = mpos;
164     dt->shared->u.atomic.u.f.esize = esize;
165     dt->shared->u.atomic.u.f.msize = msize;
166 
167 done:
168     FUNC_LEAVE_API(ret_value)
169 } /* end H5Tset_fields() */
170 
171 
172 /*-------------------------------------------------------------------------
173  * Function:	H5Tget_ebias
174  *
175  * Purpose:	Retrieves the exponent bias of a floating-point type.
176  *
177  * Return:	Success:	The bias
178  *
179  *		Failure:	0
180  *
181  * Programmer:	Robb Matzke
182  *		Wednesday, January  7, 1998
183  *
184  *-------------------------------------------------------------------------
185  */
186 size_t
H5Tget_ebias(hid_t type_id)187 H5Tget_ebias(hid_t type_id)
188 {
189     H5T_t	*dt;                    /* Datatype */
190     size_t	ret_value;              /* Return value */
191 
192     FUNC_ENTER_API(0)
193     H5TRACE1("z", "i", type_id);
194 
195     /* Check args */
196     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
197 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype")
198     while(dt->shared->parent)
199         dt = dt->shared->parent; /*defer to parent*/
200     if(H5T_FLOAT != dt->shared->type)
201 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, 0, "operation not defined for datatype class")
202 
203     /* bias */
204     H5_CHECKED_ASSIGN(ret_value, size_t, dt->shared->u.atomic.u.f.ebias, uint64_t);
205 
206 done:
207     FUNC_LEAVE_API(ret_value)
208 } /* end H5Tget_ebias() */
209 
210 
211 /*-------------------------------------------------------------------------
212  * Function:	H5Tset_ebias
213  *
214  * Purpose:	Sets the exponent bias of a floating-point type.
215  *
216  * Return:	Non-negative on success/Negative on failure
217  *
218  * Programmer:	Robb Matzke
219  *		Wednesday, January  7, 1998
220  *
221  * Modifications:
222  * 	Robb Matzke, 22 Dec 1998
223  *	Also works with derived datatypes.
224  *
225  *-------------------------------------------------------------------------
226  */
227 herr_t
H5Tset_ebias(hid_t type_id,size_t ebias)228 H5Tset_ebias(hid_t type_id, size_t ebias)
229 {
230     H5T_t	*dt;                    /* Datatype */
231     herr_t      ret_value = SUCCEED;    /* Return value */
232 
233     FUNC_ENTER_API(FAIL)
234     H5TRACE2("e", "iz", type_id, ebias);
235 
236     /* Check args */
237     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
238 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
239     if(H5T_STATE_TRANSIENT != dt->shared->state)
240 	HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only")
241     while(dt->shared->parent)
242         dt = dt->shared->parent; /*defer to parent*/
243     if(H5T_FLOAT != dt->shared->type)
244 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "operation not defined for datatype class")
245 
246     /* Commit */
247     dt->shared->u.atomic.u.f.ebias = ebias;
248 
249 done:
250     FUNC_LEAVE_API(ret_value)
251 } /* end H5Tset_ebias() */
252 
253 
254 /*-------------------------------------------------------------------------
255  * Function:	H5Tget_norm
256  *
257  * Purpose:	Returns the mantisssa normalization of a floating-point data
258  *		type.
259  *
260  * Return:	Success:	Normalization ID
261  *
262  *		Failure:	H5T_NORM_ERROR (Negative)
263  *
264  * Programmer:	Robb Matzke
265  *		Wednesday, January  7, 1998
266  *
267  *-------------------------------------------------------------------------
268  */
269 H5T_norm_t
H5Tget_norm(hid_t type_id)270 H5Tget_norm(hid_t type_id)
271 {
272     H5T_t	*dt;            /* Datatype */
273     H5T_norm_t	ret_value;      /* Return value */
274 
275     FUNC_ENTER_API(H5T_NORM_ERROR)
276     H5TRACE1("Tn", "i", type_id);
277 
278     /* Check args */
279     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
280 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR, "not a datatype")
281     while(dt->shared->parent)
282         dt = dt->shared->parent; /*defer to parent*/
283     if(H5T_FLOAT != dt->shared->type)
284 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_NORM_ERROR, "operation not defined for datatype class")
285 
286     /* norm */
287     ret_value = dt->shared->u.atomic.u.f.norm;
288 
289 done:
290     FUNC_LEAVE_API(ret_value)
291 } /* end H5Tget_norm() */
292 
293 
294 /*-------------------------------------------------------------------------
295  * Function:	H5Tset_norm
296  *
297  * Purpose:	Sets the mantissa normalization method for a floating point
298  *		datatype.
299  *
300  * Return:	Non-negative on success/Negative on failure
301  *
302  * Programmer:	Robb Matzke
303  *		Wednesday, January  7, 1998
304  *
305  *-------------------------------------------------------------------------
306  */
307 herr_t
H5Tset_norm(hid_t type_id,H5T_norm_t norm)308 H5Tset_norm(hid_t type_id, H5T_norm_t norm)
309 {
310     H5T_t	*dt;                    /* Datatype */
311     herr_t      ret_value = SUCCEED;    /* Return value */
312 
313     FUNC_ENTER_API(FAIL)
314     H5TRACE2("e", "iTn", type_id, norm);
315 
316     /* Check args */
317     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
318 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
319     if(H5T_STATE_TRANSIENT != dt->shared->state)
320 	HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only")
321     if(norm < H5T_NORM_IMPLIED || norm > H5T_NORM_NONE)
322 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization")
323     while(dt->shared->parent)
324         dt = dt->shared->parent; /*defer to parent*/
325     if(H5T_FLOAT != dt->shared->type)
326 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "operation not defined for datatype class")
327 
328     /* Commit */
329     dt->shared->u.atomic.u.f.norm = norm;
330 
331 done:
332     FUNC_LEAVE_API(ret_value)
333 } /* end H5Tset_norm() */
334 
335 
336 /*-------------------------------------------------------------------------
337  * Function:	H5Tget_inpad
338  *
339  * Purpose:	If any internal bits of a floating point type are unused
340  *		(that is, those significant bits which are not part of the
341  *		sign, exponent, or mantissa) then they will be filled
342  *		according to the value of this property.
343  *
344  * Return:	Success:	The internal padding type.
345  *
346  *		Failure:	H5T_PAD_ERROR (Negative)
347  *
348  * Programmer:	Robb Matzke
349  *		Friday, January	 9, 1998
350  *
351  *-------------------------------------------------------------------------
352  */
353 H5T_pad_t
H5Tget_inpad(hid_t type_id)354 H5Tget_inpad(hid_t type_id)
355 {
356     H5T_t	*dt;            /* Datatype */
357     H5T_pad_t	ret_value;      /* Return value */
358 
359     FUNC_ENTER_API(H5T_PAD_ERROR)
360     H5TRACE1("Tp", "i", type_id);
361 
362     /* Check args */
363     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
364 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_PAD_ERROR, "not a datatype")
365     while(dt->shared->parent)
366         dt = dt->shared->parent; /*defer to parent*/
367     if(H5T_FLOAT != dt->shared->type)
368 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_PAD_ERROR, "operation not defined for datatype class")
369 
370     /* pad */
371     ret_value = dt->shared->u.atomic.u.f.pad;
372 
373 done:
374     FUNC_LEAVE_API(ret_value)
375 } /* end H5Tget_inpad() */
376 
377 
378 /*-------------------------------------------------------------------------
379  * Function:	H5Tset_inpad
380  *
381  * Purpose:	If any internal bits of a floating point type are unused
382  *		(that is, those significant bits which are not part of the
383  *		sign, exponent, or mantissa) then they will be filled
384  *		according to the value of this property.
385  *
386  * Return:	Non-negative on success/Negative on failure
387  *
388  * Programmer:	Robb Matzke
389  *		Friday, January	 9, 1998
390  *
391  *-------------------------------------------------------------------------
392  */
393 herr_t
H5Tset_inpad(hid_t type_id,H5T_pad_t pad)394 H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
395 {
396     H5T_t	*dt;                    /* Datatype */
397     herr_t      ret_value = SUCCEED;    /* Return value */
398 
399     FUNC_ENTER_API(FAIL)
400     H5TRACE2("e", "iTp", type_id, pad);
401 
402     /* Check args */
403     if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
404 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
405     if(H5T_STATE_TRANSIENT != dt->shared->state)
406 	HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only")
407     if(pad < H5T_PAD_ZERO || pad >= H5T_NPAD)
408 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal internal pad type")
409     while(dt->shared->parent)
410         dt = dt->shared->parent; /*defer to parent*/
411     if(H5T_FLOAT != dt->shared->type)
412 	HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "operation not defined for datatype class")
413 
414     /* Commit */
415     dt->shared->u.atomic.u.f.pad = pad;
416 
417 done:
418     FUNC_LEAVE_API(ret_value)
419 } /* end H5Tset_inpad() */
420 
421