You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

mini_table.h 8.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) 2009-2022, 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. #ifndef UPB_MINI_TABLE_H_
  28. #define UPB_MINI_TABLE_H_
  29. #include "upb/msg_internal.h"
  30. // Must be last.
  31. #include "upb/port_def.inc"
  32. #ifdef __cplusplus
  33. extern "C" {
  34. #endif
  35. const upb_MiniTable_Field* upb_MiniTable_FindFieldByNumber(
  36. const upb_MiniTable* table, uint32_t number);
  37. UPB_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
  38. const upb_MiniTable* mini_table, const upb_MiniTable_Field* field) {
  39. return mini_table->subs[field->submsg_index].submsg;
  40. }
  41. UPB_INLINE bool upb_MiniTable_Enum_CheckValue(const upb_MiniTable_Enum* e,
  42. int32_t val) {
  43. uint32_t uval = (uint32_t)val;
  44. if (uval < 64) return e->mask & (1ULL << uval);
  45. // OPT: binary search long lists?
  46. int n = e->value_count;
  47. for (int i = 0; i < n; i++) {
  48. if (e->values[i] == val) return true;
  49. }
  50. return false;
  51. }
  52. /** upb_MtDataEncoder *********************************************************/
  53. // Functions to encode a string in a format that can be loaded by
  54. // upb_MiniTable_Build().
  55. typedef enum {
  56. kUpb_MessageModifier_ValidateUtf8 = 1 << 0,
  57. kUpb_MessageModifier_DefaultIsPacked = 1 << 1,
  58. kUpb_MessageModifier_IsExtendable = 1 << 2,
  59. } kUpb_MessageModifier;
  60. typedef enum {
  61. kUpb_FieldModifier_IsRepeated = 1 << 0,
  62. kUpb_FieldModifier_IsPacked = 1 << 1,
  63. kUpb_FieldModifier_IsClosedEnum = 1 << 2,
  64. kUpb_FieldModifier_IsProto3Singular = 1 << 3,
  65. kUpb_FieldModifier_IsRequired = 1 << 4,
  66. } kUpb_FieldModifier;
  67. typedef struct {
  68. char* end; // Limit of the buffer passed as a parameter.
  69. // Aliased to internal-only members in .cc.
  70. char internal[32];
  71. } upb_MtDataEncoder;
  72. // If the input buffer has at least this many bytes available, the encoder call
  73. // is guaranteed to succeed (as long as field number order is maintained).
  74. #define kUpb_MtDataEncoder_MinSize 16
  75. // Encodes field/oneof information for a given message. The sequence of calls
  76. // should look like:
  77. //
  78. // upb_MtDataEncoder e;
  79. // char buf[256];
  80. // char* ptr = buf;
  81. // e.end = ptr + sizeof(buf);
  82. // ptr = upb_MtDataEncoder_StartMessage(&e, ptr);
  83. // // Fields *must* be in field number order.
  84. // ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
  85. // ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
  86. // ptr = upb_MtDataEncoder_PutField(&e, ptr, ...);
  87. //
  88. // // If oneofs are present. Oneofs must be encoded after regular fields.
  89. // ptr = upb_MiniTable_StartOneof(&e, ptr)
  90. // ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
  91. // ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
  92. //
  93. // ptr = upb_MiniTable_StartOneof(&e, ptr);
  94. // ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
  95. // ptr = upb_MiniTable_PutOneofField(&e, ptr, ...);
  96. //
  97. // Oneofs must be encoded after all regular fields.
  98. char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
  99. uint64_t msg_mod);
  100. char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
  101. upb_FieldType type, uint32_t field_num,
  102. uint64_t field_mod);
  103. char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
  104. char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
  105. uint32_t field_num);
  106. // Encodes the set of values for a given enum. The values must be given in
  107. // order (after casting to uint32_t), and repeats are not allowed.
  108. void upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e);
  109. char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
  110. uint32_t val);
  111. char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr);
  112. /** upb_MiniTable *************************************************************/
  113. typedef enum {
  114. kUpb_MiniTablePlatform_32Bit,
  115. kUpb_MiniTablePlatform_64Bit,
  116. kUpb_MiniTablePlatform_Native =
  117. UPB_SIZE(kUpb_MiniTablePlatform_32Bit, kUpb_MiniTablePlatform_64Bit),
  118. } upb_MiniTablePlatform;
  119. // Builds a mini table from the data encoded in the buffer [data, len]. If any
  120. // errors occur, returns NULL and sets a status message. In the success case,
  121. // the caller must call upb_MiniTable_SetSub*() for all message or proto2 enum
  122. // fields to link the table to the appropriate sub-tables.
  123. upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
  124. upb_MiniTablePlatform platform,
  125. upb_Arena* arena, upb_Status* status);
  126. void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
  127. upb_MiniTable_Field* field,
  128. const upb_MiniTable* sub);
  129. void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTable_Field* field,
  130. const upb_MiniTable_Enum* sub);
  131. bool upb_MiniTable_BuildExtension(const char* data, size_t len,
  132. upb_MiniTable_Extension* ext,
  133. upb_MiniTable_Sub sub, upb_Status* status);
  134. // Special-case functions for MessageSet layout and map entries.
  135. upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
  136. upb_Arena* arena);
  137. upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
  138. upb_FieldType value_type,
  139. bool value_is_proto3_enum,
  140. upb_MiniTablePlatform platform,
  141. upb_Arena* arena);
  142. upb_MiniTable_Enum* upb_MiniTable_BuildEnum(const char* data, size_t len,
  143. upb_Arena* arena,
  144. upb_Status* status);
  145. // Like upb_MiniTable_Build(), but the user provides a buffer of layout data so
  146. // it can be reused from call to call, avoiding repeated realloc()/free().
  147. //
  148. // The caller owns `*buf` both before and after the call, and must free() it
  149. // when it is no longer in use. The function will realloc() `*buf` as
  150. // necessary, updating `*size` accordingly.
  151. upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
  152. upb_MiniTablePlatform platform,
  153. upb_Arena* arena, void** buf,
  154. size_t* buf_size, upb_Status* status);
  155. // For testing only.
  156. char upb_ToBase92(int8_t ch);
  157. char upb_FromBase92(uint8_t ch);
  158. bool upb_IsTypePackable(upb_FieldType type);
  159. #ifdef __cplusplus
  160. } /* extern "C" */
  161. #endif
  162. #include "upb/port_undef.inc"
  163. #endif /* UPB_MINI_TABLE_H_ */