Coverage Report

Created: 2024-07-27 06:20

/src/c-blosc2/blosc/blosc-private.h
Line
Count
Source (jump to first uncovered line)
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
22
/*********************************************************************
23
24
  Utility functions meant to be used internally.
25
26
*********************************************************************/
27
28
0
#define to_little(dest, src, itemsize)    endian_handler(true, dest, src, itemsize)
29
#define from_little(dest, src, itemsize)  endian_handler(true, dest, src, itemsize)
30
0
#define to_big(dest, src, itemsize)       endian_handler(false, dest, src, itemsize)
31
0
#define from_big(dest, src, itemsize)     endian_handler(false, dest, src, itemsize)
32
33
34
// Return true if platform is little endian; else false
35
552k
static bool is_little_endian(void) {
36
552k
  static const int i = 1;
37
552k
  char* p = (char*)&i;
38
39
552k
  if (p[0] == 1) {
40
552k
    return true;
41
552k
  }
42
0
  else {
43
0
    return false;
44
0
  }
45
552k
}
blosc2.c:is_little_endian
Line
Count
Source
35
552k
static bool is_little_endian(void) {
36
552k
  static const int i = 1;
37
552k
  char* p = (char*)&i;
38
39
552k
  if (p[0] == 1) {
40
552k
    return true;
41
552k
  }
42
0
  else {
43
0
    return false;
44
0
  }
45
552k
}
Unexecuted instantiation: schunk.c:is_little_endian
Unexecuted instantiation: frame.c:is_little_endian
Unexecuted instantiation: codecs-registry.c:is_little_endian
Unexecuted instantiation: tuners-registry.c:is_little_endian
Unexecuted instantiation: filters-registry.c:is_little_endian
46
47
48
static inline void endian_handler(bool little, void *dest, const void *pa, int size)
49
0
{
50
0
  bool little_endian = is_little_endian();
51
0
  if (little_endian == little) {
52
0
    memcpy(dest, pa, size);
53
0
  }
54
0
  else {
55
0
    uint8_t* pa_ = (uint8_t*)pa;
56
0
    uint8_t pa2_[8];
57
0
    switch (size) {
58
0
      case 8:
59
0
        pa2_[0] = pa_[7];
60
0
        pa2_[1] = pa_[6];
61
0
        pa2_[2] = pa_[5];
62
0
        pa2_[3] = pa_[4];
63
0
        pa2_[4] = pa_[3];
64
0
        pa2_[5] = pa_[2];
65
0
        pa2_[6] = pa_[1];
66
0
        pa2_[7] = pa_[0];
67
0
        break;
68
0
      case 4:
69
0
        pa2_[0] = pa_[3];
70
0
        pa2_[1] = pa_[2];
71
0
        pa2_[2] = pa_[1];
72
0
        pa2_[3] = pa_[0];
73
0
        break;
74
0
      case 2:
75
0
        pa2_[0] = pa_[1];
76
0
        pa2_[1] = pa_[0];
77
0
        break;
78
0
      case 1:
79
0
        pa2_[0] = pa_[0];
80
0
        break;
81
0
      default:
82
0
        BLOSC_TRACE_ERROR("Unhandled size: %d.", size);
83
0
    }
84
0
    memcpy(dest, pa2_, size);
85
0
  }
86
0
}
Unexecuted instantiation: blosc2.c:endian_handler
Unexecuted instantiation: schunk.c:endian_handler
Unexecuted instantiation: frame.c:endian_handler
Unexecuted instantiation: codecs-registry.c:endian_handler
Unexecuted instantiation: tuners-registry.c:endian_handler
Unexecuted instantiation: filters-registry.c:endian_handler
87
88
/* Copy 4 bytes from @p *pa to int32_t, changing endianness if necessary. */
89
82.2k
static inline int32_t sw32_(const void* pa) {
90
82.2k
  int32_t idest;
91
92
82.2k
  bool little_endian = is_little_endian();
93
82.2k
  if (little_endian) {
94
82.2k
    idest = *(int32_t *)pa;
95
82.2k
  }
96
0
  else {
97
0
#if defined (__GNUC__)
98
0
    return __builtin_bswap32(*(unsigned int *)pa);
99
#elif defined (_MSC_VER) /* Visual Studio */
100
    return _byteswap_ulong(*(unsigned int *)pa);
101
#else
102
    uint8_t *dest = (uint8_t *)&idest;
103
    dest[0] = pa_[3];
104
    dest[1] = pa_[2];
105
    dest[2] = pa_[1];
106
    dest[3] = pa_[0];
107
#endif
108
0
  }
109
82.2k
  return idest;
110
82.2k
}
blosc2.c:sw32_
Line
Count
Source
89
82.2k
static inline int32_t sw32_(const void* pa) {
90
82.2k
  int32_t idest;
91
92
82.2k
  bool little_endian = is_little_endian();
93
82.2k
  if (little_endian) {
94
82.2k
    idest = *(int32_t *)pa;
95
82.2k
  }
96
0
  else {
97
0
#if defined (__GNUC__)
98
0
    return __builtin_bswap32(*(unsigned int *)pa);
99
#elif defined (_MSC_VER) /* Visual Studio */
100
    return _byteswap_ulong(*(unsigned int *)pa);
101
#else
102
    uint8_t *dest = (uint8_t *)&idest;
103
    dest[0] = pa_[3];
104
    dest[1] = pa_[2];
105
    dest[2] = pa_[1];
106
    dest[3] = pa_[0];
107
#endif
108
0
  }
109
82.2k
  return idest;
110
82.2k
}
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_
111
112
/* Copy 4 bytes from int32_t to @p *dest, changing endianness if necessary. */
113
393k
static inline void _sw32(void* dest, int32_t a) {
114
393k
  uint8_t* dest_ = (uint8_t*)dest;
115
393k
  uint8_t* pa = (uint8_t*)&a;
116
117
393k
  bool little_endian = is_little_endian();
118
393k
  if (little_endian) {
119
393k
    *(int32_t *)dest_ = a;
120
393k
  }
121
0
  else {
122
0
#if defined (__GNUC__)
123
0
    *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa);
124
#elif defined (_MSC_VER) /* Visual Studio */
125
    *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa);
126
#else
127
    dest_[0] = pa[3];
128
    dest_[1] = pa[2];
129
    dest_[2] = pa[1];
130
    dest_[3] = pa[0];
131
#endif
132
0
  }
133
393k
}
blosc2.c:_sw32
Line
Count
Source
113
393k
static inline void _sw32(void* dest, int32_t a) {
114
393k
  uint8_t* dest_ = (uint8_t*)dest;
115
393k
  uint8_t* pa = (uint8_t*)&a;
116
117
393k
  bool little_endian = is_little_endian();
118
393k
  if (little_endian) {
119
393k
    *(int32_t *)dest_ = a;
120
393k
  }
121
0
  else {
122
0
#if defined (__GNUC__)
123
0
    *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa);
124
#elif defined (_MSC_VER) /* Visual Studio */
125
    *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa);
126
#else
127
    dest_[0] = pa[3];
128
    dest_[1] = pa[2];
129
    dest_[2] = pa[1];
130
    dest_[3] = pa[0];
131
#endif
132
0
  }
133
393k
}
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
134
135
/* Reverse swap bits in a 32-bit integer */
136
0
static inline int32_t bswap32_(int32_t a) {
137
0
#if defined (__GNUC__)
138
0
  return __builtin_bswap32(a);
139
140
#elif defined (_MSC_VER) /* Visual Studio */
141
  return _byteswap_ulong(a);
142
#else
143
  a = ((a & 0x000000FF) << 24) |
144
      ((a & 0x0000FF00) <<  8) |
145
      ((a & 0x00FF0000) >>  8) |
146
      ((a & 0xFF000000) >> 24);
147
  return a;
148
#endif
149
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_
150
151
/**
152
 * @brief Register a filter in Blosc.
153
 *
154
 * @param filter The filter to register.
155
 *
156
 * @return 0 if succeeds. Else a negative code is returned.
157
 */
158
int register_filter_private(blosc2_filter *filter);
159
160
/**
161
 * @brief Register a codec in Blosc.
162
 *
163
 * @param codec The codec to register.
164
 *
165
 * @return 0 if succeeds. Else a negative code is returned.
166
 */
167
int register_codec_private(blosc2_codec *codec);
168
169
170
/**
171
 * @brief Register a tune in Blosc.
172
 *
173
 * @param tune The tune to register.
174
 *
175
 * @return 0 if succeeds. Else a negative code is returned.
176
 */
177
int register_tuner_private(blosc2_tuner *tuner);
178
179
int fill_tuner(blosc2_tuner *tuner);
180
181
extern blosc2_tuner g_tuners[256];
182
extern int g_ntuners;
183
184
185
#if defined(_WIN32)
186
#include <windows.h>
187
#ifndef PATH_MAX
188
#define PATH_MAX MAX_PATH
189
#endif
190
#define RTLD_LAZY   0x000
191
#define popen _popen
192
#define pclose _pclose
193
194
static struct {
195
    long lasterror;
196
    const char *err_rutin;
197
}
198
var = {
199
    0,
200
    NULL
201
};
202
203
static inline void *dlopen (const char *filename, int flags) {
204
  BLOSC_UNUSED_PARAM(flags);
205
  HINSTANCE hInst;
206
  hInst = LoadLibrary(filename);
207
  if (hInst==NULL) {
208
    var.lasterror = GetLastError();
209
    var.err_rutin = "dlopen";
210
  }
211
212
  return hInst;
213
}
214
215
static inline void *dlsym(void *handle, const char *name) {
216
  FARPROC fp;
217
  fp = GetProcAddress((HINSTANCE)handle, name);
218
  if (!fp) {
219
    var.lasterror = GetLastError ();
220
    var.err_rutin = "dlsym";
221
  }
222
  return (void *)(intptr_t)fp;
223
}
224
225
static inline int dlclose(void *handle) {
226
  bool ok = FreeLibrary((HINSTANCE)handle);
227
  if (!ok) {
228
    var.lasterror = GetLastError();
229
    var.err_rutin = "dlclose";
230
    return BLOSC2_ERROR_FAILURE;
231
  }
232
  return BLOSC2_ERROR_SUCCESS;
233
}
234
235
static inline const char *dlerror (void) {
236
  static char errstr [88];
237
  if (var.lasterror) {
238
      sprintf (errstr, "%s error #%ld", var.err_rutin, var.lasterror);
239
      return errstr;
240
  } else {
241
      return NULL;
242
  }
243
}
244
#else
245
#include <dlfcn.h>
246
#endif
247
248
249
0
static inline int get_libpath(char *plugin_name, char *libpath, char *python_version) {
250
0
  BLOSC_TRACE_INFO("Trying to get plugin path with python%s\n", python_version);
251
0
  char python_cmd[PATH_MAX] = {0};
252
0
  sprintf(python_cmd, "python%s -c \"import blosc2_%s; blosc2_%s.print_libpath()\"", python_version, plugin_name, plugin_name);
253
0
  FILE *fp = popen(python_cmd, "r");
254
0
  if (fp == NULL) {
255
0
    BLOSC_TRACE_ERROR("Could not run python");
256
0
    return BLOSC2_ERROR_FAILURE;
257
0
  }
258
0
  if (fgets(libpath, PATH_MAX, fp) == NULL) {
259
0
    BLOSC_TRACE_ERROR("Could not read python output");
260
0
    pclose(fp);
261
0
    return BLOSC2_ERROR_FAILURE;
262
0
  }
263
0
  pclose(fp);
264
265
0
  return BLOSC2_ERROR_SUCCESS;
266
0
}
Unexecuted instantiation: blosc2.c:get_libpath
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
267
268
0
static inline void* load_lib(char *plugin_name, char *libpath) {
269
    // Attempt to directly load the library by name
270
#if defined(_WIN32)
271
    // Windows dynamic library (DLL) format
272
    snprintf(libpath, PATH_MAX, "blosc2_%s.dll", plugin_name);
273
#else
274
    // Unix/Linux/Mac OS dynamic library (.so) format
275
0
    snprintf(libpath, PATH_MAX, "libblosc2_%s.so", plugin_name);
276
0
#endif
277
0
    void* loaded_lib = dlopen(libpath, RTLD_LAZY);
278
0
    if (loaded_lib != NULL) {
279
0
        BLOSC_TRACE_INFO("Successfully loaded %s directly\n", libpath);
280
0
        return loaded_lib;
281
0
    } else {
282
#if defined(_WIN32)
283
        BLOSC_TRACE_INFO("Failed to load %s directly, error: %s\n", libpath, GetLastError());
284
#else
285
0
        BLOSC_TRACE_INFO("Failed to load %s directly, error: %s\n", libpath, dlerror());
286
0
#endif
287
0
    }
288
    // If direct loading fails, fallback to using Python to find the library path
289
0
    if (get_libpath(plugin_name, libpath, "") < 0 && get_libpath(plugin_name, libpath, "3") < 0) {
290
0
        BLOSC_TRACE_ERROR("Problems when running python or python3 for getting plugin path");
291
0
        return NULL;
292
0
    }
293
294
0
    if (strlen(libpath) == 0) {
295
0
        BLOSC_TRACE_ERROR("Could not find plugin libpath");
296
0
        return NULL;
297
0
    }
298
299
    // Try to load the library again with the path from Python
300
0
    loaded_lib = dlopen(libpath, RTLD_LAZY);
301
0
    if (loaded_lib == NULL) {
302
0
        BLOSC_TRACE_ERROR("Attempt to load plugin in path '%s' failed with error: %s", libpath, dlerror());
303
0
    } else {
304
0
        BLOSC_TRACE_INFO("Successfully loaded library with Python path: %s\n", libpath);
305
0
    }
306
307
0
    return loaded_lib;
308
0
}
Unexecuted instantiation: blosc2.c:load_lib
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
309
310
311
#endif /* BLOSC_BLOSC_PRIVATE_H */