/src/c-blosc2/blosc/blosc-private.h
Line | Count | Source |
1 | | /********************************************************************* |
2 | | Blosc - Blocked Shuffling and Compression Library |
3 | | |
4 | | Copyright (c) 2021 Blosc Development Team <blosc@blosc.org> |
5 | | https://blosc.org |
6 | | License: BSD 3-Clause (see LICENSE.txt) |
7 | | |
8 | | See LICENSE.txt for details about copyright and rights to use. |
9 | | **********************************************************************/ |
10 | | |
11 | | |
12 | | #ifndef BLOSC_BLOSC_PRIVATE_H |
13 | | #define BLOSC_BLOSC_PRIVATE_H |
14 | | |
15 | | #include "blosc2/blosc2-common.h" |
16 | | #include "blosc2.h" |
17 | | |
18 | | #include <stdbool.h> |
19 | | #include <stdlib.h> |
20 | | #include <stdint.h> |
21 | | #include <ctype.h> |
22 | | |
23 | | /********************************************************************* |
24 | | |
25 | | Utility functions meant to be used internally. |
26 | | |
27 | | *********************************************************************/ |
28 | | |
29 | | int blosc2_decompress_block_ctx(blosc2_context* context, const void* src, |
30 | | int32_t srcsize, int32_t nblock, void* dest, |
31 | | int32_t destsize); |
32 | | int blosc2_run_parallel(int16_t nthreads, void (*dojob)(void *), |
33 | | size_t jobdata_elsize, void *jobdata); |
34 | | |
35 | 0 | #define to_little(dest, src, itemsize) endian_handler(true, dest, src, itemsize) |
36 | | #define from_little(dest, src, itemsize) endian_handler(true, dest, src, itemsize) |
37 | 0 | #define to_big(dest, src, itemsize) endian_handler(false, dest, src, itemsize) |
38 | 62.8k | #define from_big(dest, src, itemsize) endian_handler(false, dest, src, itemsize) |
39 | | |
40 | | |
41 | | // Return true if platform is little endian; else false |
42 | 1.56M | static bool is_little_endian(void) { |
43 | 1.56M | static const int i = 1; |
44 | 1.56M | char* p = (char*)&i; |
45 | | |
46 | 1.56M | if (p[0] == 1) { |
47 | 1.56M | return true; |
48 | 1.56M | } |
49 | 0 | else { |
50 | 0 | return false; |
51 | 0 | } |
52 | 1.56M | } blosc2.c:is_little_endian Line | Count | Source | 42 | 1.50M | static bool is_little_endian(void) { | 43 | 1.50M | static const int i = 1; | 44 | 1.50M | char* p = (char*)&i; | 45 | | | 46 | 1.50M | if (p[0] == 1) { | 47 | 1.50M | return true; | 48 | 1.50M | } | 49 | 0 | else { | 50 | | return false; | 51 | 0 | } | 52 | 1.50M | } |
Unexecuted instantiation: schunk.c:is_little_endian Line | Count | Source | 42 | 62.8k | static bool is_little_endian(void) { | 43 | 62.8k | static const int i = 1; | 44 | 62.8k | char* p = (char*)&i; | 45 | | | 46 | 62.8k | if (p[0] == 1) { | 47 | 62.8k | return true; | 48 | 62.8k | } | 49 | 0 | else { | 50 | | return false; | 51 | 0 | } | 52 | 62.8k | } |
Unexecuted instantiation: codecs-registry.c:is_little_endian Unexecuted instantiation: tuners-registry.c:is_little_endian Unexecuted instantiation: filters-registry.c:is_little_endian |
53 | | |
54 | | |
55 | | static inline void endian_handler(bool little, void *dest, const void *pa, int size) |
56 | 62.8k | { |
57 | 62.8k | bool little_endian = is_little_endian(); |
58 | 62.8k | if (little_endian == little) { |
59 | 0 | memcpy(dest, pa, size); |
60 | 0 | } |
61 | 62.8k | else { |
62 | 62.8k | uint8_t* pa_ = (uint8_t*)pa; |
63 | 62.8k | uint8_t pa2_[8]; |
64 | 62.8k | switch (size) { |
65 | 25.6k | case 8: |
66 | 25.6k | pa2_[0] = pa_[7]; |
67 | 25.6k | pa2_[1] = pa_[6]; |
68 | 25.6k | pa2_[2] = pa_[5]; |
69 | 25.6k | pa2_[3] = pa_[4]; |
70 | 25.6k | pa2_[4] = pa_[3]; |
71 | 25.6k | pa2_[5] = pa_[2]; |
72 | 25.6k | pa2_[6] = pa_[1]; |
73 | 25.6k | pa2_[7] = pa_[0]; |
74 | 25.6k | break; |
75 | 31.4k | case 4: |
76 | 31.4k | pa2_[0] = pa_[3]; |
77 | 31.4k | pa2_[1] = pa_[2]; |
78 | 31.4k | pa2_[2] = pa_[1]; |
79 | 31.4k | pa2_[3] = pa_[0]; |
80 | 31.4k | break; |
81 | 771 | case 2: |
82 | 771 | pa2_[0] = pa_[1]; |
83 | 771 | pa2_[1] = pa_[0]; |
84 | 771 | break; |
85 | 4.94k | case 1: |
86 | 4.94k | pa2_[0] = pa_[0]; |
87 | 4.94k | break; |
88 | 0 | default: |
89 | 0 | BLOSC_TRACE_ERROR("Unhandled size: %d.", size); |
90 | 62.8k | } |
91 | 62.8k | memcpy(dest, pa2_, size); |
92 | 62.8k | } |
93 | 62.8k | } Unexecuted instantiation: blosc2.c:endian_handler Unexecuted instantiation: schunk.c:endian_handler Line | Count | Source | 56 | 62.8k | { | 57 | 62.8k | bool little_endian = is_little_endian(); | 58 | 62.8k | if (little_endian == little) { | 59 | 0 | memcpy(dest, pa, size); | 60 | 0 | } | 61 | 62.8k | else { | 62 | 62.8k | uint8_t* pa_ = (uint8_t*)pa; | 63 | 62.8k | uint8_t pa2_[8]; | 64 | 62.8k | switch (size) { | 65 | 25.6k | case 8: | 66 | 25.6k | pa2_[0] = pa_[7]; | 67 | 25.6k | pa2_[1] = pa_[6]; | 68 | 25.6k | pa2_[2] = pa_[5]; | 69 | 25.6k | pa2_[3] = pa_[4]; | 70 | 25.6k | pa2_[4] = pa_[3]; | 71 | 25.6k | pa2_[5] = pa_[2]; | 72 | 25.6k | pa2_[6] = pa_[1]; | 73 | 25.6k | pa2_[7] = pa_[0]; | 74 | 25.6k | break; | 75 | 31.4k | case 4: | 76 | 31.4k | pa2_[0] = pa_[3]; | 77 | 31.4k | pa2_[1] = pa_[2]; | 78 | 31.4k | pa2_[2] = pa_[1]; | 79 | 31.4k | pa2_[3] = pa_[0]; | 80 | 31.4k | break; | 81 | 771 | case 2: | 82 | 771 | pa2_[0] = pa_[1]; | 83 | 771 | pa2_[1] = pa_[0]; | 84 | 771 | break; | 85 | 4.94k | case 1: | 86 | 4.94k | pa2_[0] = pa_[0]; | 87 | 4.94k | break; | 88 | 0 | default: | 89 | 0 | BLOSC_TRACE_ERROR("Unhandled size: %d.", size); | 90 | 62.8k | } | 91 | 62.8k | memcpy(dest, pa2_, size); | 92 | 62.8k | } | 93 | 62.8k | } |
Unexecuted instantiation: codecs-registry.c:endian_handler Unexecuted instantiation: tuners-registry.c:endian_handler Unexecuted instantiation: filters-registry.c:endian_handler |
94 | | |
95 | | /* |
96 | | * Convert a chunk count to the serialized offsets payload size. |
97 | | * |
98 | | * Security rationale: frame metadata can be attacker-controlled, and the offsets payload |
99 | | * eventually flows into APIs that accept int32 byte lengths. This helper enforces a |
100 | | * single overflow-checked conversion so callers cannot accidentally truncate |
101 | | * nchunks * sizeof(int64_t) into a smaller signed length. |
102 | | */ |
103 | 15.8k | static inline bool blosc2_nchunks_to_offsets_nbytes(int64_t nchunks, int32_t *off_nbytes) { |
104 | 15.8k | const int64_t max_nchunks = INT32_MAX / (int64_t)sizeof(int64_t); |
105 | 15.8k | if (nchunks < 0 || nchunks > max_nchunks) { |
106 | 5 | return false; |
107 | 5 | } |
108 | 15.8k | if (off_nbytes != NULL) { |
109 | 15.8k | *off_nbytes = (int32_t)(nchunks * (int64_t)sizeof(int64_t)); |
110 | 15.8k | } |
111 | 15.8k | return true; |
112 | 15.8k | } Unexecuted instantiation: blosc2.c:blosc2_nchunks_to_offsets_nbytes Unexecuted instantiation: schunk.c:blosc2_nchunks_to_offsets_nbytes frame.c:blosc2_nchunks_to_offsets_nbytes Line | Count | Source | 103 | 15.8k | static inline bool blosc2_nchunks_to_offsets_nbytes(int64_t nchunks, int32_t *off_nbytes) { | 104 | 15.8k | const int64_t max_nchunks = INT32_MAX / (int64_t)sizeof(int64_t); | 105 | 15.8k | if (nchunks < 0 || nchunks > max_nchunks) { | 106 | 5 | return false; | 107 | 5 | } | 108 | 15.8k | if (off_nbytes != NULL) { | 109 | 15.8k | *off_nbytes = (int32_t)(nchunks * (int64_t)sizeof(int64_t)); | 110 | 15.8k | } | 111 | | return true; | 112 | 15.8k | } |
Unexecuted instantiation: codecs-registry.c:blosc2_nchunks_to_offsets_nbytes Unexecuted instantiation: tuners-registry.c:blosc2_nchunks_to_offsets_nbytes Unexecuted instantiation: filters-registry.c:blosc2_nchunks_to_offsets_nbytes |
113 | | |
114 | | /* Copy 4 bytes from @p *pa to int32_t, changing endianness if necessary. */ |
115 | 153k | static inline int32_t sw32_(const void* pa) { |
116 | 153k | int32_t idest; |
117 | | |
118 | 153k | bool little_endian = is_little_endian(); |
119 | 153k | if (little_endian) { |
120 | 153k | memcpy(&idest, pa, sizeof(idest)); |
121 | 153k | } |
122 | 0 | else { |
123 | 0 | #if defined (__GNUC__) |
124 | 0 | return __builtin_bswap32(*(unsigned int *)pa); |
125 | | #elif defined (_MSC_VER) /* Visual Studio */ |
126 | | return _byteswap_ulong(*(unsigned int *)pa); |
127 | | #else |
128 | | const uint8_t *pa_ = (const uint8_t *)pa; |
129 | | uint8_t *dest = (uint8_t *)&idest; |
130 | | dest[0] = pa_[3]; |
131 | | dest[1] = pa_[2]; |
132 | | dest[2] = pa_[1]; |
133 | | dest[3] = pa_[0]; |
134 | | #endif |
135 | 0 | } |
136 | 153k | return idest; |
137 | 153k | } Line | Count | Source | 115 | 153k | static inline int32_t sw32_(const void* pa) { | 116 | 153k | int32_t idest; | 117 | | | 118 | 153k | bool little_endian = is_little_endian(); | 119 | 153k | if (little_endian) { | 120 | 153k | memcpy(&idest, pa, sizeof(idest)); | 121 | 153k | } | 122 | 0 | else { | 123 | 0 | #if defined (__GNUC__) | 124 | 0 | return __builtin_bswap32(*(unsigned int *)pa); | 125 | | #elif defined (_MSC_VER) /* Visual Studio */ | 126 | | return _byteswap_ulong(*(unsigned int *)pa); | 127 | | #else | 128 | | const uint8_t *pa_ = (const uint8_t *)pa; | 129 | | uint8_t *dest = (uint8_t *)&idest; | 130 | | dest[0] = pa_[3]; | 131 | | dest[1] = pa_[2]; | 132 | | dest[2] = pa_[1]; | 133 | | dest[3] = pa_[0]; | 134 | | #endif | 135 | 0 | } | 136 | 153k | return idest; | 137 | 153k | } |
Unexecuted instantiation: schunk.c:sw32_ Unexecuted instantiation: frame.c:sw32_ Unexecuted instantiation: codecs-registry.c:sw32_ Unexecuted instantiation: tuners-registry.c:sw32_ Unexecuted instantiation: filters-registry.c:sw32_ |
138 | | |
139 | | /* Copy 4 bytes from int32_t to @p *dest, changing endianness if necessary. */ |
140 | 827k | static inline void _sw32(void* dest, int32_t a) { |
141 | 827k | uint8_t* dest_ = (uint8_t*)dest; |
142 | 827k | uint8_t* pa = (uint8_t*)&a; |
143 | | |
144 | 827k | bool little_endian = is_little_endian(); |
145 | 827k | if (little_endian) { |
146 | 827k | memcpy(dest_, &a, sizeof(a));; |
147 | 827k | } |
148 | 0 | else { |
149 | 0 | #if defined (__GNUC__) |
150 | 0 | *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa); |
151 | | #elif defined (_MSC_VER) /* Visual Studio */ |
152 | | *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa); |
153 | | #else |
154 | | dest_[0] = pa[3]; |
155 | | dest_[1] = pa[2]; |
156 | | dest_[2] = pa[1]; |
157 | | dest_[3] = pa[0]; |
158 | | #endif |
159 | 0 | } |
160 | 827k | } Line | Count | Source | 140 | 827k | static inline void _sw32(void* dest, int32_t a) { | 141 | 827k | uint8_t* dest_ = (uint8_t*)dest; | 142 | 827k | uint8_t* pa = (uint8_t*)&a; | 143 | | | 144 | 827k | bool little_endian = is_little_endian(); | 145 | 827k | if (little_endian) { | 146 | 827k | memcpy(dest_, &a, sizeof(a));; | 147 | 827k | } | 148 | 0 | else { | 149 | 0 | #if defined (__GNUC__) | 150 | 0 | *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa); | 151 | | #elif defined (_MSC_VER) /* Visual Studio */ | 152 | | *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa); | 153 | | #else | 154 | | dest_[0] = pa[3]; | 155 | | dest_[1] = pa[2]; | 156 | | dest_[2] = pa[1]; | 157 | | dest_[3] = pa[0]; | 158 | | #endif | 159 | 0 | } | 160 | 827k | } |
Unexecuted instantiation: schunk.c:_sw32 Unexecuted instantiation: frame.c:_sw32 Unexecuted instantiation: codecs-registry.c:_sw32 Unexecuted instantiation: tuners-registry.c:_sw32 Unexecuted instantiation: filters-registry.c:_sw32 |
161 | | |
162 | | /* Reverse swap bits in a 32-bit integer */ |
163 | 0 | static inline int32_t bswap32_(int32_t a) { |
164 | 0 | #if defined (__GNUC__) |
165 | 0 | return __builtin_bswap32(a); |
166 | |
|
167 | | #elif defined (_MSC_VER) /* Visual Studio */ |
168 | | return _byteswap_ulong(a); |
169 | | #else |
170 | | a = ((a & 0x000000FF) << 24) | |
171 | | ((a & 0x0000FF00) << 8) | |
172 | | ((a & 0x00FF0000) >> 8) | |
173 | | ((a & 0xFF000000) >> 24); |
174 | | return a; |
175 | | #endif |
176 | 0 | } Unexecuted instantiation: blosc2.c:bswap32_ Unexecuted instantiation: schunk.c:bswap32_ Unexecuted instantiation: frame.c:bswap32_ Unexecuted instantiation: codecs-registry.c:bswap32_ Unexecuted instantiation: tuners-registry.c:bswap32_ Unexecuted instantiation: filters-registry.c:bswap32_ |
177 | | |
178 | | /** |
179 | | * @brief Register a filter in Blosc. |
180 | | * |
181 | | * @param filter The filter to register. |
182 | | * |
183 | | * @return 0 if succeeds. Else a negative code is returned. |
184 | | */ |
185 | | int register_filter_private(blosc2_filter *filter); |
186 | | |
187 | | /** |
188 | | * @brief Register a codec in Blosc. |
189 | | * |
190 | | * @param codec The codec to register. |
191 | | * |
192 | | * @return 0 if succeeds. Else a negative code is returned. |
193 | | */ |
194 | | int register_codec_private(blosc2_codec *codec); |
195 | | |
196 | | |
197 | | /** |
198 | | * @brief Register a tune in Blosc. |
199 | | * |
200 | | * @param tune The tune to register. |
201 | | * |
202 | | * @return 0 if succeeds. Else a negative code is returned. |
203 | | */ |
204 | | int register_tuner_private(blosc2_tuner *tuner); |
205 | | |
206 | | int fill_tuner(blosc2_tuner *tuner); |
207 | | |
208 | | extern blosc2_tuner g_tuners[256]; |
209 | | extern int g_ntuners; |
210 | | |
211 | | |
212 | | #if defined(_WIN32) |
213 | | #include <windows.h> |
214 | | #ifndef PATH_MAX |
215 | | #define PATH_MAX MAX_PATH |
216 | | #endif |
217 | | #define RTLD_LAZY 0x000 |
218 | | #define popen _popen |
219 | | #define pclose _pclose |
220 | | |
221 | | static struct { |
222 | | long lasterror; |
223 | | const char *err_rutin; |
224 | | } |
225 | | var = { |
226 | | 0, |
227 | | NULL |
228 | | }; |
229 | | |
230 | | static inline void *dlopen (const char *filename, int flags) { |
231 | | BLOSC_UNUSED_PARAM(flags); |
232 | | HINSTANCE hInst; |
233 | | hInst = LoadLibrary(filename); |
234 | | if (hInst==NULL) { |
235 | | var.lasterror = GetLastError(); |
236 | | var.err_rutin = "dlopen"; |
237 | | } |
238 | | |
239 | | return hInst; |
240 | | } |
241 | | |
242 | | static inline void *dlsym(void *handle, const char *name) { |
243 | | FARPROC fp; |
244 | | fp = GetProcAddress((HINSTANCE)handle, name); |
245 | | if (!fp) { |
246 | | var.lasterror = GetLastError (); |
247 | | var.err_rutin = "dlsym"; |
248 | | } |
249 | | return (void *)(intptr_t)fp; |
250 | | } |
251 | | |
252 | | static inline int dlclose(void *handle) { |
253 | | bool ok = FreeLibrary((HINSTANCE)handle); |
254 | | if (!ok) { |
255 | | var.lasterror = GetLastError(); |
256 | | var.err_rutin = "dlclose"; |
257 | | return BLOSC2_ERROR_FAILURE; |
258 | | } |
259 | | return BLOSC2_ERROR_SUCCESS; |
260 | | } |
261 | | |
262 | | static inline const char *dlerror (void) { |
263 | | static char errstr [88]; |
264 | | if (var.lasterror) { |
265 | | snprintf(errstr, sizeof(errstr), "%s error #%ld", var.err_rutin, var.lasterror); |
266 | | return errstr; |
267 | | } else { |
268 | | return NULL; |
269 | | } |
270 | | } |
271 | | #else |
272 | | #include <dlfcn.h> |
273 | | #endif |
274 | | |
275 | 15 | static inline bool blosc2_valid_plugin_name(const char *plugin_name) { |
276 | 15 | if (plugin_name == NULL || plugin_name[0] == '\0') { |
277 | 0 | return false; |
278 | 0 | } |
279 | 93 | for (const unsigned char *p = (const unsigned char *)plugin_name; *p != '\0'; ++p) { |
280 | 78 | if (!isalnum(*p) && *p != '_') { |
281 | 0 | return false; |
282 | 0 | } |
283 | 78 | } |
284 | 15 | return true; |
285 | 15 | } blosc2.c:blosc2_valid_plugin_name Line | Count | Source | 275 | 15 | static inline bool blosc2_valid_plugin_name(const char *plugin_name) { | 276 | 15 | if (plugin_name == NULL || plugin_name[0] == '\0') { | 277 | 0 | return false; | 278 | 0 | } | 279 | 93 | for (const unsigned char *p = (const unsigned char *)plugin_name; *p != '\0'; ++p) { | 280 | 78 | if (!isalnum(*p) && *p != '_') { | 281 | 0 | return false; | 282 | 0 | } | 283 | 78 | } | 284 | 15 | return true; | 285 | 15 | } |
Unexecuted instantiation: schunk.c:blosc2_valid_plugin_name Unexecuted instantiation: frame.c:blosc2_valid_plugin_name Unexecuted instantiation: codecs-registry.c:blosc2_valid_plugin_name Unexecuted instantiation: tuners-registry.c:blosc2_valid_plugin_name Unexecuted instantiation: filters-registry.c:blosc2_valid_plugin_name |
286 | | |
287 | | |
288 | 10 | static inline int get_libpath(char *plugin_name, char *libpath, char *python_version) { |
289 | 10 | BLOSC_TRACE_INFO("Trying to get plugin path with python%s\n", python_version); |
290 | 10 | char python_cmd[PATH_MAX] = {0}; |
291 | 10 | if (!blosc2_valid_plugin_name(plugin_name)) { |
292 | 0 | BLOSC_TRACE_ERROR("Invalid plugin name"); |
293 | 0 | return BLOSC2_ERROR_INVALID_PARAM; |
294 | 0 | } |
295 | 10 | int written = snprintf(python_cmd, sizeof(python_cmd), |
296 | 10 | "python%s -c \"import blosc2_%s; blosc2_%s.print_libpath()\"", |
297 | 10 | python_version, plugin_name, plugin_name); |
298 | 10 | if (written < 0 || (size_t)written >= sizeof(python_cmd)) { |
299 | 0 | BLOSC_TRACE_ERROR("Python command is too long"); |
300 | 0 | return BLOSC2_ERROR_FAILURE; |
301 | 0 | } |
302 | 10 | FILE *fp = popen(python_cmd, "r"); |
303 | 10 | if (fp == NULL) { |
304 | 0 | BLOSC_TRACE_ERROR("Could not run python"); |
305 | 0 | return BLOSC2_ERROR_FAILURE; |
306 | 0 | } |
307 | 10 | if (fgets(libpath, PATH_MAX, fp) == NULL) { |
308 | 10 | BLOSC_TRACE_ERROR("Could not read python output"); |
309 | 10 | pclose(fp); |
310 | 10 | return BLOSC2_ERROR_FAILURE; |
311 | 10 | } |
312 | 0 | pclose(fp); |
313 | |
|
314 | 0 | return BLOSC2_ERROR_SUCCESS; |
315 | 10 | } Line | Count | Source | 288 | 10 | static inline int get_libpath(char *plugin_name, char *libpath, char *python_version) { | 289 | 10 | BLOSC_TRACE_INFO("Trying to get plugin path with python%s\n", python_version); | 290 | 10 | char python_cmd[PATH_MAX] = {0}; | 291 | 10 | if (!blosc2_valid_plugin_name(plugin_name)) { | 292 | 0 | BLOSC_TRACE_ERROR("Invalid plugin name"); | 293 | 0 | return BLOSC2_ERROR_INVALID_PARAM; | 294 | 0 | } | 295 | 10 | int written = snprintf(python_cmd, sizeof(python_cmd), | 296 | 10 | "python%s -c \"import blosc2_%s; blosc2_%s.print_libpath()\"", | 297 | 10 | python_version, plugin_name, plugin_name); | 298 | 10 | if (written < 0 || (size_t)written >= sizeof(python_cmd)) { | 299 | 0 | BLOSC_TRACE_ERROR("Python command is too long"); | 300 | 0 | return BLOSC2_ERROR_FAILURE; | 301 | 0 | } | 302 | 10 | FILE *fp = popen(python_cmd, "r"); | 303 | 10 | if (fp == NULL) { | 304 | 0 | BLOSC_TRACE_ERROR("Could not run python"); | 305 | 0 | return BLOSC2_ERROR_FAILURE; | 306 | 0 | } | 307 | 10 | if (fgets(libpath, PATH_MAX, fp) == NULL) { | 308 | 10 | BLOSC_TRACE_ERROR("Could not read python output"); | 309 | 10 | pclose(fp); | 310 | 10 | return BLOSC2_ERROR_FAILURE; | 311 | 10 | } | 312 | 0 | pclose(fp); | 313 | |
| 314 | 0 | return BLOSC2_ERROR_SUCCESS; | 315 | 10 | } |
Unexecuted instantiation: schunk.c:get_libpath Unexecuted instantiation: frame.c:get_libpath Unexecuted instantiation: codecs-registry.c:get_libpath Unexecuted instantiation: tuners-registry.c:get_libpath Unexecuted instantiation: filters-registry.c:get_libpath |
316 | | |
317 | 5 | static inline void* load_lib(char *plugin_name, char *libpath) { |
318 | 5 | if (!blosc2_valid_plugin_name(plugin_name)) { |
319 | 0 | BLOSC_TRACE_ERROR("Invalid plugin name"); |
320 | 0 | return NULL; |
321 | 0 | } |
322 | | // Attempt to directly load the library by name |
323 | | #if defined(_WIN32) |
324 | | // Windows dynamic library (DLL) format |
325 | | snprintf(libpath, PATH_MAX, "blosc2_%s.dll", plugin_name); |
326 | | #else |
327 | | // Unix/Linux/Mac OS dynamic library (.so) format |
328 | 5 | snprintf(libpath, PATH_MAX, "libblosc2_%s.so", plugin_name); |
329 | 5 | #endif |
330 | 5 | void* loaded_lib = dlopen(libpath, RTLD_LAZY); |
331 | 5 | if (loaded_lib != NULL) { |
332 | 0 | BLOSC_TRACE_INFO("Successfully loaded %s directly\n", libpath); |
333 | 0 | return loaded_lib; |
334 | 5 | } else { |
335 | | #if defined(_WIN32) |
336 | | BLOSC_TRACE_INFO("Failed to load %s directly, error: %lu\n", libpath, GetLastError()); |
337 | | #else |
338 | 5 | BLOSC_TRACE_INFO("Failed to load %s directly, error: %s\n", libpath, dlerror()); |
339 | 5 | #endif |
340 | 5 | } |
341 | | // If direct loading fails, fallback to using Python to find the library path |
342 | 5 | if (get_libpath(plugin_name, libpath, "") < 0 && get_libpath(plugin_name, libpath, "3") < 0) { |
343 | 5 | BLOSC_TRACE_ERROR("Problems when running python or python3 for getting plugin path"); |
344 | 5 | return NULL; |
345 | 5 | } |
346 | | |
347 | 0 | if (strlen(libpath) == 0) { |
348 | 0 | BLOSC_TRACE_ERROR("Could not find plugin libpath"); |
349 | 0 | return NULL; |
350 | 0 | } |
351 | | |
352 | | // Try to load the library again with the path from Python |
353 | 0 | loaded_lib = dlopen(libpath, RTLD_LAZY); |
354 | 0 | if (loaded_lib == NULL) { |
355 | 0 | BLOSC_TRACE_ERROR("Attempt to load plugin in path '%s' failed with error: %s", libpath, dlerror()); |
356 | 0 | } else { |
357 | 0 | BLOSC_TRACE_INFO("Successfully loaded library with Python path: %s\n", libpath); |
358 | 0 | } |
359 | |
|
360 | 0 | return loaded_lib; |
361 | 0 | } Line | Count | Source | 317 | 5 | static inline void* load_lib(char *plugin_name, char *libpath) { | 318 | 5 | if (!blosc2_valid_plugin_name(plugin_name)) { | 319 | 0 | BLOSC_TRACE_ERROR("Invalid plugin name"); | 320 | 0 | return NULL; | 321 | 0 | } | 322 | | // Attempt to directly load the library by name | 323 | | #if defined(_WIN32) | 324 | | // Windows dynamic library (DLL) format | 325 | | snprintf(libpath, PATH_MAX, "blosc2_%s.dll", plugin_name); | 326 | | #else | 327 | | // Unix/Linux/Mac OS dynamic library (.so) format | 328 | 5 | snprintf(libpath, PATH_MAX, "libblosc2_%s.so", plugin_name); | 329 | 5 | #endif | 330 | 5 | void* loaded_lib = dlopen(libpath, RTLD_LAZY); | 331 | 5 | if (loaded_lib != NULL) { | 332 | 0 | BLOSC_TRACE_INFO("Successfully loaded %s directly\n", libpath); | 333 | 0 | return loaded_lib; | 334 | 5 | } else { | 335 | | #if defined(_WIN32) | 336 | | BLOSC_TRACE_INFO("Failed to load %s directly, error: %lu\n", libpath, GetLastError()); | 337 | | #else | 338 | 5 | BLOSC_TRACE_INFO("Failed to load %s directly, error: %s\n", libpath, dlerror()); | 339 | 5 | #endif | 340 | 5 | } | 341 | | // If direct loading fails, fallback to using Python to find the library path | 342 | 5 | if (get_libpath(plugin_name, libpath, "") < 0 && get_libpath(plugin_name, libpath, "3") < 0) { | 343 | 5 | BLOSC_TRACE_ERROR("Problems when running python or python3 for getting plugin path"); | 344 | 5 | return NULL; | 345 | 5 | } | 346 | | | 347 | 0 | if (strlen(libpath) == 0) { | 348 | 0 | BLOSC_TRACE_ERROR("Could not find plugin libpath"); | 349 | 0 | return NULL; | 350 | 0 | } | 351 | | | 352 | | // Try to load the library again with the path from Python | 353 | 0 | loaded_lib = dlopen(libpath, RTLD_LAZY); | 354 | 0 | if (loaded_lib == NULL) { | 355 | 0 | BLOSC_TRACE_ERROR("Attempt to load plugin in path '%s' failed with error: %s", libpath, dlerror()); | 356 | 0 | } else { | 357 | 0 | BLOSC_TRACE_INFO("Successfully loaded library with Python path: %s\n", libpath); | 358 | 0 | } | 359 | |
| 360 | 0 | return loaded_lib; | 361 | 0 | } |
Unexecuted instantiation: schunk.c:load_lib Unexecuted instantiation: frame.c:load_lib Unexecuted instantiation: codecs-registry.c:load_lib Unexecuted instantiation: tuners-registry.c:load_lib Unexecuted instantiation: filters-registry.c:load_lib |
362 | | |
363 | | |
364 | | #endif /* BLOSC_BLOSC_PRIVATE_H */ |