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_MAP_H_
9 #define UPB_MESSAGE_MAP_H_
10
11 #include <stddef.h>
12
13 #include "upb/base/descriptor_constants.h"
14 #include "upb/mem/arena.h"
15 #include "upb/message/internal/map.h"
16 #include "upb/message/value.h"
17 #include "upb/mini_table/field.h"
18 #include "upb/mini_table/message.h"
19
20 // Must be last.
21 #include "upb/port/def.inc"
22
23 typedef struct upb_Map upb_Map;
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 // Creates a new map on the given arena with the given key/value size.
30 UPB_API upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type,
31 upb_CType value_type);
32
33 // Returns the number of entries in the map.
34 UPB_API size_t upb_Map_Size(const upb_Map* map);
35
36 // Stores a value for the given key into |*val| (or the zero value if the key is
37 // not present). Returns whether the key was present. The |val| pointer may be
38 // NULL, in which case the function tests whether the given key is present.
39 UPB_API bool upb_Map_Get(const upb_Map* map, upb_MessageValue key,
40 upb_MessageValue* val);
41
42 // Removes all entries in the map.
43 UPB_API void upb_Map_Clear(upb_Map* map);
44
45 // Sets the given key to the given value, returning whether the key was inserted
46 // or replaced. If the key was inserted, then any existing iterators will be
47 // invalidated.
48 UPB_API upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key,
49 upb_MessageValue val,
50 upb_Arena* arena);
51
52 // Sets the given key to the given value. Returns false if memory allocation
53 // failed. If the key is newly inserted, then any existing iterators will be
54 // invalidated.
upb_Map_Set(upb_Map * map,upb_MessageValue key,upb_MessageValue val,upb_Arena * arena)55 UPB_API_INLINE bool upb_Map_Set(upb_Map* map, upb_MessageValue key,
56 upb_MessageValue val, upb_Arena* arena) {
57 return upb_Map_Insert(map, key, val, arena) !=
58 kUpb_MapInsertStatus_OutOfMemory;
59 }
60
61 // Deletes this key from the table. Returns true if the key was present.
62 // If present and |val| is non-NULL, stores the deleted value.
63 UPB_API bool upb_Map_Delete(upb_Map* map, upb_MessageValue key,
64 upb_MessageValue* val);
65
66 // Map iteration:
67 //
68 // size_t iter = kUpb_Map_Begin;
69 // upb_MessageValue key, val;
70 // while (upb_Map_Next(map, &key, &val, &iter)) {
71 // ...
72 // }
73
74 #define kUpb_Map_Begin ((size_t) - 1)
75
76 // Advances to the next entry. Returns false if no more entries are present.
77 // Otherwise returns true and populates both *key and *value.
78 UPB_API bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key,
79 upb_MessageValue* val, size_t* iter);
80
81 // Sets the value for the entry pointed to by iter.
82 // WARNING: this does not currently work for string values!
83 UPB_API void upb_Map_SetEntryValue(upb_Map* map, size_t iter,
84 upb_MessageValue val);
85
86 // DEPRECATED iterator, slated for removal.
87
88 /* Map iteration:
89 *
90 * size_t iter = kUpb_Map_Begin;
91 * while (upb_MapIterator_Next(map, &iter)) {
92 * upb_MessageValue key = upb_MapIterator_Key(map, iter);
93 * upb_MessageValue val = upb_MapIterator_Value(map, iter);
94 * }
95 */
96
97 // Advances to the next entry. Returns false if no more entries are present.
98 UPB_API bool upb_MapIterator_Next(const upb_Map* map, size_t* iter);
99
100 // Returns true if the iterator still points to a valid entry, or false if the
101 // iterator is past the last element. It is an error to call this function with
102 // kUpb_Map_Begin (you must call next() at least once first).
103 UPB_API bool upb_MapIterator_Done(const upb_Map* map, size_t iter);
104
105 // Returns the key and value for this entry of the map.
106 UPB_API upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter);
107 UPB_API upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter);
108
109 // Mark a map and all of its descendents as frozen/immutable.
110 // If the map values are messages then |m| must point to the minitable for
111 // those messages. Otherwise |m| must be NULL.
112 UPB_API void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m);
113
114 // Returns whether a map has been frozen.
115 UPB_API_INLINE bool upb_Map_IsFrozen(const upb_Map* map);
116
117 #ifdef __cplusplus
118 } /* extern "C" */
119 #endif
120
121 #include "upb/port/undef.inc"
122
123 #endif /* UPB_MESSAGE_MAP_H_ */
124