WPILibC++ 2027.0.0-alpha-3
Loading...
Searching...
No Matches
map.h
Go to the documentation of this file.
1// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#ifndef UPB_MESSAGE_INTERNAL_MAP_H_
9#define UPB_MESSAGE_INTERNAL_MAP_H_
10
11#include <stddef.h>
12#include <stdint.h>
13#include <string.h>
14
17#include "upb/hash/common.h"
18#include "upb/hash/int_table.h"
19#include "upb/hash/str_table.h"
20#include "upb/mem/arena.h"
21
22// Must be last.
23#include "upb/port/def.inc"
24
30
31// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
32
37
38struct upb_Map {
39 // Size of key and val, based on the map type.
40 // Strings are represented as '0' because they must be handled specially.
43 bool UPB_PRIVATE(is_frozen);
44 bool UPB_PRIVATE(is_strtable);
45
47};
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
54 map->UPB_PRIVATE(is_frozen) = true;
55}
56
58 return map->UPB_PRIVATE(is_frozen);
59}
60
61// Converting between internal table representation and user values.
62//
63// _upb_map_tokey() and _upb_map_fromkey() are inverses.
64// _upb_map_tovalue() and _upb_map_fromvalue() are inverses.
65//
66// These functions account for the fact that strings are treated differently
67// from other types when stored in a map.
68
69UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) {
70 if (size == UPB_MAPTYPE_STRING) {
71 return *(upb_StringView*)key;
72 } else {
73 return upb_StringView_FromDataAndSize((const char*)key, size);
74 }
75}
76
77UPB_INLINE uintptr_t _upb_map_tointkey(const void* key, size_t key_size) {
78 uintptr_t intkey = 0;
79 memcpy(&intkey, key, key_size);
80 return intkey;
81}
82
83UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) {
84 if (size == UPB_MAPTYPE_STRING) {
85 memcpy(out, &key, sizeof(key));
86 } else {
87 memcpy(out, key.data, size);
88 }
89}
90
91UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size,
92 upb_value* msgval, upb_Arena* a) {
93 if (size == UPB_MAPTYPE_STRING) {
94 upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp));
95 if (!strp) return false;
96 *strp = *(upb_StringView*)val;
97 *msgval = upb_value_ptr(strp);
98 } else {
99 memcpy(msgval, val, size);
100 }
101 return true;
102}
103
104UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) {
105 if (size == UPB_MAPTYPE_STRING) {
106 const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val);
107 memcpy(out, strp, sizeof(upb_StringView));
108 } else {
109 memcpy(out, &val, size);
110 }
111}
112
113UPB_INLINE bool _upb_map_next(const struct upb_Map* map, size_t* iter) {
114 if (map->UPB_PRIVATE(is_strtable)) {
116 it.t = &map->t.strtable;
117 it.index = *iter;
119 *iter = it.index;
120 return !upb_strtable_done(&it);
121 } else {
122 uintptr_t key;
123 upb_value val;
124 intptr_t int_iter = 0;
125 memcpy(&int_iter, iter, sizeof(intptr_t));
126 upb_inttable_next(&map->t.inttable, &key, &val, &int_iter);
127 memcpy(iter, &int_iter, sizeof(size_t));
128 return !upb_inttable_done(&map->t.inttable, int_iter);
129 }
130}
131
134
135 if (map->UPB_PRIVATE(is_strtable)) {
136 upb_strtable_clear(&map->t.strtable);
137 } else {
138 upb_inttable_clear(&map->t.inttable);
139 }
140}
141
142UPB_INLINE bool _upb_Map_Delete(struct upb_Map* map, const void* key,
143 size_t key_size, upb_value* val) {
145
146 if (map->UPB_PRIVATE(is_strtable)) {
148 return upb_strtable_remove2(&map->t.strtable, k.data, k.size, val);
149 } else {
150 uintptr_t intkey = _upb_map_tointkey(key, key_size);
151 return upb_inttable_remove(&map->t.inttable, intkey, val);
152 }
153}
154
155UPB_INLINE bool _upb_Map_Get(const struct upb_Map* map, const void* key,
156 size_t key_size, void* val, size_t val_size) {
157 upb_value tabval = {0};
158 bool ret;
159 if (map->UPB_PRIVATE(is_strtable)) {
161 ret = upb_strtable_lookup2(&map->t.strtable, k.data, k.size, &tabval);
162 } else {
163 uintptr_t intkey = _upb_map_tointkey(key, key_size);
164 ret = upb_inttable_lookup(&map->t.inttable, intkey, &tabval);
165 }
166 if (ret && val) {
167 _upb_map_fromvalue(tabval, val, val_size);
168 }
169 return ret;
170}
171
173 const void* key, size_t key_size,
174 void* val, size_t val_size,
175 upb_Arena* a) {
177
178 // Prep the value.
179 upb_value tabval = {0};
180 if (!_upb_map_tovalue(val, val_size, &tabval, a)) {
182 }
183
184 bool removed;
185 if (map->UPB_PRIVATE(is_strtable)) {
187 // TODO: add overwrite operation to minimize number of lookups.
188 removed =
189 upb_strtable_remove2(&map->t.strtable, strkey.data, strkey.size, NULL);
190 if (!upb_strtable_insert(&map->t.strtable, strkey.data, strkey.size, tabval,
191 a)) {
193 }
194 } else {
195 uintptr_t intkey = _upb_map_tointkey(key, key_size);
196 removed = upb_inttable_remove(&map->t.inttable, intkey, NULL);
197 if (!upb_inttable_insert(&map->t.inttable, intkey, tabval, a)) {
199 }
200 }
201 return removed ? kUpb_MapInsertStatus_Replaced
203}
204
205UPB_INLINE size_t _upb_Map_Size(const struct upb_Map* map) {
206 if (map->UPB_PRIVATE(is_strtable)) {
207 return map->t.strtable.t.count;
208 } else {
209 return upb_inttable_count(&map->t.inttable);
210 }
211}
212
213// Strings/bytes are special-cased in maps.
214extern char _upb_Map_CTypeSizeTable[12];
215
217 return _upb_Map_CTypeSizeTable[ctype];
218}
219
220// Creates a new map on the given arena with this key/value type.
221struct upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size);
222
223#ifdef __cplusplus
224} /* extern "C" */
225#endif
226
227#include "upb/port/undef.inc"
228
229#endif /* UPB_MESSAGE_INTERNAL_MAP_H_ */
#define UPB_API_INLINE
Definition def.inc:163
#define UPB_MAPTYPE_STRING
Definition def.inc:133
#define UPB_ASSERT(expr)
Definition def.inc:329
#define UPB_PRIVATE(x)
Definition def.inc:393
#define UPB_INLINE
Definition def.inc:144
upb_CType
Definition descriptor_constants.h:18
void upb_inttable_clear(upb_inttable *t)
bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val)
bool upb_inttable_done(const upb_inttable *t, intptr_t i)
bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v)
bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val, upb_Arena *a)
bool upb_inttable_next(const upb_inttable *t, uintptr_t *key, upb_value *val, intptr_t *iter)
size_t upb_inttable_count(const upb_inttable *t)
UPB_API_INLINE void * upb_Arena_Malloc(struct upb_Arena *a, size_t size)
Definition arena.h:65
UPB_INLINE void UPB_PRIVATE _upb_Map_ShallowFreeze(struct upb_Map *map)
Definition map.h:53
UPB_API_INLINE bool upb_Map_IsFrozen(const struct upb_Map *map)
Definition map.h:57
UPB_INLINE size_t _upb_Map_Size(const struct upb_Map *map)
Definition map.h:205
UPB_INLINE upb_MapInsertStatus _upb_Map_Insert(struct upb_Map *map, const void *key, size_t key_size, void *val, size_t val_size, upb_Arena *a)
Definition map.h:172
UPB_INLINE void _upb_map_fromvalue(upb_value val, void *out, size_t size)
Definition map.h:104
UPB_INLINE size_t _upb_Map_CTypeSize(upb_CType ctype)
Definition map.h:216
UPB_INLINE bool _upb_Map_Delete(struct upb_Map *map, const void *key, size_t key_size, upb_value *val)
Definition map.h:142
UPB_INLINE bool _upb_Map_Get(const struct upb_Map *map, const void *key, size_t key_size, void *val, size_t val_size)
Definition map.h:155
struct upb_Map * _upb_Map_New(upb_Arena *a, size_t key_size, size_t value_size)
UPB_INLINE bool _upb_map_next(const struct upb_Map *map, size_t *iter)
Definition map.h:113
upb_MapInsertStatus
Definition map.h:25
@ kUpb_MapInsertStatus_OutOfMemory
Definition map.h:28
@ kUpb_MapInsertStatus_Inserted
Definition map.h:26
@ kUpb_MapInsertStatus_Replaced
Definition map.h:27
char _upb_Map_CTypeSizeTable[12]
UPB_INLINE void _upb_Map_Clear(struct upb_Map *map)
Definition map.h:132
UPB_INLINE uintptr_t _upb_map_tointkey(const void *key, size_t key_size)
Definition map.h:77
UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval, upb_Arena *a)
Definition map.h:91
UPB_INLINE upb_StringView _upb_map_tokey(const void *key, size_t size)
Definition map.h:69
UPB_INLINE void _upb_map_fromkey(upb_StringView key, void *out, size_t size)
Definition map.h:83
bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, upb_value *v)
void upb_strtable_clear(upb_strtable *t)
bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len, upb_value *val)
void upb_strtable_next(upb_strtable_iter *i)
bool upb_strtable_insert(upb_strtable *t, const char *key, size_t len, upb_value val, upb_Arena *a)
bool upb_strtable_done(const upb_strtable_iter *i)
UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char *data, size_t size)
Definition string_view.h:32
Definition arena.h:29
Definition map.h:38
char val_size
Definition map.h:42
bool UPB_PRIVATE(is_frozen)
bool UPB_PRIVATE(is_strtable)
char key_size
Definition map.h:41
Definition string_view.h:23
const char * data
Definition string_view.h:24
size_t size
Definition string_view.h:25
Definition int_table.h:20
Definition str_table.h:124
size_t index
Definition str_table.h:126
const upb_strtable * t
Definition str_table.h:125
Definition str_table.h:22
upb_table t
Definition str_table.h:23
Definition common.h:44
Definition map.h:33
upb_strtable strtable
Definition map.h:34
upb_inttable inttable
Definition map.h:35