-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathhdf5_dl.c
467 lines (410 loc) · 15.9 KB
/
hdf5_dl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
# /*##########################################################################
#
# Copyright (c) 2019-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
/* This provides replacement for HDF5 functions/variables used by filters.
*
* Those replacement provides no-op functions by default and if init_filter
* is called it provides access to HDF5 functions/variables through dynamic
* loading.
* This is useful on Linux/macOS to avoid linking the plugin with a dedicated
* HDF5 library.
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "hdf5.h"
#include "H5PLextern.h"
/*Function types*/
/*H5*/
typedef herr_t (*DL_func_H5open)(void);
/*H5E*/
typedef herr_t (* DL_func_H5Epush1)(
const char *file, const char *func, unsigned line,
H5E_major_t maj, H5E_minor_t min, const char *str);
typedef herr_t (* DL_func_H5Epush2)(
hid_t err_stack, const char *file, const char *func, unsigned line,
hid_t cls_id, hid_t maj_id, hid_t min_id, const char *msg, ...);
typedef herr_t (* DL_func_H5Eprint2) ( hid_t err_stack, FILE * stream );
/*H5P*/
typedef htri_t (* DL_func_H5Pexist)(hid_t plist_id, const char *name);
typedef herr_t (* DL_func_H5Pget)(hid_t plist_id, const char *name, void * value);
typedef herr_t (* DL_func_H5Pget_filter_by_id2)(hid_t plist_id, H5Z_filter_t id,
unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
unsigned *filter_config/*out*/);
typedef H5Z_filter_t (* DL_func_H5Pget_filter2)(hid_t plist_id, unsigned filter,
unsigned int *flags/*out*/,
size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/,
size_t namelen, char name[],
unsigned *filter_config /*out*/);
typedef int (* DL_func_H5Pget_chunk)(
hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/);
typedef int (* DL_func_H5Pget_nfilters)(hid_t plist_id);
typedef herr_t (* DL_func_H5Pinsert2)(hid_t plist_id, const char *name, size_t size,
void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close);
typedef htri_t (* DL_func_H5Pisa_class)(hid_t plist_id, hid_t pclass_id);
typedef herr_t (* DL_func_H5Pmodify_filter)(
hid_t plist_id, H5Z_filter_t filter,
unsigned int flags, size_t cd_nelmts,
const unsigned int cd_values[/*cd_nelmts*/]);
typedef herr_t (* DL_func_H5Premove_filter)(hid_t plist_id, H5Z_filter_t filter);
typedef herr_t (* DL_func_H5Pset)(hid_t plist_id, const char *name, const void *value);
typedef herr_t (* DL_func_H5Pset_filter)(hid_t plist_id, H5Z_filter_t filter,
unsigned int flags, size_t cd_nelmts,
const unsigned int c_values[]);
/*H5S*/
typedef int (* DL_func_H5Sget_simple_extent_dims)(hid_t space_id, hsize_t dims[],
hsize_t maxdims[]);
typedef int (* DL_func_H5Sget_simple_extent_ndims)(hid_t space_id);
typedef htri_t (* DL_func_H5Sis_simple)(hid_t space_id);
/*H5T*/
typedef herr_t (* DL_func_H5Tconvert)(hid_t src_id, hid_t dst_id, size_t nelmts,
void *buf, void *background, hid_t plist_id);
typedef hid_t (* DL_func_H5Tget_native_type)(hid_t type_id, H5T_direction_t direction);
typedef H5T_sign_t (* DL_func_H5Tget_sign)(hid_t type_id);
typedef size_t (* DL_func_H5Tget_size)(
hid_t type_id);
typedef H5T_class_t (* DL_func_H5Tget_class)(hid_t type_id);
typedef H5T_order_t (* DL_func_H5Tget_order)(hid_t type_id);
typedef hid_t (* DL_func_H5Tget_super)(hid_t type);
typedef herr_t (* DL_func_H5Tclose)(hid_t type_id);
/*H5Z*/
typedef herr_t (* DL_func_H5Zregister)(const void *cls);
typedef herr_t (* DL_func_H5Zunregister) (H5Z_filter_t id);
static struct {
/*H5*/
DL_func_H5open H5open;
/*H5E*/
DL_func_H5Epush1 H5Epush1;
DL_func_H5Epush2 H5Epush2;
DL_func_H5Eprint2 H5Eprint2;
/*H5P*/
DL_func_H5Pexist H5Pexist;
DL_func_H5Pget H5Pget;
DL_func_H5Pget_filter2 H5Pget_filter2;
DL_func_H5Pget_nfilters H5Pget_nfilters;
DL_func_H5Pget_filter_by_id2 H5Pget_filter_by_id2;
DL_func_H5Pget_chunk H5Pget_chunk;
DL_func_H5Pinsert2 H5Pinsert2;
DL_func_H5Pisa_class H5Pisa_class;
DL_func_H5Pmodify_filter H5Pmodify_filter;
DL_func_H5Premove_filter H5Premove_filter;
DL_func_H5Pset H5Pset;
DL_func_H5Pset_filter H5Pset_filter;
/*H5S*/
DL_func_H5Sget_simple_extent_dims H5Sget_simple_extent_dims;
DL_func_H5Sget_simple_extent_ndims H5Sget_simple_extent_ndims;
DL_func_H5Sis_simple H5Sis_simple;
/*H5T*/
DL_func_H5Tconvert H5Tconvert;
DL_func_H5Tget_native_type H5Tget_native_type;
DL_func_H5Tget_sign H5Tget_sign;
DL_func_H5Tget_size H5Tget_size;
DL_func_H5Tget_class H5Tget_class;
DL_func_H5Tget_order H5Tget_order;
DL_func_H5Tget_super H5Tget_super;
DL_func_H5Tclose H5Tclose;
/*H5T*/
DL_func_H5Zregister H5Zregister;
DL_func_H5Zunregister H5Zunregister;
} DL_H5Functions = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL};
/*HDF5 variables*/
#define DEF_DEFAULT_VARIABLE(NAME)\
hid_t NAME = -1
#define DEF_DLSYM_VARIABLE(NAME)\
NAME = *((hid_t *)dlsym(handle, #NAME))
DEF_DEFAULT_VARIABLE(H5E_ARGS_g);
DEF_DEFAULT_VARIABLE(H5E_BADSIZE_g);
DEF_DEFAULT_VARIABLE(H5E_BADTYPE_g);
DEF_DEFAULT_VARIABLE(H5E_BADVALUE_g);
DEF_DEFAULT_VARIABLE(H5E_CANTGET_g);
DEF_DEFAULT_VARIABLE(H5E_CANTINIT_g);
DEF_DEFAULT_VARIABLE(H5E_CANTFILTER_g);
DEF_DEFAULT_VARIABLE(H5E_CANTREGISTER_g);
DEF_DEFAULT_VARIABLE(H5E_CALLBACK_g);
DEF_DEFAULT_VARIABLE(H5E_ERR_CLS_g);
DEF_DEFAULT_VARIABLE(H5E_NOSPACE_g);
DEF_DEFAULT_VARIABLE(H5E_OVERFLOW_g);
DEF_DEFAULT_VARIABLE(H5E_PLINE_g);
DEF_DEFAULT_VARIABLE(H5E_READERROR_g);
DEF_DEFAULT_VARIABLE(H5E_RESOURCE_g);
DEF_DEFAULT_VARIABLE(H5P_CLS_DATASET_CREATE_ID_g);
DEF_DEFAULT_VARIABLE(H5T_NATIVE_UINT_g);
DEF_DEFAULT_VARIABLE(H5T_NATIVE_UINT32_g);
DEF_DEFAULT_VARIABLE(H5T_NATIVE_UINT64_g);
DEF_DEFAULT_VARIABLE(H5T_STD_U32BE_g);
DEF_DEFAULT_VARIABLE(H5T_STD_U32LE_g);
DEF_DEFAULT_VARIABLE(H5T_STD_U64BE_g);
DEF_DEFAULT_VARIABLE(H5T_STD_U64LE_g);
/* Initialize the dynamic loading of symbols and register the plugin
*
* libname: Name of the DLL from which to load libHDF5 symbols
* Returns: a value < 0 if an error occured
*/
int init_filter(const char* libname)
{
void * handle;
handle = dlopen(libname, RTLD_LAZY | RTLD_LOCAL);
if (handle == NULL) {
return -1;
}
/*H5*/
DL_H5Functions.H5open = (DL_func_H5open)dlsym(handle, "H5open");
/*H5E*/
DL_H5Functions.H5Epush1 = (DL_func_H5Epush1)dlsym(handle, "H5Epush1");
DL_H5Functions.H5Epush2 = (DL_func_H5Epush2)dlsym(handle, "H5Epush2");
DL_H5Functions.H5Eprint2 = (DL_func_H5Eprint2)dlsym(handle, "H5Eprint2");
/*H5P*/
DL_H5Functions.H5Pexist = (DL_func_H5Pexist)dlsym(handle, "H5Pexist");
DL_H5Functions.H5Pget = (DL_func_H5Pget)dlsym(handle, "H5Pget");
DL_H5Functions.H5Pget_filter2 = (DL_func_H5Pget_filter2)dlsym(handle, "H5Pget_filter2");
DL_H5Functions.H5Pget_filter_by_id2 = (DL_func_H5Pget_filter_by_id2)dlsym(handle, "H5Pget_filter_by_id2");
DL_H5Functions.H5Pget_chunk = (DL_func_H5Pget_chunk)dlsym(handle, "H5Pget_chunk");
DL_H5Functions.H5Pget_nfilters = (DL_func_H5Pget_nfilters)dlsym(handle, "H5Pget_nfilters");
DL_H5Functions.H5Pinsert2 = (DL_func_H5Pinsert2)dlsym(handle, "H5Pinsert2");
DL_H5Functions.H5Pisa_class = (DL_func_H5Pisa_class)dlsym(handle, "H5Pisa_class");
DL_H5Functions.H5Pmodify_filter = (DL_func_H5Pmodify_filter)dlsym(handle, "H5Pmodify_filter");
DL_H5Functions.H5Premove_filter = (DL_func_H5Premove_filter)dlsym(handle, "H5Premove_filter");
DL_H5Functions.H5Pset = (DL_func_H5Pset)dlsym(handle, "H5Pset");
DL_H5Functions.H5Pset_filter = (DL_func_H5Pset_filter)dlsym(handle, "H5Pset_filter");
/*H5S*/
DL_H5Functions.H5Sget_simple_extent_dims = (DL_func_H5Sget_simple_extent_dims) \
dlsym(handle, "H5Sget_simple_extent_dims");
DL_H5Functions.H5Sget_simple_extent_ndims = (DL_func_H5Sget_simple_extent_ndims) \
dlsym(handle, "H5Sget_simple_extent_ndims");
DL_H5Functions.H5Sis_simple = (DL_func_H5Sis_simple) dlsym(handle, "H5Sis_simple");
/*H5T*/
DL_H5Functions.H5Tconvert = (DL_func_H5Tconvert)dlsym(handle, "H5Tconvert");
DL_H5Functions.H5Tget_native_type = (DL_func_H5Tget_native_type)dlsym(handle, "H5Tget_native_type");
DL_H5Functions.H5Tget_sign = (DL_func_H5Tget_sign)dlsym(handle, "H5Tget_sign");
DL_H5Functions.H5Tget_size = (DL_func_H5Tget_size)dlsym(handle, "H5Tget_size");
DL_H5Functions.H5Tget_class = (DL_func_H5Tget_class)dlsym(handle, "H5Tget_class");
DL_H5Functions.H5Tget_order = (DL_func_H5Tget_order)dlsym(handle, "H5Tget_order");
DL_H5Functions.H5Tget_super = (DL_func_H5Tget_super)dlsym(handle, "H5Tget_super");
DL_H5Functions.H5Tclose = (DL_func_H5Tclose)dlsym(handle, "H5Tclose");
/*H5Z*/
DL_H5Functions.H5Zregister = (DL_func_H5Zregister)dlsym(handle, "H5Zregister");
DL_H5Functions.H5Zunregister = (DL_func_H5Zunregister)dlsym(handle, "H5Zunregister");
/*Variables*/
DEF_DLSYM_VARIABLE(H5E_ARGS_g);
DEF_DLSYM_VARIABLE(H5E_BADTYPE_g);
DEF_DLSYM_VARIABLE(H5E_BADVALUE_g);
DEF_DLSYM_VARIABLE(H5E_CANTGET_g);
DEF_DLSYM_VARIABLE(H5E_CANTINIT_g);
DEF_DLSYM_VARIABLE(H5E_CANTFILTER_g);
DEF_DLSYM_VARIABLE(H5E_CANTREGISTER_g);
DEF_DLSYM_VARIABLE(H5E_CALLBACK_g);
DEF_DLSYM_VARIABLE(H5E_ERR_CLS_g);
DEF_DLSYM_VARIABLE(H5E_NOSPACE_g);
DEF_DLSYM_VARIABLE(H5E_OVERFLOW_g);
DEF_DLSYM_VARIABLE(H5E_PLINE_g);
DEF_DLSYM_VARIABLE(H5E_RESOURCE_g);
DEF_DLSYM_VARIABLE(H5P_CLS_DATASET_CREATE_ID_g);
DEF_DLSYM_VARIABLE(H5T_NATIVE_UINT_g);
DEF_DLSYM_VARIABLE(H5T_NATIVE_UINT32_g);
DEF_DLSYM_VARIABLE(H5T_NATIVE_UINT64_g);
DEF_DLSYM_VARIABLE(H5T_STD_U32BE_g);
DEF_DLSYM_VARIABLE(H5T_STD_U32LE_g);
DEF_DLSYM_VARIABLE(H5T_STD_U64BE_g);
DEF_DLSYM_VARIABLE(H5T_STD_U64LE_g);
return 1;
};
#define CALL(fallback, func, ...)\
if(DL_H5Functions.func != NULL) {\
return DL_H5Functions.func(__VA_ARGS__);\
} else {\
return fallback;\
}
/*Function wrappers*/
/*H5*/
herr_t H5open(void)
{
CALL(0, H5open)
};
herr_t H5free_memory(void *mem)
{
/* Special case: Compression filter is not suppose to use this function */
free(mem);
return 0;
};
void * H5allocate_memory(size_t size, hbool_t clear)
{
/* Special case: Compression filter is not suppose to use this function */
void * ptr = malloc(size);
if (clear) {
memset(ptr, 0, size);
}
return ptr;
};
/*H5E*/
herr_t H5Epush1(const char *file, const char *func, unsigned line,
H5E_major_t maj, H5E_minor_t min, const char *str)
{
CALL(0, H5Epush1, file, func, line, maj, min, str)
}
herr_t H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line,
hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...)
{
if(DL_H5Functions.H5Epush2 != NULL) {
/* Avoid using variadic: convert fmt+ ... to a message sting */
va_list ap;
char msg_string[256]; /*Buffer hopefully wide enough*/
va_start(ap, fmt);
vsnprintf(msg_string, sizeof(msg_string), fmt, ap);
msg_string[sizeof(msg_string) - 1] = '\0';
va_end(ap);
return DL_H5Functions.H5Epush2(err_stack, file, func, line, cls_id, maj_id, min_id, msg_string);
} else {
return 0;
}
}
herr_t H5Eprint2( hid_t err_stack, FILE * stream ){
CALL(-1, H5Eprint2, err_stack, stream)
}
/*H5P*/
htri_t H5Pexist(hid_t plist_id, const char *name)
{
CALL(0, H5Pexist, plist_id, name)
}
herr_t H5Pget(hid_t plist_id, const char *name, void * value)
{
CALL(0, H5Pget, plist_id, name, value)
}
herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id,
unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
unsigned *filter_config/*out*/)
{
CALL(0, H5Pget_filter_by_id2, plist_id, id, flags, cd_nelmts, cd_values, namelen, name, filter_config)
}
H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter,
unsigned int *flags/*out*/,
size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/,
size_t namelen, char name[],
unsigned *filter_config /*out*/)
{
CALL(0, H5Pget_filter2, plist_id, filter, flags, cd_nelmts, cd_values, namelen, name, filter_config)
}
int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/)
{
CALL(0, H5Pget_chunk, plist_id, max_ndims, dim)
}
int H5Pget_nfilters(hid_t plist_id)
{
CALL(0, H5Pget_nfilters, plist_id)
}
herr_t H5Pinsert2(hid_t plist_id, const char *name, size_t size,
void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close)
{
CALL(0, H5Pinsert2, plist_id, name, size, value, prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close)
}
htri_t H5Pisa_class(hid_t plist_id, hid_t pclass_id)
{
CALL(0, H5Pisa_class, plist_id, pclass_id)
}
herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter,
unsigned int flags, size_t cd_nelmts,
const unsigned int cd_values[/*cd_nelmts*/])
{
CALL(0, H5Pmodify_filter, plist_id, filter, flags, cd_nelmts, cd_values)
}
herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter)
{
CALL(0, H5Premove_filter, plist_id, filter)
}
herr_t H5Pset(hid_t plist_id, const char *name, const void *value)
{
CALL(0, H5Pset, plist_id, name, value)
}
herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter,
unsigned int flags, size_t cd_nelmts,
const unsigned int c_values[])
{
CALL(0, H5Pset_filter, plist_id, filter, flags, cd_nelmts, c_values)
}
/*H5S*/
int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[],
hsize_t maxdims[])
{
CALL(0, H5Sget_simple_extent_dims, space_id, dims, maxdims)
}
int H5Sget_simple_extent_ndims(hid_t space_id)
{
CALL(0, H5Sget_simple_extent_ndims, space_id)
}
htri_t H5Sis_simple(hid_t space_id)
{
CALL(0, H5Sis_simple, space_id)
}
/*H5T*/
herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts,
void *buf, void *background, hid_t plist_id)
{
CALL(0, H5Tconvert, src_id, dst_id, nelmts, buf, background, plist_id)
}
hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction)
{
CALL(0, H5Tget_native_type, type_id, direction)
}
H5T_sign_t H5Tget_sign(hid_t type_id)
{
CALL(H5T_SGN_ERROR, H5Tget_sign, type_id)
}
size_t H5Tget_size(hid_t type_id)
{
CALL(0, H5Tget_size, type_id)
}
H5T_class_t H5Tget_class(hid_t type_id)
{
CALL(H5T_NO_CLASS, H5Tget_class, type_id)
}
H5T_order_t H5Tget_order(hid_t type_id)
{
CALL(H5T_ORDER_ERROR, H5Tget_order, type_id)
}
hid_t H5Tget_super(hid_t type)
{
CALL(0, H5Tget_super, type)
}
herr_t H5Tclose(hid_t type_id)
{
CALL(0, H5Tclose, type_id)
}
/*H5Z*/
herr_t H5Zregister(const void *cls)
{
CALL(-1, H5Zregister, cls)
}
herr_t H5Zunregister(H5Z_filter_t id){
CALL(-1, H5Zunregister, id)
};