blob: 70923b690eada0cbe19cb392dc05072719ead965 (
plain)
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
|
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Joshua Haberman. See LICENSE for details.
*
* Defines an in-memory, polymorphic array type. The array does not know its
* own type -- its owner must know that information out-of-band.
*
* upb_arrays are memory-managed in the sense that they contain a pointer
* ("mem") to memory that is "owned" by the array (which may be NULL if the
* array owns no memory). There is a separate pointer ("elements") that points
* to the the array's currently "effective" memory, which is either equal to
* mem (if the array's current value is memory we own) or not (if the array is
* referencing other memory).
*
* If the array is referencing other memory, it is up to the array's owner to
* ensure that the other memory remains valid for as long as the array is
* referencing it.
*
*/
#ifndef UPB_ARRAY_H_
#define UPB_ARRAY_H_
#include <stdlib.h>
#include "upb_def.h" /* Because we use upb_fielddef */
#ifdef __cplusplus
extern "C" {
#endif
struct upb_string;
/* Returns a pointer to an array element. Does not perform a bounds check! */
INLINE union upb_value_ptr upb_array_getelementptr(struct upb_array *arr,
upb_arraylen_t n)
{
union upb_value_ptr ptr;
ptr._void = UPB_INDEX(arr->elements._void, n,
upb_type_info[arr->fielddef->type].size);
return ptr;
}
/* Allocation/Deallocation/Resizing. ******************************************/
INLINE struct upb_array *upb_array_new(struct upb_fielddef *f)
{
struct upb_array *arr = (struct upb_array*)malloc(sizeof(*arr));
upb_mmhead_init(&arr->mmhead);
arr->elements._void = NULL;
arr->len = 0;
arr->size = 0;
arr->fielddef = f;
return arr;
}
INLINE uint32_t upb_round_up_to_pow2(uint32_t v)
{
/* cf. http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
INLINE union upb_value_ptr upb_array_append(struct upb_array *arr)
{
size_t size = upb_type_info[arr->fielddef->type].size;
if(arr->len == arr->size) {
arr->size = UPB_MAX(4, upb_round_up_to_pow2(arr->len + 1));
arr->elements._void = realloc(arr->elements._void, arr->size * size);
memset((char*)arr->elements._void + (arr->len * size), 0,
(arr->size - arr->len) * size);
}
return upb_array_getelementptr(arr, arr->len++);
}
INLINE void upb_array_truncate(struct upb_array *arr)
{
arr->len = 0;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
|