1 /*
2 * Copyright (c) 2009-2021, Google LLC
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google LLC nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 ** Our memory representation for parsing tables and messages themselves.
30 ** Functions in this file are used by generated code and possibly reflection.
31 **
32 ** The definitions in this file are internal to upb.
33 **/
34
35 #ifndef UPB_MESSAGE_INTERNAL_H_
36 #define UPB_MESSAGE_INTERNAL_H_
37
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "upb/hash/common.h"
42 #include "upb/message/extension_internal.h"
43 #include "upb/message/message.h"
44 #include "upb/mini_table/extension_internal.h"
45 #include "upb/mini_table/extension_registry.h"
46 #include "upb/mini_table/file_internal.h"
47 #include "upb/mini_table/message_internal.h"
48
49 // Must be last.
50 #include "upb/port/def.inc"
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 extern const float kUpb_FltInfinity;
57 extern const double kUpb_Infinity;
58 extern const double kUpb_NaN;
59
60 /* Internal members of a upb_Message that track unknown fields and/or
61 * extensions. We can change this without breaking binary compatibility. We put
62 * these before the user's data. The user's upb_Message* points after the
63 * upb_Message_Internal. */
64
65 typedef struct {
66 /* Total size of this structure, including the data that follows.
67 * Must be aligned to 8, which is alignof(upb_Message_Extension) */
68 uint32_t size;
69
70 /* Offsets relative to the beginning of this structure.
71 *
72 * Unknown data grows forward from the beginning to unknown_end.
73 * Extension data grows backward from size to ext_begin.
74 * When the two meet, we're out of data and have to realloc.
75 *
76 * If we imagine that the final member of this struct is:
77 * char data[size - overhead]; // overhead =
78 * sizeof(upb_Message_InternalData)
79 *
80 * Then we have:
81 * unknown data: data[0 .. (unknown_end - overhead)]
82 * extensions data: data[(ext_begin - overhead) .. (size - overhead)] */
83 uint32_t unknown_end;
84 uint32_t ext_begin;
85 /* Data follows, as if there were an array:
86 * char data[size - sizeof(upb_Message_InternalData)]; */
87 } upb_Message_InternalData;
88
89 typedef struct {
90 upb_Message_InternalData* internal;
91 /* Message data follows. */
92 } upb_Message_Internal;
93
94 /* Maps upb_CType -> memory size. */
95 extern char _upb_CTypeo_size[12];
96
upb_msg_sizeof(const upb_MiniTable * t)97 UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) {
98 return t->size + sizeof(upb_Message_Internal);
99 }
100
101 // Inline version upb_Message_New(), for internal use.
_upb_Message_New(const upb_MiniTable * mini_table,upb_Arena * arena)102 UPB_INLINE upb_Message* _upb_Message_New(const upb_MiniTable* mini_table,
103 upb_Arena* arena) {
104 size_t size = upb_msg_sizeof(mini_table);
105 void* mem = upb_Arena_Malloc(arena, size + sizeof(upb_Message_Internal));
106 if (UPB_UNLIKELY(!mem)) return NULL;
107 upb_Message* msg = UPB_PTR_AT(mem, sizeof(upb_Message_Internal), upb_Message);
108 memset(mem, 0, size);
109 return msg;
110 }
111
upb_Message_Getinternal(const upb_Message * msg)112 UPB_INLINE upb_Message_Internal* upb_Message_Getinternal(
113 const upb_Message* msg) {
114 ptrdiff_t size = sizeof(upb_Message_Internal);
115 return (upb_Message_Internal*)((char*)msg - size);
116 }
117
118 // Clears the given message.
119 void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l);
120
121 // Discards the unknown fields for this message only.
122 void _upb_Message_DiscardUnknown_shallow(upb_Message* msg);
123
124 // Adds unknown data (serialized protobuf data) to the given message.
125 // The data is copied into the message instance.
126 bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len,
127 upb_Arena* arena);
128
129 #ifdef __cplusplus
130 } /* extern "C" */
131 #endif
132
133 #include "upb/port/undef.inc"
134
135 #endif /* UPB_MESSAGE_INTERNAL_H_ */
136