Coverage Report

Created: 2025-10-10 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Pencdec.c
Line
Count
Source
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: Generic Property Functions
15
 */
16
17
/****************/
18
/* Module Setup */
19
/****************/
20
21
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
22
23
/***********/
24
/* Headers */
25
/***********/
26
#include "H5private.h"   /* Generic Functions     */
27
#include "H5Eprivate.h"  /* Error handling        */
28
#include "H5Iprivate.h"  /* IDs           */
29
#include "H5MMprivate.h" /* Memory management     */
30
#include "H5Ppkg.h"      /* Property lists        */
31
#include "H5VMprivate.h" /* Vector functions      */
32
33
/****************/
34
/* Local Macros */
35
/****************/
36
37
/* Version # of encoded property lists */
38
0
#define H5P_ENCODE_VERS 0
39
40
/******************/
41
/* Local Typedefs */
42
/******************/
43
44
/* Typedef for iterator when encoding a property list */
45
typedef struct {
46
    bool    encode;       /* Whether the property list should be encoded */
47
    size_t *enc_size_ptr; /* Pointer to size of encoded buffer */
48
    void  **pp;           /* Pointer to encoding buffer pointer */
49
} H5P_enc_iter_ud_t;
50
51
/********************/
52
/* Local Prototypes */
53
/********************/
54
55
/*********************/
56
/* Package Variables */
57
/*********************/
58
59
/*****************************/
60
/* Library Private Variables */
61
/*****************************/
62
63
/*******************/
64
/* Local Variables */
65
/*******************/
66
67
/*-------------------------------------------------------------------------
68
 * Function:       H5P__encode_size_t
69
 *
70
 * Purpose:        Generic encoding callback routine for 'size_t' properties.
71
 *
72
 * Return:     Success: Non-negative
73
 *       Failure: Negative
74
 *
75
 *-------------------------------------------------------------------------
76
 */
77
herr_t
78
H5P__encode_size_t(const void *value, void **_pp, size_t *size)
79
0
{
80
0
    uint64_t  enc_value = (uint64_t) * (const size_t *)value; /* Property value to encode */
81
0
    uint8_t **pp        = (uint8_t **)_pp;
82
0
    unsigned  enc_size  = H5VM_limit_enc_size(enc_value); /* Size of encoded property */
83
84
0
    FUNC_ENTER_PACKAGE_NOERR
85
86
    /* Sanity checks */
87
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
88
0
    assert(enc_size < 256);
89
0
    assert(size);
90
91
0
    if (NULL != *pp) {
92
        /* Encode the size */
93
0
        *(*pp)++ = (uint8_t)enc_size;
94
95
        /* Encode the value */
96
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
97
0
    } /* end if */
98
99
    /* Set size needed for encoding */
100
0
    *size += (1 + enc_size);
101
102
0
    FUNC_LEAVE_NOAPI(SUCCEED)
103
0
} /* end H5P__encode_size_t() */
104
105
/*-------------------------------------------------------------------------
106
 * Function:       H5P__encode_hsize_t
107
 *
108
 * Purpose:        Generic encoding callback routine for 'hsize_t' properties.
109
 *
110
 * Return:     Success: Non-negative
111
 *       Failure: Negative
112
 *
113
 *-------------------------------------------------------------------------
114
 */
115
herr_t
116
H5P__encode_hsize_t(const void *value, void **_pp, size_t *size)
117
0
{
118
0
    uint64_t  enc_value = (uint64_t) * (const hsize_t *)value; /* Property value to encode */
119
0
    unsigned  enc_size  = H5VM_limit_enc_size(enc_value);      /* Size of encoded property */
120
0
    uint8_t **pp        = (uint8_t **)_pp;
121
122
0
    FUNC_ENTER_PACKAGE_NOERR
123
124
    /* Sanity checks */
125
0
    HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
126
0
    assert(enc_size < 256);
127
0
    assert(size);
128
129
0
    if (NULL != *pp) {
130
0
        *(*pp)++ = (uint8_t)enc_size;
131
132
        /* Encode the value */
133
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
134
0
    } /* end if */
135
136
    /* Set size needed for encoding */
137
0
    *size += (1 + enc_size);
138
139
0
    FUNC_LEAVE_NOAPI(SUCCEED)
140
0
} /* end H5P__encode_hsize_t() */
141
142
/*-------------------------------------------------------------------------
143
 * Function:       H5P__encode_unsigned
144
 *
145
 * Purpose:        Generic encoding callback routine for 'unsigned' properties.
146
 *
147
 * Return:     Success: Non-negative
148
 *       Failure: Negative
149
 *
150
 *-------------------------------------------------------------------------
151
 */
152
herr_t
153
H5P__encode_unsigned(const void *value, void **_pp, size_t *size)
154
0
{
155
0
    uint8_t **pp = (uint8_t **)_pp;
156
157
0
    FUNC_ENTER_PACKAGE_NOERR
158
159
    /* Sanity checks */
160
0
    assert(value);
161
0
    assert(size);
162
163
0
    if (NULL != *pp) {
164
        /* Encode the size */
165
0
        *(*pp)++ = (uint8_t)sizeof(unsigned);
166
167
        /* Encode the value */
168
0
        H5_ENCODE_UNSIGNED(*pp, *(const unsigned *)value);
169
0
    } /* end if */
170
171
    /* Set size needed for encoding */
172
0
    *size += (1 + sizeof(unsigned));
173
174
0
    FUNC_LEAVE_NOAPI(SUCCEED)
175
0
} /* end H5P__encode_unsigned() */
176
177
/*-------------------------------------------------------------------------
178
 * Function:       H5P__encode_uint8_t
179
 *
180
 * Purpose:        Generic encoding callback routine for 'uint8_t' properties.
181
 *
182
 * Return:     Success: Non-negative
183
 *       Failure: Negative
184
 *
185
 *-------------------------------------------------------------------------
186
 */
187
herr_t
188
H5P__encode_uint8_t(const void *value, void **_pp, size_t *size)
189
0
{
190
0
    uint8_t **pp = (uint8_t **)_pp;
191
192
0
    FUNC_ENTER_PACKAGE_NOERR
193
194
    /* Sanity checks */
195
0
    assert(value);
196
0
    assert(size);
197
198
0
    if (NULL != *pp) {
199
        /* Encode the value */
200
0
        *(*pp)++ = *(const uint8_t *)value;
201
0
    } /* end if */
202
203
    /* Set size needed for encoding */
204
0
    *size += 1;
205
206
0
    FUNC_LEAVE_NOAPI(SUCCEED)
207
0
} /* end H5P__encode_uint8_t() */
208
209
/*-------------------------------------------------------------------------
210
 * Function:       H5P__encode_bool
211
 *
212
 * Purpose:        Generic encoding callback routine for 'bool' properties.
213
 *
214
 * Return:     Success: Non-negative
215
 *       Failure: Negative
216
 *
217
 *-------------------------------------------------------------------------
218
 */
219
herr_t
220
H5P__encode_bool(const void *value, void **_pp, size_t *size)
221
0
{
222
0
    uint8_t **pp = (uint8_t **)_pp;
223
224
0
    FUNC_ENTER_PACKAGE_NOERR
225
226
    /* Sanity checks */
227
0
    assert(value);
228
0
    assert(size);
229
230
0
    if (NULL != *pp)
231
        /* Encode the value */
232
0
        *(*pp)++ = (uint8_t) * (const bool *)value;
233
234
    /* Set size needed for encoding */
235
0
    *size += 1;
236
237
0
    FUNC_LEAVE_NOAPI(SUCCEED)
238
0
} /* end H5P__encode_bool() */
239
240
/*-------------------------------------------------------------------------
241
 * Function:       H5P__encode_double
242
 *
243
 * Purpose:        Generic encoding callback routine for 'double' properties.
244
 *
245
 * Return:     Success: Non-negative
246
 *       Failure: Negative
247
 *
248
 *-------------------------------------------------------------------------
249
 */
250
herr_t
251
H5P__encode_double(const void *value, void **_pp, size_t *size)
252
0
{
253
0
    uint8_t **pp = (uint8_t **)_pp;
254
255
0
    FUNC_ENTER_PACKAGE_NOERR
256
257
    /* Sanity checks */
258
0
    assert(value);
259
0
    assert(size);
260
261
0
    if (NULL != *pp) {
262
        /* Encode the size */
263
0
        *(*pp)++ = (uint8_t)sizeof(double);
264
265
        /* Encode the value */
266
0
        H5_ENCODE_DOUBLE(*pp, *(const double *)value);
267
0
    } /* end if */
268
269
    /* Set size needed for encoding */
270
0
    *size += (1 + sizeof(double));
271
272
0
    FUNC_LEAVE_NOAPI(SUCCEED)
273
0
} /* end H5P__encode_double() */
274
275
/*-------------------------------------------------------------------------
276
 * Function:       H5P__encode_uint64_t
277
 *
278
 * Purpose:        Generic encoding callback routine for 'uint64_t' properties.
279
 *
280
 * Return:     Success: Non-negative
281
 *       Failure: Negative
282
 *
283
 *-------------------------------------------------------------------------
284
 */
285
herr_t
286
H5P__encode_uint64_t(const void *value, void **_pp, size_t *size)
287
0
{
288
0
    uint8_t **pp = (uint8_t **)_pp;
289
290
0
    FUNC_ENTER_PACKAGE_NOERR
291
292
    /* Sanity checks */
293
0
    assert(value);
294
0
    assert(size);
295
296
0
    if (NULL != *pp) {
297
        /* Encode the size */
298
0
        *(*pp)++ = (uint8_t)sizeof(uint64_t);
299
300
        /* Encode the value */
301
0
        UINT64ENCODE(*pp, *(const unsigned *)value);
302
0
    } /* end if */
303
304
    /* Set size needed for encoding */
305
0
    *size += (1 + sizeof(uint64_t));
306
307
0
    FUNC_LEAVE_NOAPI(SUCCEED)
308
0
} /* end H5P__encode_uint64_t() */
309
310
/*--------------------------------------------------------------------------
311
 NAME
312
    H5P__encode_cb
313
 PURPOSE
314
    Internal callback routine when iterating over properties while encoding
315
    a property list.
316
 USAGE
317
    int H5P__encode_cb(item, key, udata)
318
        H5P_genprop_t *prop;        IN: Pointer to the property
319
        void *udata;                IN/OUT: Pointer to iteration data from user
320
 RETURNS
321
    Success: H5_ITER_CONT
322
    Fail: H5_ITER_ERROR
323
 DESCRIPTION
324
    This routine encodes a property in a property list
325
 GLOBAL VARIABLES
326
 COMMENTS, BUGS, ASSUMPTIONS
327
 EXAMPLES
328
 REVISION LOG
329
--------------------------------------------------------------------------*/
330
static int
331
H5P__encode_cb(H5P_genprop_t *prop, void *_udata)
332
0
{
333
0
    H5P_enc_iter_ud_t *udata     = (H5P_enc_iter_ud_t *)_udata; /* Pointer to user data */
334
0
    int                ret_value = H5_ITER_CONT;                /* Return value */
335
336
0
    FUNC_ENTER_PACKAGE
337
338
    /* Sanity check */
339
0
    assert(prop);
340
0
    assert(udata);
341
342
    /* Check if this property can be encoded */
343
0
    if (prop->encode) {
344
0
        size_t prop_name_len;  /* Length of property's name */
345
0
        size_t prop_value_len; /* Encoded size of property's value */
346
347
        /* Encode (or not, if the 'encode' flag is off) the property's name */
348
0
        prop_name_len = strlen(prop->name) + 1;
349
0
        if (udata->encode) {
350
0
            strcpy((char *)*(udata->pp), prop->name);
351
0
            *(uint8_t **)(udata->pp) += prop_name_len;
352
0
        } /* end if */
353
0
        *(udata->enc_size_ptr) += prop_name_len;
354
355
        /* Prepare & restore library for user callback */
356
0
        H5_BEFORE_USER_CB(H5_ITER_ERROR)
357
0
            {
358
                /* Encode (or not, if *(udata->pp) is NULL) the property value */
359
0
                prop_value_len = 0;
360
0
                ret_value      = (prop->encode)(prop->value, udata->pp, &prop_value_len);
361
0
            }
362
0
        H5_AFTER_USER_CB(H5_ITER_ERROR)
363
0
        if (ret_value < 0)
364
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, H5_ITER_ERROR, "property encoding routine failed");
365
0
        *(udata->enc_size_ptr) += prop_value_len;
366
0
    } /* end if */
367
368
0
done:
369
0
    FUNC_LEAVE_NOAPI(ret_value)
370
0
} /* end H5P__encode_cb() */
371
372
/*-------------------------------------------------------------------------
373
 NAME
374
    H5P__encode
375
 PURPOSE
376
    Internal routine to encode a property list into a binary buffer.
377
 USAGE
378
    herr_t H5P__encode(plist, enc_all_prop, buf, nalloc)
379
        const H5P_genplist_t *plist;  IN: Property list to encode
380
        bool enc_all_prop;  IN: Whether to encode all properties (true),
381
                or just non-default (i.e. changed) properties (false).
382
        uint8_t *buf;    OUT: buffer to hold the encoded plist
383
        size_t *nalloc;  IN/OUT: size of buffer needed to encode plist
384
 RETURNS
385
    Returns non-negative on success, negative on failure.
386
 DESCRIPTION
387
    Encodes a property list into a binary buffer. If the buffer is NULL, then
388
    the call will set the size needed to encode the plist in nalloc. Otherwise
389
    the routine will encode the plist in buf.
390
 GLOBAL VARIABLES
391
 COMMENTS, BUGS, ASSUMPTIONS
392
 EXAMPLES
393
 REVISION LOG
394
--------------------------------------------------------------------------*/
395
herr_t
396
H5P__encode(const H5P_genplist_t *plist, bool enc_all_prop, void *buf, size_t *nalloc)
397
0
{
398
0
    H5P_enc_iter_ud_t udata;                 /* User data for property iteration callback */
399
0
    uint8_t          *p = (uint8_t *)buf;    /* Temporary pointer to encoding buffer */
400
0
    int               idx;                   /* Index of property to start at */
401
0
    size_t            encode_size = 0;       /* Size of buffer needed to encode properties */
402
0
    bool              encode      = true;    /* Whether the property list should be encoded */
403
0
    herr_t            ret_value   = SUCCEED; /* Return value */
404
405
0
    FUNC_ENTER_PACKAGE
406
407
    /* Sanity check */
408
0
    if (NULL == nalloc)
409
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad allocation size pointer");
410
411
    /* If the buffer is NULL, then this call to H5P__encode will return how much
412
     * space is needed to encode a property.
413
     */
414
0
    if (NULL == p)
415
0
        encode = false;
416
417
    /* Encode property list description info */
418
0
    if (encode) {
419
        /* Version # of property list encoding */
420
0
        *p++ = (uint8_t)H5P_ENCODE_VERS;
421
422
        /* Type of property list */
423
0
        *p++ = (uint8_t)plist->pclass->type;
424
0
    } /* end if */
425
0
    encode_size += 2;
426
427
    /* Initialize user data for iteration callback */
428
0
    udata.encode       = encode;
429
0
    udata.enc_size_ptr = &encode_size;
430
0
    udata.pp           = (void **)&p;
431
432
    /* Iterate over all properties in property list, encoding them */
433
0
    idx = 0;
434
0
    if (H5P__iterate_plist(plist, enc_all_prop, &idx, H5P__encode_cb, &udata) < 0)
435
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADITER, FAIL, "can't iterate over properties");
436
437
    /* Encode a terminator for list of properties */
438
0
    if (encode)
439
0
        *p++ = 0;
440
0
    encode_size++;
441
442
    /* Set the size of the buffer needed/used to encode the property list */
443
0
    *nalloc = encode_size;
444
445
0
done:
446
0
    FUNC_LEAVE_NOAPI(ret_value)
447
0
} /* end H5P__encode() */
448
449
/*-------------------------------------------------------------------------
450
 * Function:       H5P__decode_size_t
451
 *
452
 * Purpose:        Generic decoding callback routine for 'size_t' properties.
453
 *
454
 * Return:     Success: Non-negative
455
 *       Failure: Negative
456
 *
457
 *-------------------------------------------------------------------------
458
 */
459
herr_t
460
H5P__decode_size_t(const void **_pp, void *_value)
461
0
{
462
0
    size_t         *value = (size_t *)_value; /* Property value to return */
463
0
    const uint8_t **pp    = (const uint8_t **)_pp;
464
0
    uint64_t        enc_value; /* Decoded property value */
465
0
    unsigned        enc_size;  /* Size of encoded property */
466
467
0
    FUNC_ENTER_PACKAGE_NOERR
468
469
    /* Sanity check */
470
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
471
0
    assert(pp);
472
0
    assert(*pp);
473
0
    assert(value);
474
475
    /* Decode the size */
476
0
    enc_size = *(*pp)++;
477
0
    assert(enc_size < 256);
478
479
    /* Decode the value */
480
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
481
0
    H5_CHECKED_ASSIGN(*value, size_t, enc_value, uint64_t);
482
483
0
    FUNC_LEAVE_NOAPI(SUCCEED)
484
0
} /* end H5P__decode_size_t() */
485
486
/*-------------------------------------------------------------------------
487
 * Function:       H5P__decode_hsize_t
488
 *
489
 * Purpose:        Generic decoding callback routine for 'hsize_t' properties.
490
 *
491
 * Return:     Success: Non-negative
492
 *       Failure: Negative
493
 *
494
 *-------------------------------------------------------------------------
495
 */
496
herr_t
497
H5P__decode_hsize_t(const void **_pp, void *_value)
498
0
{
499
0
    hsize_t        *value = (hsize_t *)_value; /* Property value to return */
500
0
    const uint8_t **pp    = (const uint8_t **)_pp;
501
0
    uint64_t        enc_value; /* Decoded property value */
502
0
    unsigned        enc_size;  /* Size of encoded property */
503
504
0
    FUNC_ENTER_PACKAGE_NOERR
505
506
    /* Sanity check */
507
0
    HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
508
0
    assert(pp);
509
0
    assert(*pp);
510
0
    assert(value);
511
512
    /* Decode the size */
513
0
    enc_size = *(*pp)++;
514
0
    assert(enc_size < 256);
515
516
    /* Decode the value */
517
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
518
0
    H5_CHECKED_ASSIGN(*value, hsize_t, enc_value, uint64_t);
519
520
0
    FUNC_LEAVE_NOAPI(SUCCEED)
521
0
} /* end H5P__decode_hsize_t() */
522
523
/*-------------------------------------------------------------------------
524
 * Function:       H5P__decode_unsigned
525
 *
526
 * Purpose:        Generic decoding callback routine for 'unsigned' properties.
527
 *
528
 * Return:     Success: Non-negative
529
 *       Failure: Negative
530
 *
531
 *-------------------------------------------------------------------------
532
 */
533
herr_t
534
H5P__decode_unsigned(const void **_pp, void *_value)
535
0
{
536
0
    unsigned       *value = (unsigned *)_value; /* Property value to return */
537
0
    const uint8_t **pp    = (const uint8_t **)_pp;
538
0
    unsigned        enc_size;            /* Size of encoded property */
539
0
    herr_t          ret_value = SUCCEED; /* Return value */
540
541
0
    FUNC_ENTER_PACKAGE
542
543
    /* Sanity checks */
544
0
    assert(pp);
545
0
    assert(*pp);
546
0
    assert(value);
547
548
    /* Decode the size */
549
0
    enc_size = *(*pp)++;
550
0
    if (enc_size != sizeof(unsigned))
551
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unsigned value can't be decoded");
552
553
0
    H5_DECODE_UNSIGNED(*pp, *value);
554
555
0
done:
556
0
    FUNC_LEAVE_NOAPI(ret_value)
557
0
} /* end H5P__decode_unsigned() */
558
559
/*-------------------------------------------------------------------------
560
 * Function:       H5P__decode_uint8_t
561
 *
562
 * Purpose:        Generic decoding callback routine for 'uint8_t' properties.
563
 *
564
 * Return:     Success: Non-negative
565
 *       Failure: Negative
566
 *
567
 *-------------------------------------------------------------------------
568
 */
569
herr_t
570
H5P__decode_uint8_t(const void **_pp, void *_value)
571
0
{
572
0
    uint8_t        *value     = (uint8_t *)_value; /* Property value to return */
573
0
    const uint8_t **pp        = (const uint8_t **)_pp;
574
0
    herr_t          ret_value = SUCCEED; /* Return value */
575
576
0
    FUNC_ENTER_PACKAGE_NOERR
577
578
    /* Sanity checks */
579
0
    assert(pp);
580
0
    assert(*pp);
581
0
    assert(value);
582
583
    /* Decode the value */
584
0
    *value = *(*pp)++;
585
586
0
    FUNC_LEAVE_NOAPI(ret_value)
587
0
} /* end H5P__decode_uint8_t() */
588
589
/*-------------------------------------------------------------------------
590
 * Function:       H5P__decode_bool
591
 *
592
 * Purpose:        Generic decoding callback routine for 'bool' properties.
593
 *
594
 * Return:     Success: Non-negative
595
 *       Failure: Negative
596
 *
597
 *-------------------------------------------------------------------------
598
 */
599
herr_t
600
H5P__decode_bool(const void **_pp, void *_value)
601
0
{
602
0
    bool           *value     = (bool *)_value; /* Property value to return */
603
0
    const uint8_t **pp        = (const uint8_t **)_pp;
604
0
    herr_t          ret_value = SUCCEED; /* Return value */
605
606
0
    FUNC_ENTER_PACKAGE_NOERR
607
608
    /* Sanity checks */
609
0
    assert(pp);
610
0
    assert(*pp);
611
0
    assert(value);
612
613
    /* Decode the value */
614
0
    *value = (bool)*(*pp)++;
615
616
0
    FUNC_LEAVE_NOAPI(ret_value)
617
0
} /* end H5P__decode_bool() */
618
619
/*-------------------------------------------------------------------------
620
 * Function:       H5P__decode_double
621
 *
622
 * Purpose:        Generic decoding callback routine for 'double' properties.
623
 *
624
 * Return:     Success: Non-negative
625
 *       Failure: Negative
626
 *
627
 *-------------------------------------------------------------------------
628
 */
629
herr_t
630
H5P__decode_double(const void **_pp, void *_value)
631
0
{
632
0
    double         *value = (double *)_value; /* Property value to return */
633
0
    const uint8_t **pp    = (const uint8_t **)_pp;
634
0
    unsigned        enc_size;            /* Size of encoded property */
635
0
    herr_t          ret_value = SUCCEED; /* Return value */
636
637
0
    FUNC_ENTER_PACKAGE
638
639
    /* Sanity checks */
640
0
    assert(pp);
641
0
    assert(*pp);
642
0
    assert(value);
643
644
    /* Decode the size */
645
0
    enc_size = *(*pp)++;
646
0
    if (enc_size != sizeof(double))
647
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "double value can't be decoded");
648
649
0
    H5_DECODE_DOUBLE(*pp, *value);
650
651
0
done:
652
0
    FUNC_LEAVE_NOAPI(ret_value)
653
0
} /* end H5P__decode_double() */
654
655
/*-------------------------------------------------------------------------
656
 * Function:       H5P__decode_uint64_t
657
 *
658
 * Purpose:        Generic decoding callback routine for 'uint64_t' properties.
659
 *
660
 * Return:     Success: Non-negative
661
 *       Failure: Negative
662
 *
663
 *-------------------------------------------------------------------------
664
 */
665
herr_t
666
H5P__decode_uint64_t(const void **_pp, void *_value)
667
0
{
668
0
    uint64_t       *value = (uint64_t *)_value; /* Property value to return */
669
0
    const uint8_t **pp    = (const uint8_t **)_pp;
670
0
    unsigned        enc_size;            /* Size of encoded property */
671
0
    herr_t          ret_value = SUCCEED; /* Return value */
672
673
0
    FUNC_ENTER_PACKAGE
674
675
    /* Sanity checks */
676
0
    assert(pp);
677
0
    assert(*pp);
678
0
    assert(value);
679
680
    /* Decode the size */
681
0
    enc_size = *(*pp)++;
682
0
    if (enc_size != sizeof(uint64_t))
683
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "uint64_t value can't be decoded");
684
685
0
    UINT64DECODE(*pp, *value);
686
687
0
done:
688
0
    FUNC_LEAVE_NOAPI(ret_value)
689
0
} /* end H5P__decode_uint64_t() */
690
691
/*-------------------------------------------------------------------------
692
 NAME
693
    H5P__decode
694
 PURPOSE
695
    Internal routine to decode a property list from a binary buffer.
696
 USAGE
697
    H5P_genplist_t *H5P__decode(buf)
698
        const void *buf;    IN: buffer that holds the encoded plist
699
 RETURNS
700
    Returns non-negative ID of new property list object on success, negative
701
        on failure.
702
 DESCRIPTION
703
     Decodes a property list from a binary buffer. The contents of the buffer
704
     contain the values for the corresponding properties of the plist. The decode
705
     callback of a certain property decodes its value from the buffer and sets it
706
     in the property list.
707
 GLOBAL VARIABLES
708
 COMMENTS, BUGS, ASSUMPTIONS
709
     Properties in the property list that are not encoded in the serialized
710
     form retain their default value.
711
 EXAMPLES
712
 REVISION LOG
713
--------------------------------------------------------------------------*/
714
hid_t
715
H5P__decode(const void *buf)
716
0
{
717
0
    H5P_genplist_t  *plist;                            /* Property list to decode into */
718
0
    void            *value_buf = NULL;                 /* Pointer to buffer to use when decoding values */
719
0
    const uint8_t   *p         = (const uint8_t *)buf; /* Current pointer into buffer */
720
0
    H5P_plist_type_t type;                             /* Type of encoded property list */
721
0
    hid_t            plist_id       = -1;              /* ID of new property list */
722
0
    size_t           value_buf_size = 0;               /* Size of current value buffer */
723
0
    uint8_t          vers;                             /* Version of encoded property list */
724
0
    hid_t            ret_value = H5I_INVALID_HID;      /* Return value */
725
726
0
    FUNC_ENTER_PACKAGE
727
728
    /* Sanity check */
729
0
    if (NULL == p)
730
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "decode buffer is NULL");
731
732
    /* Get the version number of the encoded property list */
733
0
    vers = (uint8_t)*p++;
734
0
    if ((uint8_t)H5P_ENCODE_VERS != vers)
735
0
        HGOTO_ERROR(H5E_PLIST, H5E_VERSION, FAIL, "bad version # of encoded information, expected %u, got %u",
736
0
                    (unsigned)H5P_ENCODE_VERS, (unsigned)vers);
737
738
    /* Get the type of the property list */
739
0
    type = (H5P_plist_type_t)*p++;
740
0
    if (type <= H5P_TYPE_USER || type >= H5P_TYPE_MAX_TYPE)
741
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "bad type of encoded information: %u", (unsigned)type);
742
743
    /* Create new property list of the specified type */
744
0
    if ((plist_id = H5P__new_plist_of_type(type)) < 0)
745
0
        HGOTO_ERROR(H5E_PLIST, H5E_VERSION, FAIL, "can't create property list of type: %u\n", (unsigned)type);
746
747
    /* Get the property list object */
748
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
749
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property class");
750
751
    /* Loop over encoded properties, deserializing their values */
752
0
    while (p) {
753
0
        H5P_genprop_t *prop; /* Pointer to property with same name */
754
0
        const char    *name; /* Pointer to property list name */
755
756
        /* Check for end of serialized list of properties */
757
0
        if (0 == *p)
758
0
            break;
759
760
        /* Get property list name */
761
0
        name = (const char *)p;
762
0
        p += strlen(name) + 1;
763
764
        /* Find property with name */
765
0
        if (NULL == (prop = H5P__find_prop_plist(plist, name)))
766
0
            HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist: '%s'", name);
767
768
        /* Check if we should increase the size of the value buffer */
769
0
        if (prop->size > value_buf_size) {
770
0
            if (NULL == (value_buf = H5MM_realloc(value_buf, prop->size)))
771
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "decoding buffer allocation failed");
772
0
            value_buf_size = prop->size;
773
0
        } /* end if */
774
775
        /* Decode serialized value */
776
0
        if (prop->decode) {
777
            /* Prepare & restore library for user callback */
778
0
            H5_BEFORE_USER_CB(FAIL)
779
0
                {
780
0
                    ret_value = (prop->decode)((const void **)&p, value_buf);
781
0
                }
782
0
            H5_AFTER_USER_CB(FAIL)
783
0
            if (ret_value < 0)
784
0
                HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL,
785
0
                            "property decoding routine failed, property: '%s'", name);
786
0
        } /* end if */
787
0
        else
788
0
            HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no decode callback for property: '%s'", name);
789
790
        /* Set the value for the property */
791
0
        if (H5P_poke(plist, name, value_buf) < 0)
792
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value for property: '%s'", name);
793
0
    } /* end while */
794
795
    /* Set return value */
796
0
    ret_value = plist_id;
797
798
0
done:
799
    /* Release resources */
800
0
    if (value_buf)
801
0
        value_buf = H5MM_xfree(value_buf);
802
803
    /* Cleanup on error */
804
0
    if (ret_value < 0) {
805
0
        if (plist_id > 0 && H5I_dec_ref(plist_id) < 0)
806
0
            HDONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL,
807
0
                        "unable to close partially initialized property list");
808
0
    } /* end if */
809
810
0
    FUNC_LEAVE_NOAPI(ret_value)
811
0
} /* end H5P__decode() */