Line | Count | Source (jump to first uncovered line) |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /* |
14 | | * Purpose: Extensible array testing functions. |
15 | | * |
16 | | */ |
17 | | |
18 | | /**********************/ |
19 | | /* Module Declaration */ |
20 | | /**********************/ |
21 | | |
22 | | #include "H5EAmodule.h" /* This source code file is part of the H5EA module */ |
23 | | #define H5EA_TESTING |
24 | | |
25 | | /***********************/ |
26 | | /* Other Packages Used */ |
27 | | /***********************/ |
28 | | |
29 | | /***********/ |
30 | | /* Headers */ |
31 | | /***********/ |
32 | | #include "H5private.h" /* Generic Functions */ |
33 | | #include "H5Eprivate.h" /* Error handling */ |
34 | | #include "H5EApkg.h" /* Extensible Arrays */ |
35 | | #include "H5FLprivate.h" /* Free Lists */ |
36 | | #include "H5VMprivate.h" /* Vector functions */ |
37 | | |
38 | | /****************/ |
39 | | /* Local Macros */ |
40 | | /****************/ |
41 | | |
42 | | /* Sanity checking value for callback contexts */ |
43 | 0 | #define H5EA__TEST_BOGUS_VAL 42 |
44 | | |
45 | | /******************/ |
46 | | /* Local Typedefs */ |
47 | | /******************/ |
48 | | |
49 | | /* Callback context */ |
50 | | typedef struct H5EA__test_ctx_t { |
51 | | uint32_t bogus; /* Placeholder field to verify that context is working */ |
52 | | H5EA__ctx_cb_t *cb; /* Pointer to context's callback action */ |
53 | | } H5EA__test_ctx_t; |
54 | | |
55 | | /********************/ |
56 | | /* Package Typedefs */ |
57 | | /********************/ |
58 | | |
59 | | /********************/ |
60 | | /* Local Prototypes */ |
61 | | /********************/ |
62 | | |
63 | | /* Extensible array class callbacks */ |
64 | | static void *H5EA__test_crt_context(void *udata); |
65 | | static herr_t H5EA__test_dst_context(void *ctx); |
66 | | static herr_t H5EA__test_fill(void *nat_blk, size_t nelmts); |
67 | | static herr_t H5EA__test_encode(void *raw, const void *elmt, size_t nelmts, void *ctx); |
68 | | static herr_t H5EA__test_decode(const void *raw, void *elmt, size_t nelmts, void *ctx); |
69 | | static herr_t H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt); |
70 | | static void *H5EA__test_crt_dbg_context(H5F_t H5_ATTR_UNUSED *f, haddr_t H5_ATTR_UNUSED obj_addr); |
71 | | static herr_t H5EA__test_dst_dbg_context(void *_ctx); |
72 | | |
73 | | /*********************/ |
74 | | /* Package Variables */ |
75 | | /*********************/ |
76 | | |
77 | | /* Extensible array testing class information */ |
78 | | const H5EA_class_t H5EA_CLS_TEST[1] = {{ |
79 | | H5EA_CLS_TEST_ID, /* Type of Extensible array */ |
80 | | "Testing", /* Name of Extensible Array class */ |
81 | | sizeof(uint64_t), /* Size of native element */ |
82 | | H5EA__test_crt_context, /* Create context */ |
83 | | H5EA__test_dst_context, /* Destroy context */ |
84 | | H5EA__test_fill, /* Fill block of missing elements callback */ |
85 | | H5EA__test_encode, /* Element encoding callback */ |
86 | | H5EA__test_decode, /* Element decoding callback */ |
87 | | H5EA__test_debug, /* Element debugging callback */ |
88 | | H5EA__test_crt_dbg_context, /* Create debugging context */ |
89 | | H5EA__test_dst_dbg_context /* Destroy debugging context */ |
90 | | }}; |
91 | | |
92 | | /*****************************/ |
93 | | /* Library Private Variables */ |
94 | | /*****************************/ |
95 | | |
96 | | /*******************/ |
97 | | /* Local Variables */ |
98 | | /*******************/ |
99 | | |
100 | | /* Declare a free list to manage the H5EA__test_ctx_t struct */ |
101 | | H5FL_DEFINE_STATIC(H5EA__test_ctx_t); |
102 | | |
103 | | /* Declare a free list to manage the H5EA__ctx_cb_t struct */ |
104 | | H5FL_DEFINE_STATIC(H5EA__ctx_cb_t); |
105 | | |
106 | | /*------------------------------------------------------------------------- |
107 | | * Function: H5EA__test_crt_context |
108 | | * |
109 | | * Purpose: Create context for callbacks |
110 | | * |
111 | | * Return: Success: non-NULL |
112 | | * Failure: NULL |
113 | | * |
114 | | *------------------------------------------------------------------------- |
115 | | */ |
116 | | static void * |
117 | | H5EA__test_crt_context(void *_udata) |
118 | 0 | { |
119 | 0 | H5EA__test_ctx_t *ctx; /* Context for callbacks */ |
120 | 0 | H5EA__ctx_cb_t *udata = (H5EA__ctx_cb_t *)_udata; /* User data for context */ |
121 | 0 | void *ret_value = NULL; |
122 | |
|
123 | 0 | FUNC_ENTER_PACKAGE |
124 | | |
125 | | /* Allocate new context structure */ |
126 | 0 | if (NULL == (ctx = H5FL_MALLOC(H5EA__test_ctx_t))) |
127 | 0 | HGOTO_ERROR(H5E_EARRAY, H5E_CANTALLOC, NULL, |
128 | 0 | "can't allocate extensible array client callback context"); |
129 | | |
130 | | /* Initialize the context */ |
131 | 0 | ctx->bogus = H5EA__TEST_BOGUS_VAL; |
132 | 0 | ctx->cb = udata; |
133 | | |
134 | | /* Set return value */ |
135 | 0 | ret_value = ctx; |
136 | |
|
137 | 0 | done: |
138 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
139 | 0 | } /* end H5EA__test_crt_context() */ |
140 | | |
141 | | /*------------------------------------------------------------------------- |
142 | | * Function: H5EA__test_dst_context |
143 | | * |
144 | | * Purpose: Destroy context for callbacks |
145 | | * |
146 | | * Return: Success: non-negative |
147 | | * Failure: negative |
148 | | * |
149 | | *------------------------------------------------------------------------- |
150 | | */ |
151 | | static herr_t |
152 | | H5EA__test_dst_context(void *_ctx) |
153 | 0 | { |
154 | 0 | H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */ |
155 | |
|
156 | 0 | FUNC_ENTER_PACKAGE_NOERR |
157 | | |
158 | | /* Sanity checks */ |
159 | 0 | assert(H5EA__TEST_BOGUS_VAL == ctx->bogus); |
160 | | |
161 | | /* Release context structure */ |
162 | 0 | ctx = H5FL_FREE(H5EA__test_ctx_t, ctx); |
163 | |
|
164 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
165 | 0 | } /* end H5EA__test_dst_context() */ |
166 | | |
167 | | /*------------------------------------------------------------------------- |
168 | | * Function: H5EA__test_fill |
169 | | * |
170 | | * Purpose: Fill "missing elements" in block of elements |
171 | | * |
172 | | * Return: Success: non-negative |
173 | | * Failure: negative |
174 | | * |
175 | | *------------------------------------------------------------------------- |
176 | | */ |
177 | | static herr_t |
178 | | H5EA__test_fill(void *nat_blk, size_t nelmts) |
179 | 0 | { |
180 | 0 | uint64_t fill_val = H5EA_TEST_FILL; /* Value to fill elements with */ |
181 | |
|
182 | 0 | FUNC_ENTER_PACKAGE_NOERR |
183 | | |
184 | | /* Sanity checks */ |
185 | 0 | assert(nat_blk); |
186 | 0 | assert(nelmts); |
187 | |
|
188 | 0 | H5VM_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts); |
189 | |
|
190 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
191 | 0 | } /* end H5EA__test_fill() */ |
192 | | |
193 | | /*------------------------------------------------------------------------- |
194 | | * Function: H5EA__test_encode |
195 | | * |
196 | | * Purpose: Encode an element from "native" to "raw" form |
197 | | * |
198 | | * Return: Success: non-negative |
199 | | * Failure: negative |
200 | | * |
201 | | *------------------------------------------------------------------------- |
202 | | */ |
203 | | static herr_t |
204 | | H5EA__test_encode(void *raw, const void *_elmt, size_t nelmts, void *_ctx) |
205 | 0 | { |
206 | 0 | H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */ |
207 | 0 | const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */ |
208 | 0 | herr_t ret_value = SUCCEED; |
209 | |
|
210 | 0 | FUNC_ENTER_PACKAGE |
211 | | |
212 | | /* Sanity checks */ |
213 | 0 | assert(raw); |
214 | 0 | assert(elmt); |
215 | 0 | assert(nelmts); |
216 | 0 | assert(H5EA__TEST_BOGUS_VAL == ctx->bogus); |
217 | | |
218 | | /* Check for callback action */ |
219 | 0 | if (ctx->cb) { |
220 | 0 | if ((*ctx->cb->encode)(elmt, nelmts, ctx->cb->udata) < 0) |
221 | 0 | HGOTO_ERROR(H5E_EARRAY, H5E_BADVALUE, FAIL, "extensible array testing callback action failed"); |
222 | 0 | } |
223 | | |
224 | | /* Encode native elements into raw elements */ |
225 | 0 | while (nelmts) { |
226 | | /* Encode element - advances 'raw' pointer */ |
227 | 0 | UINT64ENCODE(raw, *elmt); |
228 | | |
229 | | /* Advance native element pointer */ |
230 | 0 | elmt++; |
231 | | |
232 | | /* Decrement # of elements to encode */ |
233 | 0 | nelmts--; |
234 | 0 | } |
235 | |
|
236 | 0 | done: |
237 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
238 | 0 | } /* end H5EA__test_encode() */ |
239 | | |
240 | | /*------------------------------------------------------------------------- |
241 | | * Function: H5EA__test_decode |
242 | | * |
243 | | * Purpose: Decode an element from "raw" to "native" form |
244 | | * |
245 | | * Return: Success: non-negative |
246 | | * Failure: negative |
247 | | * |
248 | | *------------------------------------------------------------------------- |
249 | | */ |
250 | | static herr_t |
251 | | H5EA__test_decode(const void *_raw, void *_elmt, size_t nelmts, void H5_ATTR_NDEBUG_UNUSED *_ctx) |
252 | 0 | { |
253 | | #ifndef NDEBUG |
254 | | H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */ |
255 | | #endif /* NDEBUG */ |
256 | 0 | uint64_t *elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */ |
257 | 0 | const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */ |
258 | |
|
259 | 0 | FUNC_ENTER_PACKAGE_NOERR |
260 | | |
261 | | /* Sanity checks */ |
262 | 0 | assert(raw); |
263 | 0 | assert(elmt); |
264 | 0 | assert(nelmts); |
265 | 0 | assert(H5EA__TEST_BOGUS_VAL == ctx->bogus); |
266 | | |
267 | | /* Decode raw elements into native elements */ |
268 | 0 | while (nelmts) { |
269 | | /* Decode element - advances 'raw' pointer */ |
270 | 0 | UINT64DECODE(raw, *elmt); |
271 | | |
272 | | /* Advance native element pointer */ |
273 | 0 | elmt++; |
274 | | |
275 | | /* Decrement # of elements to decode */ |
276 | 0 | nelmts--; |
277 | 0 | } |
278 | |
|
279 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
280 | 0 | } /* end H5EA__test_decode() */ |
281 | | |
282 | | /*------------------------------------------------------------------------- |
283 | | * Function: H5EA__test_debug |
284 | | * |
285 | | * Purpose: Display an element for debugging |
286 | | * |
287 | | * Return: Success: non-negative |
288 | | * Failure: negative |
289 | | * |
290 | | *------------------------------------------------------------------------- |
291 | | */ |
292 | | static herr_t |
293 | | H5EA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt) |
294 | 0 | { |
295 | 0 | char temp_str[128]; /* Temporary string, for formatting */ |
296 | |
|
297 | 0 | FUNC_ENTER_PACKAGE_NOERR |
298 | | |
299 | | /* Sanity checks */ |
300 | 0 | assert(stream); |
301 | 0 | assert(elmt); |
302 | | |
303 | | /* Print element */ |
304 | 0 | snprintf(temp_str, sizeof(temp_str), "Element #%llu:", (unsigned long long)idx); |
305 | 0 | fprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str, |
306 | 0 | (unsigned long long)*(const uint64_t *)elmt); |
307 | |
|
308 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
309 | 0 | } /* end H5EA__test_debug() */ |
310 | | |
311 | | /*------------------------------------------------------------------------- |
312 | | * Function: H5EA__test_crt_dbg_context |
313 | | * |
314 | | * Purpose: Create context for debugging callback |
315 | | * |
316 | | * Return: Success: non-NULL |
317 | | * Failure: NULL |
318 | | * |
319 | | *------------------------------------------------------------------------- |
320 | | */ |
321 | | static void * |
322 | | H5EA__test_crt_dbg_context(H5F_t H5_ATTR_UNUSED *f, haddr_t H5_ATTR_UNUSED obj_addr) |
323 | 0 | { |
324 | 0 | H5EA__ctx_cb_t *ctx; /* Context for callbacks */ |
325 | 0 | void *ret_value = NULL; |
326 | |
|
327 | 0 | FUNC_ENTER_PACKAGE |
328 | | |
329 | | /* Allocate new context structure */ |
330 | 0 | if (NULL == (ctx = H5FL_MALLOC(H5EA__ctx_cb_t))) |
331 | 0 | HGOTO_ERROR(H5E_EARRAY, H5E_CANTALLOC, NULL, |
332 | 0 | "can't allocate extensible array client callback context"); |
333 | | |
334 | | /* Set return value */ |
335 | 0 | ret_value = ctx; |
336 | |
|
337 | 0 | done: |
338 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
339 | 0 | } /* end H5EA__test_crt_dbg_context() */ |
340 | | |
341 | | /*------------------------------------------------------------------------- |
342 | | * Function: H5EA__test_dst_dbg_context |
343 | | * |
344 | | * Purpose: Destroy context for callbacks |
345 | | * |
346 | | * Return: Success: non-negative |
347 | | * Failure: negative |
348 | | * |
349 | | *------------------------------------------------------------------------- |
350 | | */ |
351 | | static herr_t |
352 | | H5EA__test_dst_dbg_context(void *_ctx) |
353 | 0 | { |
354 | 0 | H5EA__ctx_cb_t *ctx = (H5EA__ctx_cb_t *)_ctx; /* Callback context to destroy */ |
355 | |
|
356 | 0 | FUNC_ENTER_PACKAGE_NOERR |
357 | |
|
358 | 0 | assert(_ctx); |
359 | | |
360 | | /* Release context structure */ |
361 | 0 | ctx = H5FL_FREE(H5EA__ctx_cb_t, ctx); |
362 | |
|
363 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
364 | 0 | } /* end H5EA__test_dst_dbg_context() */ |
365 | | |
366 | | /*------------------------------------------------------------------------- |
367 | | * Function: H5EA__get_cparam_test |
368 | | * |
369 | | * Purpose: Retrieve the parameters used to create the extensible array |
370 | | * |
371 | | * Return: Success: non-negative |
372 | | * Failure: negative |
373 | | * |
374 | | *------------------------------------------------------------------------- |
375 | | */ |
376 | | herr_t |
377 | | H5EA__get_cparam_test(const H5EA_t *ea, H5EA_create_t *cparam) |
378 | 0 | { |
379 | 0 | FUNC_ENTER_PACKAGE_NOERR |
380 | | |
381 | | /* Check arguments. */ |
382 | 0 | assert(ea); |
383 | 0 | assert(cparam); |
384 | | |
385 | | /* Get extensible array creation parameters */ |
386 | 0 | cparam->raw_elmt_size = ea->hdr->cparam.raw_elmt_size; |
387 | 0 | cparam->max_nelmts_bits = ea->hdr->cparam.max_nelmts_bits; |
388 | 0 | cparam->idx_blk_elmts = ea->hdr->cparam.idx_blk_elmts; |
389 | 0 | cparam->sup_blk_min_data_ptrs = ea->hdr->cparam.sup_blk_min_data_ptrs; |
390 | 0 | cparam->data_blk_min_elmts = ea->hdr->cparam.data_blk_min_elmts; |
391 | 0 | cparam->max_dblk_page_nelmts_bits = ea->hdr->cparam.max_dblk_page_nelmts_bits; |
392 | |
|
393 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
394 | 0 | } /* end H5EA__get_cparam_test() */ |
395 | | |
396 | | /*------------------------------------------------------------------------- |
397 | | * Function: H5EA__cmp_cparam_test |
398 | | * |
399 | | * Purpose: Compare the parameters used to create the extensible array |
400 | | * |
401 | | * Return: Success: non-negative |
402 | | * Failure: negative |
403 | | * |
404 | | *------------------------------------------------------------------------- |
405 | | */ |
406 | | int |
407 | | H5EA__cmp_cparam_test(const H5EA_create_t *cparam1, const H5EA_create_t *cparam2) |
408 | 0 | { |
409 | 0 | int ret_value = 0; |
410 | |
|
411 | 0 | FUNC_ENTER_PACKAGE_NOERR |
412 | | |
413 | | /* Check arguments */ |
414 | 0 | assert(cparam1); |
415 | 0 | assert(cparam2); |
416 | | |
417 | | /* Compare creation parameters for array */ |
418 | 0 | if (cparam1->raw_elmt_size < cparam2->raw_elmt_size) |
419 | 0 | HGOTO_DONE(-1); |
420 | 0 | else if (cparam1->raw_elmt_size > cparam2->raw_elmt_size) |
421 | 0 | HGOTO_DONE(1); |
422 | | |
423 | 0 | if (cparam1->max_nelmts_bits < cparam2->max_nelmts_bits) |
424 | 0 | HGOTO_DONE(-1); |
425 | 0 | else if (cparam1->max_nelmts_bits > cparam2->max_nelmts_bits) |
426 | 0 | HGOTO_DONE(1); |
427 | | |
428 | 0 | if (cparam1->idx_blk_elmts < cparam2->idx_blk_elmts) |
429 | 0 | HGOTO_DONE(-1); |
430 | 0 | else if (cparam1->idx_blk_elmts > cparam2->idx_blk_elmts) |
431 | 0 | HGOTO_DONE(1); |
432 | | |
433 | 0 | if (cparam1->sup_blk_min_data_ptrs < cparam2->sup_blk_min_data_ptrs) |
434 | 0 | HGOTO_DONE(-1); |
435 | 0 | else if (cparam1->sup_blk_min_data_ptrs > cparam2->sup_blk_min_data_ptrs) |
436 | 0 | HGOTO_DONE(1); |
437 | | |
438 | 0 | if (cparam1->data_blk_min_elmts < cparam2->data_blk_min_elmts) |
439 | 0 | HGOTO_DONE(-1); |
440 | 0 | else if (cparam1->data_blk_min_elmts > cparam2->data_blk_min_elmts) |
441 | 0 | HGOTO_DONE(1); |
442 | | |
443 | 0 | if (cparam1->max_dblk_page_nelmts_bits < cparam2->max_dblk_page_nelmts_bits) |
444 | 0 | HGOTO_DONE(-1); |
445 | 0 | else if (cparam1->max_dblk_page_nelmts_bits > cparam2->max_dblk_page_nelmts_bits) |
446 | 0 | HGOTO_DONE(1); |
447 | | |
448 | 0 | done: |
449 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
450 | 0 | } /* end H5EA__cmp_cparam_test() */ |