|
15 | 15 | #ifndef UPB_MESSAGE_INTERNAL_MESSAGE_H_
|
16 | 16 | #define UPB_MESSAGE_INTERNAL_MESSAGE_H_
|
17 | 17 |
|
| 18 | +#include <stdint.h> |
18 | 19 | #include <stdlib.h>
|
19 | 20 | #include <string.h>
|
20 | 21 |
|
| 22 | +#include "upb/base/string_view.h" |
21 | 23 | #include "upb/mem/arena.h"
|
22 | 24 | #include "upb/message/internal/extension.h"
|
| 25 | +#include "upb/message/internal/types.h" |
| 26 | +#include "upb/mini_table/extension.h" |
23 | 27 | #include "upb/mini_table/message.h"
|
24 | 28 |
|
25 | 29 | // Must be last.
|
@@ -101,6 +105,68 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg,
|
101 | 105 | bool UPB_PRIVATE(_upb_Message_Realloc)(struct upb_Message* msg, size_t need,
|
102 | 106 | upb_Arena* arena);
|
103 | 107 |
|
| 108 | +#define kUpb_Message_UnknownBegin 0 |
| 109 | +#define kUpb_Message_ExtensionBegin 0 |
| 110 | + |
| 111 | +UPB_INLINE bool upb_Message_NextUnknown(const struct upb_Message* msg, |
| 112 | + upb_StringView* data, uintptr_t* iter) { |
| 113 | + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); |
| 114 | + if (in && *iter == kUpb_Message_UnknownBegin) { |
| 115 | + size_t len = in->unknown_end - sizeof(upb_Message_Internal); |
| 116 | + if (len != 0) { |
| 117 | + data->size = len; |
| 118 | + data->data = (const char*)(in + 1); |
| 119 | + (*iter)++; |
| 120 | + return true; |
| 121 | + } |
| 122 | + } |
| 123 | + data->size = 0; |
| 124 | + data->data = NULL; |
| 125 | + return false; |
| 126 | +} |
| 127 | + |
| 128 | +UPB_INLINE bool upb_Message_HasUnknown(const struct upb_Message* msg) { |
| 129 | + upb_StringView data; |
| 130 | + uintptr_t iter = kUpb_Message_UnknownBegin; |
| 131 | + return upb_Message_NextUnknown(msg, &data, &iter); |
| 132 | +} |
| 133 | + |
| 134 | +UPB_INLINE bool upb_Message_NextExtension(const struct upb_Message* msg, |
| 135 | + const upb_MiniTableExtension** out_e, |
| 136 | + upb_MessageValue* out_v, |
| 137 | + uintptr_t* iter) { |
| 138 | + size_t count; |
| 139 | + const upb_Extension* exts = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count); |
| 140 | + size_t i = *iter; |
| 141 | + if (i < count) { |
| 142 | + // Extensions are stored in reverse wire order, so to iterate in wire order, |
| 143 | + // we need to iterate backwards. |
| 144 | + *out_e = exts[count - 1 - i].ext; |
| 145 | + *out_v = exts[count - 1 - i].data; |
| 146 | + *iter = i + 1; |
| 147 | + return true; |
| 148 | + } |
| 149 | + |
| 150 | + return false; |
| 151 | +} |
| 152 | + |
| 153 | +UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( |
| 154 | + const struct upb_Message* msg, const upb_MiniTableExtension** out_e, |
| 155 | + upb_MessageValue* out_v, uintptr_t* iter) { |
| 156 | + size_t count; |
| 157 | + const upb_Extension* exts = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count); |
| 158 | + size_t i = *iter; |
| 159 | + if (i < count) { |
| 160 | + // Extensions are stored in reverse wire order |
| 161 | + *out_e = exts[i].ext; |
| 162 | + *out_v = exts[i].data; |
| 163 | + *iter = i + 1; |
| 164 | + return true; |
| 165 | + } |
| 166 | + |
| 167 | + return false; |
| 168 | +} |
| 169 | + |
104 | 170 | #ifdef __cplusplus
|
105 | 171 | } /* extern "C" */
|
106 | 172 | #endif
|
|
0 commit comments