Implement unknown field aliasing support

PiperOrigin-RevId: 708077050
pull/19753/head
Protobuf Team Bot 2 months ago committed by Copybara-Service
parent f135dede85
commit efbd632e56
  1. 3
      upb/message/internal/message.h
  2. 17
      upb/message/message.c
  3. 4
      upb/wire/decode.h

@ -120,7 +120,8 @@ void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg);
// Adds unknown data (serialized protobuf data) to the given message. The data // Adds unknown data (serialized protobuf data) to the given message. The data
// must represent one or more complete and well formed proto fields. // must represent one or more complete and well formed proto fields.
// The data is copied into the message instance. // If alias is set, will keep a view to the provided data; otherwise a copy is
// made.
bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg,
const char* data, size_t len, const char* data, size_t len,
upb_Arena* arena, bool alias); upb_Arena* arena, bool alias);

@ -43,11 +43,18 @@ bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data,
if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) {
return false; return false;
} }
upb_StringView* view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); upb_StringView* view;
if (!view) return false; if (alias) {
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); view = upb_Arena_Malloc(arena, sizeof(upb_StringView));
memcpy(copy, data, len); if (!view) return false;
view->data = copy; view->data = data;
} else {
view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len);
if (!view) return false;
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char);
memcpy(copy, data, len);
view->data = copy;
}
view->size = len; view->size = len;
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view); in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view);

@ -26,8 +26,8 @@ extern "C" {
#endif #endif
enum { enum {
/* If set, strings will alias the input buffer instead of copying into the /* If set, strings and unknown fields will alias the input buffer instead of
* arena. */ * copying into the arena. */
kUpb_DecodeOption_AliasString = 1, kUpb_DecodeOption_AliasString = 1,
/* If set, the parse will return failure if any message is missing any /* If set, the parse will return failure if any message is missing any

Loading…
Cancel
Save