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 7.8 kB

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