1 /*
2 ** Functions for use by generated code. These are not public and users must
3 ** not call them directly.
4 */
5
6 #ifndef UPB_GENERATED_UTIL_H_
7 #define UPB_GENERATED_UTIL_H_
8
9 #include <stdint.h>
10 #include "upb/msg.h"
11
12 #include "upb/port_def.inc"
13
14 #define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs)
15
_upb_array_accessor(const void * msg,size_t ofs,size_t * size)16 UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs,
17 size_t *size) {
18 const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*);
19 if (arr) {
20 if (size) *size = arr->len;
21 return arr->data;
22 } else {
23 if (size) *size = 0;
24 return NULL;
25 }
26 }
27
_upb_array_mutable_accessor(void * msg,size_t ofs,size_t * size)28 UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs,
29 size_t *size) {
30 upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
31 if (arr) {
32 if (size) *size = arr->len;
33 return arr->data;
34 } else {
35 if (size) *size = 0;
36 return NULL;
37 }
38 }
39
40 /* TODO(haberman): this is a mess. It will improve when upb_array no longer
41 * carries reflective state (type, elem_size). */
_upb_array_resize_accessor(void * msg,size_t ofs,size_t size,size_t elem_size,upb_fieldtype_t type,upb_arena * arena)42 UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size,
43 size_t elem_size,
44 upb_fieldtype_t type,
45 upb_arena *arena) {
46 upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
47
48 if (!arr) {
49 arr = upb_array_new(arena);
50 if (!arr) return NULL;
51 *PTR_AT(msg, ofs, upb_array*) = arr;
52 }
53
54 if (size > arr->size) {
55 size_t new_size = UPB_MAX(arr->size, 4);
56 size_t old_bytes = arr->size * elem_size;
57 size_t new_bytes;
58 while (new_size < size) new_size *= 2;
59 new_bytes = new_size * elem_size;
60 arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes);
61 if (!arr->data) {
62 return NULL;
63 }
64 arr->size = new_size;
65 }
66
67 arr->len = size;
68 return arr->data;
69 }
70
_upb_array_append_accessor(void * msg,size_t ofs,size_t elem_size,upb_fieldtype_t type,const void * value,upb_arena * arena)71 UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
72 size_t elem_size,
73 upb_fieldtype_t type,
74 const void *value,
75 upb_arena *arena) {
76 upb_array *arr = *PTR_AT(msg, ofs, upb_array*);
77 size_t i = arr ? arr->len : 0;
78 void *data =
79 _upb_array_resize_accessor(msg, ofs, i + 1, elem_size, type, arena);
80 if (!data) return false;
81 memcpy(PTR_AT(data, i * elem_size, char), value, elem_size);
82 return true;
83 }
84
_upb_has_field(const void * msg,size_t idx)85 UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) {
86 return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0;
87 }
88
_upb_sethas(const void * msg,size_t idx)89 UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) {
90 return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8));
91 }
92
_upb_clearhas(const void * msg,size_t idx)93 UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) {
94 return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8)));
95 }
96
_upb_has_oneof_field(const void * msg,size_t case_ofs,int32_t num)97 UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) {
98 return *PTR_AT(msg, case_ofs, int32_t) == num;
99 }
100
101 #undef PTR_AT
102
103 #include "upb/port_undef.inc"
104
105 #endif /* UPB_GENERATED_UTIL_H_ */
106