Derek Benson | e2ab51b | 2024-06-25 07:25:21 -0700 | [diff] [blame] | 1 | #include "upb/message/merge.h" |
| 2 | |
| 3 | #include "stddef.h" |
| 4 | #include "upb/mem/arena.h" |
| 5 | #include "upb/message/message.h" |
| 6 | #include "upb/mini_table/extension_registry.h" |
| 7 | #include "upb/mini_table/message.h" |
| 8 | #include "upb/wire/decode.h" |
| 9 | #include "upb/wire/encode.h" |
| 10 | |
| 11 | // Must be last. |
| 12 | #include "upb/port/def.inc" |
| 13 | |
| 14 | bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, |
| 15 | const upb_MiniTable* mt, |
| 16 | const upb_ExtensionRegistry* extreg, |
| 17 | upb_Arena* arena) { |
| 18 | char* buf = NULL; |
| 19 | size_t size = 0; |
| 20 | // This tmp arena is used to hold the bytes for `src` serialized. This bends |
| 21 | // the typical "no hidden allocations" design of upb, but under a properly |
| 22 | // optimized implementation this extra allocation would not be necessary and |
| 23 | // so we don't want to unnecessarily have the bad API or bloat the passed-in |
| 24 | // arena with this very-short-term allocation. |
| 25 | upb_Arena* encode_arena = upb_Arena_New(); |
| 26 | upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size); |
| 27 | if (e_status != kUpb_EncodeStatus_Ok) { |
| 28 | upb_Arena_Free(encode_arena); |
| 29 | return false; |
| 30 | } |
| 31 | upb_DecodeStatus d_status = upb_Decode(buf, size, dst, mt, extreg, 0, arena); |
| 32 | if (d_status != kUpb_DecodeStatus_Ok) { |
| 33 | upb_Arena_Free(encode_arena); |
| 34 | return false; |
| 35 | } |
| 36 | upb_Arena_Free(encode_arena); |
| 37 | return true; |
| 38 | } |