1 /*
2  * Copyright (c) 2015, The University of Oxford
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  * 3. Neither the name of the University of Oxford nor the names of its
13  *    contributors may be used to endorse or promote products derived from this
14  *    software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef OSKAR_BINARY_DATA_TYPES_H_
30 #define OSKAR_BINARY_DATA_TYPES_H_
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /* Define an enumerator for the type.
37  *
38  * IMPORTANT:
39  * 1. All these must be small enough to fit into one byte (8 bits) only.
40  * 2. To maintain binary data compatibility, do not modify any numbers
41  *    that appear in the list below!
42  */
43 enum OSKAR_DATA_TYPE
44 {
45     /* Byte (char): bit 0 set. */
46     OSKAR_CHAR                   = 0x01,
47 
48     /* Integer (int): bit 1 set. */
49     OSKAR_INT                    = 0x02,
50 
51     /* Scalar single (float): bit 2 set. */
52     OSKAR_SINGLE                 = 0x04,
53 
54     /* Scalar double (double): bit 3 set. */
55     OSKAR_DOUBLE                 = 0x08,
56 
57     /* Complex flag: bit 5 set. */
58     OSKAR_COMPLEX                = 0x20,
59 
60     /* Matrix flag: bit 6 set. */
61     OSKAR_MATRIX                 = 0x40,
62 
63     /* Scalar complex single (float2). */
64     OSKAR_SINGLE_COMPLEX         = OSKAR_SINGLE | OSKAR_COMPLEX,
65 
66     /* Scalar complex double (double2). */
67     OSKAR_DOUBLE_COMPLEX         = OSKAR_DOUBLE | OSKAR_COMPLEX,
68 
69     /* Matrix complex float (float4c). */
70     OSKAR_SINGLE_COMPLEX_MATRIX  = OSKAR_SINGLE | OSKAR_COMPLEX | OSKAR_MATRIX,
71 
72     /* Matrix complex double (double4c). */
73     OSKAR_DOUBLE_COMPLEX_MATRIX  = OSKAR_DOUBLE | OSKAR_COMPLEX | OSKAR_MATRIX
74 };
75 
76 #if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
77     #define OSKAR_BINARY_INLINE static inline
78 #else
79     #define OSKAR_BINARY_INLINE static
80 #endif
81 
82 /**
83  * @brief
84  * Returns the base type (precision) of an OSKAR binary type enumerator.
85  *
86  * @details
87  * Returns the base type of an OSKAR binary type enumerator
88  * (OSKAR_SINGLE, OSKAR_DOUBLE, OSKAR_INT, or OSKAR_CHAR), ignoring complex
89  * or matrix types.
90  *
91  * @param[in] type Enumerated type.
92  *
93  * @return The base type.
94  */
oskar_type_precision(const int type)95 OSKAR_BINARY_INLINE int oskar_type_precision(const int type)
96 {
97     return (type & 0x0F);
98 }
99 
100 /**
101  * @brief
102  * Checks if the OSKAR binary type is double precision.
103  *
104  * @details
105  * Returns 1 (true) if the binary type is double precision, else 0 (false).
106  *
107  * @param[in] type Enumerated type.
108  *
109  * @return 1 if double, 0 otherwise.
110  */
oskar_type_is_double(const int type)111 OSKAR_BINARY_INLINE int oskar_type_is_double(const int type)
112 {
113     return ((type & 0x0F) == OSKAR_DOUBLE);
114 }
115 
116 /**
117  * @brief
118  * Checks if the OSKAR binary type is single precision.
119  *
120  * @details
121  * Returns 1 (true) if the binary type is single precision, else 0 (false).
122  *
123  * @param[in] type Enumerated type.
124  *
125  * @return 1 if single, 0 otherwise.
126  */
oskar_type_is_single(const int type)127 OSKAR_BINARY_INLINE int oskar_type_is_single(const int type)
128 {
129     return ((type & 0x0F) == OSKAR_SINGLE);
130 }
131 
132 /**
133  * @brief
134  * Checks if the OSKAR binary type is complex.
135  *
136  * @details
137  * Returns 1 (true) if the binary type is complex, else 0 (false).
138  *
139  * @param[in] type Enumerated type.
140  *
141  * @return 1 if complex, 0 if real.
142  */
oskar_type_is_complex(const int type)143 OSKAR_BINARY_INLINE int oskar_type_is_complex(const int type)
144 {
145     return ((type & OSKAR_COMPLEX) == OSKAR_COMPLEX);
146 }
147 
148 /**
149  * @brief
150  * Checks if the OSKAR binary type is real.
151  *
152  * @details
153  * Returns 1 (true) if the binary type is real, else 0 (false).
154  *
155  * @param[in] type Enumerated type.
156  *
157  * @return 1 if real, 0 if complex.
158  */
oskar_type_is_real(const int type)159 OSKAR_BINARY_INLINE int oskar_type_is_real(const int type)
160 {
161     return ((type & OSKAR_COMPLEX) == 0);
162 }
163 
164 /**
165  * @brief
166  * Checks if the OSKAR binary type is matrix.
167  *
168  * @details
169  * Returns 1 (true) if the binary type is matrix, else 0 (false).
170  *
171  * @param[in] type Enumerated type.
172  *
173  * @return 1 if matrix, 0 if scalar.
174  */
oskar_type_is_matrix(const int type)175 OSKAR_BINARY_INLINE int oskar_type_is_matrix(const int type)
176 {
177     return ((type & OSKAR_MATRIX) == OSKAR_MATRIX);
178 }
179 
180 /**
181  * @brief
182  * Checks if the OSKAR binary type is scalar.
183  *
184  * @details
185  * Returns 1 (true) if the binary type is scalar, else 0 (false).
186  *
187  * @param[in] type Enumerated type.
188  *
189  * @return 1 if scalar, 0 if matrix.
190  */
oskar_type_is_scalar(const int type)191 OSKAR_BINARY_INLINE int oskar_type_is_scalar(const int type)
192 {
193     return ((type & OSKAR_MATRIX) == 0);
194 }
195 
196 #ifdef __cplusplus
197 }
198 #endif
199 
200 #endif /* OSKAR_BINARY_DATA_TYPES_H_ */
201