• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // upb_Encode: parsing from a upb_Message using a upb_MiniTable.
9 
10 #ifndef UPB_WIRE_ENCODE_H_
11 #define UPB_WIRE_ENCODE_H_
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include "upb/mem/arena.h"
17 #include "upb/message/message.h"
18 #include "upb/mini_table/message.h"
19 
20 // Must be last.
21 #include "upb/port/def.inc"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 enum {
28   /* If set, the results of serializing will be deterministic across all
29    * instances of this binary. There are no guarantees across different
30    * binary builds.
31    *
32    * If your proto contains maps, the encoder will need to malloc()/free()
33    * memory during encode. */
34   kUpb_EncodeOption_Deterministic = 1,
35 
36   // When set, unknown fields are not encoded.
37   kUpb_EncodeOption_SkipUnknown = 2,
38 
39   // When set, the encode will fail if any required fields are missing.
40   kUpb_EncodeOption_CheckRequired = 4,
41 };
42 
43 // LINT.IfChange
44 typedef enum {
45   kUpb_EncodeStatus_Ok = 0,
46   kUpb_EncodeStatus_OutOfMemory = 1,  // Arena alloc failed
47   kUpb_EncodeStatus_MaxDepthExceeded = 2,
48 
49   // kUpb_EncodeOption_CheckRequired failed but the parse otherwise succeeded.
50   kUpb_EncodeStatus_MissingRequired = 3,
51 } upb_EncodeStatus;
52 // LINT.ThenChange(//depot/google3/third_party/protobuf/rust/upb.rs:encode_status)
53 
upb_EncodeOptions_MaxDepth(uint16_t depth)54 UPB_INLINE uint32_t upb_EncodeOptions_MaxDepth(uint16_t depth) {
55   return (uint32_t)depth << 16;
56 }
57 
upb_EncodeOptions_GetMaxDepth(uint32_t options)58 UPB_INLINE uint16_t upb_EncodeOptions_GetMaxDepth(uint32_t options) {
59   return options >> 16;
60 }
61 
62 // Enforce an upper bound on recursion depth.
upb_Encode_LimitDepth(uint32_t encode_options,uint32_t limit)63 UPB_INLINE int upb_Encode_LimitDepth(uint32_t encode_options, uint32_t limit) {
64   uint32_t max_depth = upb_EncodeOptions_GetMaxDepth(encode_options);
65   if (max_depth > limit) max_depth = limit;
66   return upb_EncodeOptions_MaxDepth(max_depth) | (encode_options & 0xffff);
67 }
68 
69 UPB_API upb_EncodeStatus upb_Encode(const upb_Message* msg,
70                                     const upb_MiniTable* l, int options,
71                                     upb_Arena* arena, char** buf, size_t* size);
72 
73 // Encodes the message prepended by a varint of the serialized length.
74 UPB_API upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg,
75                                                   const upb_MiniTable* l,
76                                                   int options, upb_Arena* arena,
77                                                   char** buf, size_t* size);
78 // Utility function for wrapper languages to get an error string from a
79 // upb_EncodeStatus.
80 UPB_API const char* upb_EncodeStatus_String(upb_EncodeStatus status);
81 
82 #ifdef __cplusplus
83 } /* extern "C" */
84 #endif
85 
86 #include "upb/port/undef.inc"
87 
88 #endif /* UPB_WIRE_ENCODE_H_ */
89