Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALValue.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2016 Jolien Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20#include <stdio.h>
21#include <string.h>
22#include <unistd.h>
23#include <lal/LALStdlib.h>
24#include <lal/LALStdio.h>
25#include <lal/LALValue.h>
26#include "LALValue_private.h"
27#include "config.h"
28
29/* warning: garbage until set */
30LALValue * XLALValueAlloc(size_t size)
31{
32 LALValue *v = XLALMalloc(sizeof(*v) + size);
33 if (!v)
35 v->size = size;
36 return v;
37}
38
39/* warning: garbage until set */
40LALValue * XLALValueRealloc(LALValue *value, size_t size)
41{
42 if (value == NULL)
43 return XLALValueAlloc(size);
44 value = XLALRealloc(value, sizeof(*value) + size);
45 if (!value)
47 value->size = size;
48 return value;
49}
50
51LALValue * XLALValueDuplicate(const LALValue *value)
52{
53 size_t size = sizeof(LALValue) + value->size;
54 LALValue *copy = XLALMalloc(size);
55 if (!copy)
57 return memcpy(copy, value, size);
58}
59
60LALValue * XLALValueCopy(LALValue *copy, const LALValue *orig)
61{
62 LALTYPECODE type = XLALValueGetType(orig);
63 size_t size = XLALValueGetSize(orig);
64 const void * data = XLALValueGetDataPtr(orig);
65 return XLALValueSet(copy, data, size, type);
66}
67
68LALValue * XLALValueSet(LALValue *value, const void *data, size_t size, LALTYPECODE type)
69{
70 XLAL_CHECK_NULL(value != NULL, XLAL_EFAULT);
71
72 /* sanity check type-size relation */
73 switch (type) {
75 /* variable length strings allowed */
76 break;
78 XLAL_CHECK_NULL(size == sizeof(INT2), XLAL_ETYPE, "Wrong size for type");
79 break;
81 XLAL_CHECK_NULL(size == sizeof(INT4), XLAL_ETYPE, "Wrong size for type");
82 break;
84 XLAL_CHECK_NULL(size == sizeof(INT8), XLAL_ETYPE, "Wrong size for type");
85 break;
87 /* variable length BLOBs allowed */
88 break;
90 XLAL_CHECK_NULL(size == sizeof(UINT2), XLAL_ETYPE, "Wrong size for type");
91 break;
93 XLAL_CHECK_NULL(size == sizeof(UINT4), XLAL_ETYPE, "Wrong size for type");
94 break;
96 XLAL_CHECK_NULL(size == sizeof(UINT8), XLAL_ETYPE, "Wrong size for type");
97 break;
98 case LAL_S_TYPE_CODE:
99 XLAL_CHECK_NULL(size == sizeof(REAL4), XLAL_ETYPE, "Wrong size for type");
100 break;
101 case LAL_D_TYPE_CODE:
102 XLAL_CHECK_NULL(size == sizeof(REAL8), XLAL_ETYPE, "Wrong size for type");
103 break;
104 case LAL_C_TYPE_CODE:
105 XLAL_CHECK_NULL(size == sizeof(COMPLEX8), XLAL_ETYPE, "Wrong size for type");
106 break;
107 case LAL_Z_TYPE_CODE:
108 XLAL_CHECK_NULL(size == sizeof(COMPLEX16), XLAL_ETYPE, "Wrong size for type");
109 break;
110 default:
111 XLAL_ERROR_NULL(XLAL_ETYPE, "Unsupported LALTYPECODE value 0%o", (unsigned int)type);
112 }
113
114 /* make sure sizes are compatible */
115 XLAL_CHECK_NULL(size == value->size, XLAL_ESIZE, "Value has incompatible size");
116
117 value->type = type;
118 memcpy(value->data, data, size);
119 return value;
120}
121
122void XLALDestroyValue(LALValue *value)
123{
124 XLALFree(value);
125 return;
126}
127
128LALValue *XLALCreateValue(const void * data, size_t size, LALTYPECODE type)
129{
130 LALValue *v = XLALValueAlloc(size);
131 if (v == NULL)
133 v = XLALValueSet(v, data, size, type);
134 if (v == NULL)
136 return v;
137}
138
139LALValue *XLALCreateBLOBValue(const void * blob, size_t size)
140{
141 LALValue *v = XLALCreateValue(blob, size, LAL_UCHAR_TYPE_CODE);
142 if (v == NULL)
144 return v;
145}
146
147LALValue *XLALCreateStringValue(const char *string)
148{
149 size_t size = strlen(string) + 1;
150 LALValue *v = XLALCreateValue(string, size, LAL_CHAR_TYPE_CODE);
151 if (v == NULL)
153 return v;
154}
155
156#define DEFINE_CREATE_FUNC(TYPE, TCODE) \
157 LALValue *XLALCreate ## TYPE ## Value(TYPE value) \
158 { \
159 LALValue *v = XLALCreateValue(&value, sizeof(value), TCODE); \
160 if (v == NULL) \
161 XLAL_ERROR_NULL(XLAL_EFUNC); \
162 return v; \
163 }
164
177
178#undef DEFINE_CREATE_FUNC
179
180LALTYPECODE XLALValueGetType(const LALValue *value)
181{
182 return value->type;
183}
184
185size_t XLALValueGetSize(const LALValue *value)
186{
187 return value->size;
188}
189
190/* warning: shallow pointer */
191const void * XLALValueGetDataPtr(const LALValue *value)
192{
193 return value->data;
194}
195
196void * XLALValueGetData(void *data, size_t size, LALTYPECODE type, const LALValue *value)
197{
198 if (value->size != size || value->type != type)
199 XLAL_ERROR_NULL(XLAL_ETYPE, "Incorrect value type");
200 return memcpy(data, value->data, size);
201}
202
203int XLALValueEqual(const LALValue *value1, const LALValue *value2)
204{
205 if (value1->size == value2->size && value1->type == value2->type)
206 return memcmp(value1->data, value2->data, value1->size) == 0;
207 return 0;
208}
209
210void * XLALValueGetBLOB(const LALValue *value)
211{
212 void *blob;
213 /* sanity check the type */
214 if (value->type != LAL_UCHAR_TYPE_CODE)
215 XLAL_ERROR_NULL(XLAL_ETYPE, "Value is not a BLOB");
216 blob = LALMalloc(value->size);
217 if (blob == NULL)
219 return memcpy(blob, value->data, value->size);
220}
221
222/* warning: shallow pointer */
223const char * XLALValueGetString(const LALValue *value)
224{
225 /* sanity check the type */
226 if (value->type != LAL_CHAR_TYPE_CODE)
227 XLAL_ERROR_NULL(XLAL_ETYPE, "Value is not a string");
228 /* make sure this is a nul-terminated string */
229 if (value->size == 0 || ((const char *)(value->data))[value->size - 1] != '\0')
230 XLAL_ERROR_NULL(XLAL_ETYPE, "Value is not a string");
231 return (const char *)(value->data);
232}
233
234#define DEFINE_GET_FUNC(TYPE, TCODE, FAILVAL) \
235 TYPE XLALValueGet ## TYPE (const LALValue *value) \
236 { \
237 XLAL_CHECK_VAL(FAILVAL, value->type == TCODE, XLAL_ETYPE); \
238 return *(const TYPE *)(value->data); \
239 }
240
253
254#undef DEFINE_GET_FUNC
255
256REAL8 XLALValueGetAsREAL8(const LALValue *value)
257{
258 const INT8 max_as_double = LAL_INT8_C(9007199254740992);
259 const UINT8 umax_as_double = LAL_INT8_C(9007199254740992);
260 INT8 i;
261 UINT8 u;
262 REAL8 result;
263 switch (value->type) {
265 if (value->size == 1)
266 result = *(const CHAR *)value;
267 else
268 XLAL_ERROR_REAL8(XLAL_ETYPE, "Cannot convert string to float");
269 break;
270 case LAL_I2_TYPE_CODE:
271 result = XLALValueGetINT2(value);
272 break;
273 case LAL_I4_TYPE_CODE:
274 result = XLALValueGetINT4(value);
275 break;
276 case LAL_I8_TYPE_CODE:
277 result = i = XLALValueGetINT8(value);
278 if (i > max_as_double || -i > max_as_double)
279 XLAL_PRINT_WARNING("Loss of precision");
280 break;
282 if (value->size == 1)
283 result = XLALValueGetUCHAR(value);
284 else
285 XLAL_ERROR_REAL8(XLAL_ETYPE, "Cannot convert BLOB to float");
286 break;
287 case LAL_U2_TYPE_CODE:
288 result = XLALValueGetUINT2(value);
289 break;
290 case LAL_U4_TYPE_CODE:
291 result = XLALValueGetUINT4(value);
292 break;
293 case LAL_U8_TYPE_CODE:
294 result = u = XLALValueGetUINT8(value);
295 if (u > umax_as_double)
296 XLAL_PRINT_WARNING("Loss of precision");
297 break;
298 case LAL_S_TYPE_CODE:
299 result = XLALValueGetREAL4(value);
300 break;
301 case LAL_D_TYPE_CODE:
302 result = XLALValueGetREAL8(value);
303 break;
304 case LAL_C_TYPE_CODE:
305 case LAL_Z_TYPE_CODE:
306 XLAL_ERROR_REAL8(XLAL_ETYPE, "Cannot convert complex to float");
307 default:
308 XLAL_ERROR_REAL8(XLAL_ETYPE, "Unsupported LALTYPECODE value 0%o", (unsigned int)value->type);
309 }
310 return result;
311}
312
313char * XLALValueAsStringAppend(char *s, const LALValue *value)
314{
315 COMPLEX8 c;
316 COMPLEX16 z;
317 switch (value->type) {
319 if (value->size == 1)
320 s = XLALStringAppendFmt(s, "'%c'", *(const CHAR *)(value->data));
321 else
322 s = XLALStringAppendFmt(s, "\"%s\"", (const CHAR *)(value->data));
323 break;
324 case LAL_I2_TYPE_CODE:
325 if (value->size != sizeof(INT2))
326 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
328 break;
329 case LAL_I4_TYPE_CODE:
330 if (value->size != sizeof(INT4))
331 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
333 break;
334 case LAL_I8_TYPE_CODE:
335 if (value->size != sizeof(INT8))
336 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
338 break;
340 if (value->size == sizeof(UCHAR))
341 s = XLALStringAppendFmt(s, "0x%x", XLALValueGetUCHAR(value));
342 else {
343 s = XLALStringAppendFmt(s, "b\"");
344 for (size_t i = 0; i < value->size; ++i)
345 s = XLALStringAppendFmt(s, "\\x%02x", ((const UCHAR *)(value->data))[i]);
346 s = XLALStringAppendFmt(s, "\"");
347 }
348 break;
349 case LAL_U2_TYPE_CODE:
350 if (value->size != sizeof(UINT2))
351 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
353 break;
354 case LAL_U4_TYPE_CODE:
355 if (value->size != sizeof(UINT4))
356 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
358 break;
359 case LAL_U8_TYPE_CODE:
360 if (value->size != sizeof(UINT8))
361 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
363 break;
364 case LAL_S_TYPE_CODE:
365 if (value->size != sizeof(REAL4))
366 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
367 s = XLALStringAppendFmt(s, "%.8g", XLALValueGetREAL4(value));
368 break;
369 case LAL_D_TYPE_CODE:
370 if (value->size != sizeof(REAL8))
371 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
372 s = XLALStringAppendFmt(s, "%.16g", XLALValueGetREAL8(value));
373 break;
374 case LAL_C_TYPE_CODE:
375 c = XLALValueGetCOMPLEX8(value);
376 if (value->size != sizeof(COMPLEX8))
377 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
378 s = XLALStringAppendFmt(s, "%.8g%+.8gj", crealf(c), cimagf(c));
379 break;
380 case LAL_Z_TYPE_CODE:
381 z = XLALValueGetCOMPLEX16(value);
382 if (value->size != sizeof(COMPLEX16))
383 XLAL_ERROR_NULL(XLAL_ESIZE, "Value has incorrect size for type");
384 s = XLALStringAppendFmt(s, "%.16g%+.16gj", creal(z), cimag(z));
385 break;
386 default:
387 XLAL_ERROR_NULL(XLAL_ETYPE, "Unsupported LALTYPECODE value 0%o", (unsigned int)value->type);
388 }
389 return s;
390}
391
392void XLALValuePrint(const LALValue *value, int fd)
393{
394 char *s = NULL;
395 s = XLALValueAsStringAppend(s, value);
397#if HAVE_DPRINTF
398 dprintf(fd, "%s", s);
399#else
400 /* hack... */
401 switch (fd) {
402 case 1:
403 fprintf(stdout, "%s", s);
404 break;
405 case 2:
406 fprintf(stderr, "%s", s);
407 break;
408 default:
409 LALFree(s);
410 XLAL_ERROR_VOID(XLAL_EIO, "Don't know what to do with file descriptor %d", fd);
411 }
412#endif
413 LALFree(s);
414 return;
415}
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
char * XLALStringAppendFmt(char *s, const char *fmt,...)
Append the formatted string 'fmt' to the string 's', which is reallocated with XLALRealloc() to the r...
Definition: LALString.c:69
LALValue * XLALValueRealloc(LALValue *value, size_t size)
Definition: LALValue.c:40
char * XLALValueAsStringAppend(char *s, const LALValue *value)
Definition: LALValue.c:313
LALValue * XLALCreateValue(const void *data, size_t size, LALTYPECODE type)
Definition: LALValue.c:128
const void * XLALValueGetDataPtr(const LALValue *value)
Definition: LALValue.c:191
REAL8 XLALValueGetAsREAL8(const LALValue *value)
Definition: LALValue.c:256
LALValue * XLALValueAlloc(size_t size)
Definition: LALValue.c:30
LALValue * XLALValueCopy(LALValue *copy, const LALValue *orig)
Definition: LALValue.c:60
int XLALValueEqual(const LALValue *value1, const LALValue *value2)
Definition: LALValue.c:203
LALValue * XLALCreateBLOBValue(const void *blob, size_t size)
Definition: LALValue.c:139
void * XLALValueGetData(void *data, size_t size, LALTYPECODE type, const LALValue *value)
Definition: LALValue.c:196
#define DEFINE_GET_FUNC(TYPE, TCODE, FAILVAL)
Definition: LALValue.c:234
void XLALDestroyValue(LALValue *value)
Definition: LALValue.c:122
void XLALValuePrint(const LALValue *value, int fd)
Definition: LALValue.c:392
LALValue * XLALValueSet(LALValue *value, const void *data, size_t size, LALTYPECODE type)
Definition: LALValue.c:68
LALValue * XLALValueDuplicate(const LALValue *value)
Definition: LALValue.c:51
LALValue * XLALCreateStringValue(const char *string)
Definition: LALValue.c:147
#define DEFINE_CREATE_FUNC(TYPE, TCODE)
Definition: LALValue.c:156
const char * XLALValueGetString(const LALValue *value)
Definition: LALValue.c:223
size_t XLALValueGetSize(const LALValue *value)
Definition: LALValue.c:185
void * XLALValueGetBLOB(const LALValue *value)
Definition: LALValue.c:210
LALTYPECODE XLALValueGetType(const LALValue *value)
Definition: LALValue.c:180
REAL8 XLALValueGetREAL8(const LALValue *value)
REAL4 XLALValueGetREAL4(const LALValue *value)
INT2 XLALValueGetINT2(const LALValue *value)
INT8 XLALValueGetINT8(const LALValue *value)
UCHAR XLALValueGetUCHAR(const LALValue *value)
COMPLEX8 XLALValueGetCOMPLEX8(const LALValue *value)
COMPLEX16 XLALValueGetCOMPLEX16(const LALValue *value)
UINT8 XLALValueGetUINT8(const LALValue *value)
INT4 XLALValueGetINT4(const LALValue *value)
UINT4 XLALValueGetUINT4(const LALValue *value)
UINT2 XLALValueGetUINT2(const LALValue *value)
#define fprintf
LALTYPECODE
Type codes: use these type codes to identify a LAL atomic data type, see Headers LAL(Atomic)Datatypes...
Definition: LALDatatypes.h:49
unsigned char UCHAR
One-byte unsigned integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint64_t UINT8
Eight-byte unsigned integer; on some platforms this is equivalent to unsigned long int instead.
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
#define LAL_INT8_C(c)
Macro for use in defining v as an INT8 constant.
double REAL8
Double precision real floating-point number (8 bytes).
int16_t INT2
Two-byte signed integer.
int64_t INT8
Eight-byte signed integer; on some platforms this is equivalent to long int instead.
uint16_t UINT2
Two-byte unsigned integer.
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint32_t UINT4
Four-byte unsigned integer.
float complex COMPLEX8
Single-precision floating-point complex number (8 bytes total)
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
@ LAL_C_TYPE_CODE
COMPLEX8 type code (27)
Definition: LALDatatypes.h:60
@ LAL_CHAR_TYPE_CODE
CHAR type code (0)
Definition: LALDatatypes.h:50
@ LAL_U2_TYPE_CODE
UINT2 type code (33)
Definition: LALDatatypes.h:55
@ LAL_Z_TYPE_CODE
COMPLEX16 type code (28)
Definition: LALDatatypes.h:61
@ LAL_S_TYPE_CODE
REAL4 type code (18)
Definition: LALDatatypes.h:58
@ LAL_I2_TYPE_CODE
INT2 type code (1)
Definition: LALDatatypes.h:51
@ LAL_I8_TYPE_CODE
INT8 type code (3)
Definition: LALDatatypes.h:53
@ LAL_D_TYPE_CODE
REAL8 type code (19)
Definition: LALDatatypes.h:59
@ LAL_I4_TYPE_CODE
INT4 type code (2)
Definition: LALDatatypes.h:52
@ LAL_UCHAR_TYPE_CODE
UCHAR type code (32)
Definition: LALDatatypes.h:54
@ LAL_U8_TYPE_CODE
UINT8 type code (35)
Definition: LALDatatypes.h:57
@ LAL_U4_TYPE_CODE
UINT4 type code (34)
Definition: LALDatatypes.h:56
#define XLALMalloc(n)
Definition: LALMalloc.h:44
#define XLALFree(p)
Definition: LALMalloc.h:47
#define XLALRealloc(p, n)
Definition: LALMalloc.h:46
#define LAL_INT4_PRId
Definition: LALStdio.h:69
#define LAL_INT8_PRIu
Definition: LALStdio.h:84
#define LAL_INT8_PRId
Definition: LALStdio.h:81
#define LAL_INT2_PRId
Definition: LALStdio.h:57
#define LAL_INT2_PRIu
Definition: LALStdio.h:60
#define LAL_INT4_PRIu
Definition: LALStdio.h:72
#define XLAL_ERROR_VOID(...)
Macro to invoke a failure from a XLAL routine returning void.
Definition: XLALError.h:726
#define XLAL_ERROR_REAL8(...)
Macro to invoke a failure from a XLAL routine returning a REAL8.
Definition: XLALError.h:752
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
#define XLAL_CHECK_VOID(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns void.
Definition: XLALError.h:840
#define XLAL_REAL4_FAIL_NAN
Floating-point value of the XLAL REAL4 failure NaN.
Definition: XLALError.h:388
#define XLAL_REAL8_FAIL_NAN
Floating-point value of the XLAL REAL8 failure NaN.
Definition: XLALError.h:389
#define XLAL_PRINT_WARNING(...)
Macro that will print a warning message with a standard format.
Definition: XLALError.h:270
#define XLAL_CHECK_NULL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a pointe...
Definition: XLALError.h:825
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_ETYPE
Wrong or unknown type.
Definition: XLALError.h:422
@ XLAL_ESIZE
Wrong size.
Definition: XLALError.h:420
@ XLAL_EIO
I/O error.
Definition: XLALError.h:406
@ XLAL_FAILURE
Failure return value (not an error number)
Definition: XLALError.h:402