encode.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
  2. #include "upb/encode.h"
  3. #include <string.h>
  4. #include "upb/msg.h"
  5. #include "upb/upb.h"
  6. #include "upb/port_def.inc"
  7. #define UPB_PB_VARINT_MAX_LEN 10
  8. #define CHK(x) do { if (!(x)) { return false; } } while(0)
  9. static size_t upb_encode_varint(uint64_t val, char *buf) {
  10. size_t i;
  11. if (val < 128) { buf[0] = val; return 1; }
  12. i = 0;
  13. while (val) {
  14. uint8_t byte = val & 0x7fU;
  15. val >>= 7;
  16. if (val) byte |= 0x80U;
  17. buf[i++] = byte;
  18. }
  19. return i;
  20. }
  21. static uint32_t upb_zzencode_32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
  22. static uint64_t upb_zzencode_64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
  23. typedef struct {
  24. upb_alloc *alloc;
  25. char *buf, *ptr, *limit;
  26. } upb_encstate;
  27. static size_t upb_roundup_pow2(size_t bytes) {
  28. size_t ret = 128;
  29. while (ret < bytes) {
  30. ret *= 2;
  31. }
  32. return ret;
  33. }
  34. static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
  35. size_t old_size = e->limit - e->buf;
  36. size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
  37. char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
  38. CHK(new_buf);
  39. /* We want previous data at the end, realloc() put it at the beginning. */
  40. if (old_size > 0) {
  41. memmove(new_buf + new_size - old_size, e->buf, old_size);
  42. }
  43. e->ptr = new_buf + new_size - (e->limit - e->ptr);
  44. e->limit = new_buf + new_size;
  45. e->buf = new_buf;
  46. return true;
  47. }
  48. /* Call to ensure that at least "bytes" bytes are available for writing at
  49. * e->ptr. Returns false if the bytes could not be allocated. */
  50. static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
  51. CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
  52. upb_encode_growbuffer(e, bytes));
  53. e->ptr -= bytes;
  54. return true;
  55. }
  56. /* Writes the given bytes to the buffer, handling reserve/advance. */
  57. static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
  58. if (len == 0) return true;
  59. CHK(upb_encode_reserve(e, len));
  60. memcpy(e->ptr, data, len);
  61. return true;
  62. }
  63. static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
  64. /* TODO(haberman): byte-swap for big endian. */
  65. return upb_put_bytes(e, &val, sizeof(uint64_t));
  66. }
  67. static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
  68. /* TODO(haberman): byte-swap for big endian. */
  69. return upb_put_bytes(e, &val, sizeof(uint32_t));
  70. }
  71. static bool upb_put_varint(upb_encstate *e, uint64_t val) {
  72. size_t len;
  73. char *start;
  74. CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
  75. len = upb_encode_varint(val, e->ptr);
  76. start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
  77. memmove(start, e->ptr, len);
  78. e->ptr = start;
  79. return true;
  80. }
  81. static bool upb_put_double(upb_encstate *e, double d) {
  82. uint64_t u64;
  83. UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
  84. memcpy(&u64, &d, sizeof(uint64_t));
  85. return upb_put_fixed64(e, u64);
  86. }
  87. static bool upb_put_float(upb_encstate *e, float d) {
  88. uint32_t u32;
  89. UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
  90. memcpy(&u32, &d, sizeof(uint32_t));
  91. return upb_put_fixed32(e, u32);
  92. }
  93. static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
  94. uint32_t ret;
  95. uint32_t offset = ~f->presence;
  96. memcpy(&ret, msg + offset, sizeof(ret));
  97. return ret;
  98. }
  99. static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
  100. uint32_t hasbit = f->presence;
  101. UPB_ASSERT(f->presence > 0);
  102. return msg[hasbit / 8] & (1 << (hasbit % 8));
  103. }
  104. static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
  105. return upb_put_varint(e, (field_number << 3) | wire_type);
  106. }
  107. static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
  108. size_t size) {
  109. size_t bytes = arr->len * size;
  110. const void* data = _upb_array_constptr(arr);
  111. return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes);
  112. }
  113. bool upb_encode_message(upb_encstate *e, const char *msg,
  114. const upb_msglayout *m, size_t *size);
  115. static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
  116. const upb_msglayout *m,
  117. const upb_msglayout_field *f,
  118. bool skip_zero_value) {
  119. const char *field_mem = _field_mem;
  120. #define CASE(ctype, type, wire_type, encodeval) do { \
  121. ctype val = *(ctype*)field_mem; \
  122. if (skip_zero_value && val == 0) { \
  123. return true; \
  124. } \
  125. return upb_put_ ## type(e, encodeval) && \
  126. upb_put_tag(e, f->number, wire_type); \
  127. } while(0)
  128. switch (f->descriptortype) {
  129. case UPB_DESCRIPTOR_TYPE_DOUBLE:
  130. CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
  131. case UPB_DESCRIPTOR_TYPE_FLOAT:
  132. CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
  133. case UPB_DESCRIPTOR_TYPE_INT64:
  134. case UPB_DESCRIPTOR_TYPE_UINT64:
  135. CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
  136. case UPB_DESCRIPTOR_TYPE_UINT32:
  137. CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
  138. case UPB_DESCRIPTOR_TYPE_INT32:
  139. case UPB_DESCRIPTOR_TYPE_ENUM:
  140. CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
  141. case UPB_DESCRIPTOR_TYPE_SFIXED64:
  142. case UPB_DESCRIPTOR_TYPE_FIXED64:
  143. CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
  144. case UPB_DESCRIPTOR_TYPE_FIXED32:
  145. case UPB_DESCRIPTOR_TYPE_SFIXED32:
  146. CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
  147. case UPB_DESCRIPTOR_TYPE_BOOL:
  148. CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
  149. case UPB_DESCRIPTOR_TYPE_SINT32:
  150. CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
  151. case UPB_DESCRIPTOR_TYPE_SINT64:
  152. CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
  153. case UPB_DESCRIPTOR_TYPE_STRING:
  154. case UPB_DESCRIPTOR_TYPE_BYTES: {
  155. upb_strview view = *(upb_strview*)field_mem;
  156. if (skip_zero_value && view.size == 0) {
  157. return true;
  158. }
  159. return upb_put_bytes(e, view.data, view.size) &&
  160. upb_put_varint(e, view.size) &&
  161. upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
  162. }
  163. case UPB_DESCRIPTOR_TYPE_GROUP: {
  164. size_t size;
  165. void *submsg = *(void **)field_mem;
  166. const upb_msglayout *subm = m->submsgs[f->submsg_index];
  167. if (submsg == NULL) {
  168. return true;
  169. }
  170. return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
  171. upb_encode_message(e, submsg, subm, &size) &&
  172. upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
  173. }
  174. case UPB_DESCRIPTOR_TYPE_MESSAGE: {
  175. size_t size;
  176. void *submsg = *(void **)field_mem;
  177. const upb_msglayout *subm = m->submsgs[f->submsg_index];
  178. if (submsg == NULL) {
  179. return true;
  180. }
  181. return upb_encode_message(e, submsg, subm, &size) &&
  182. upb_put_varint(e, size) &&
  183. upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
  184. }
  185. }
  186. #undef CASE
  187. UPB_UNREACHABLE();
  188. }
  189. static bool upb_encode_array(upb_encstate *e, const char *field_mem,
  190. const upb_msglayout *m,
  191. const upb_msglayout_field *f) {
  192. const upb_array *arr = *(const upb_array**)field_mem;
  193. if (arr == NULL || arr->len == 0) {
  194. return true;
  195. }
  196. #define VARINT_CASE(ctype, encode) { \
  197. const ctype *start = _upb_array_constptr(arr); \
  198. const ctype *ptr = start + arr->len; \
  199. size_t pre_len = e->limit - e->ptr; \
  200. do { \
  201. ptr--; \
  202. CHK(upb_put_varint(e, encode)); \
  203. } while (ptr != start); \
  204. CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
  205. } \
  206. break; \
  207. do { ; } while(0)
  208. switch (f->descriptortype) {
  209. case UPB_DESCRIPTOR_TYPE_DOUBLE:
  210. CHK(upb_put_fixedarray(e, arr, sizeof(double)));
  211. break;
  212. case UPB_DESCRIPTOR_TYPE_FLOAT:
  213. CHK(upb_put_fixedarray(e, arr, sizeof(float)));
  214. break;
  215. case UPB_DESCRIPTOR_TYPE_SFIXED64:
  216. case UPB_DESCRIPTOR_TYPE_FIXED64:
  217. CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
  218. break;
  219. case UPB_DESCRIPTOR_TYPE_FIXED32:
  220. case UPB_DESCRIPTOR_TYPE_SFIXED32:
  221. CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
  222. break;
  223. case UPB_DESCRIPTOR_TYPE_INT64:
  224. case UPB_DESCRIPTOR_TYPE_UINT64:
  225. VARINT_CASE(uint64_t, *ptr);
  226. case UPB_DESCRIPTOR_TYPE_UINT32:
  227. VARINT_CASE(uint32_t, *ptr);
  228. case UPB_DESCRIPTOR_TYPE_INT32:
  229. case UPB_DESCRIPTOR_TYPE_ENUM:
  230. VARINT_CASE(int32_t, (int64_t)*ptr);
  231. case UPB_DESCRIPTOR_TYPE_BOOL:
  232. VARINT_CASE(bool, *ptr);
  233. case UPB_DESCRIPTOR_TYPE_SINT32:
  234. VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
  235. case UPB_DESCRIPTOR_TYPE_SINT64:
  236. VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
  237. case UPB_DESCRIPTOR_TYPE_STRING:
  238. case UPB_DESCRIPTOR_TYPE_BYTES: {
  239. const upb_strview *start = _upb_array_constptr(arr);
  240. const upb_strview *ptr = start + arr->len;
  241. do {
  242. ptr--;
  243. CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
  244. upb_put_varint(e, ptr->size) &&
  245. upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
  246. } while (ptr != start);
  247. return true;
  248. }
  249. case UPB_DESCRIPTOR_TYPE_GROUP: {
  250. const void *const*start = _upb_array_constptr(arr);
  251. const void *const*ptr = start + arr->len;
  252. const upb_msglayout *subm = m->submsgs[f->submsg_index];
  253. do {
  254. size_t size;
  255. ptr--;
  256. CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
  257. upb_encode_message(e, *ptr, subm, &size) &&
  258. upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
  259. } while (ptr != start);
  260. return true;
  261. }
  262. case UPB_DESCRIPTOR_TYPE_MESSAGE: {
  263. const void *const*start = _upb_array_constptr(arr);
  264. const void *const*ptr = start + arr->len;
  265. const upb_msglayout *subm = m->submsgs[f->submsg_index];
  266. do {
  267. size_t size;
  268. ptr--;
  269. CHK(upb_encode_message(e, *ptr, subm, &size) &&
  270. upb_put_varint(e, size) &&
  271. upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
  272. } while (ptr != start);
  273. return true;
  274. }
  275. }
  276. #undef VARINT_CASE
  277. /* We encode all primitive arrays as packed, regardless of what was specified
  278. * in the .proto file. Could special case 1-sized arrays. */
  279. CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
  280. return true;
  281. }
  282. static bool upb_encode_map(upb_encstate *e, const char *field_mem,
  283. const upb_msglayout *m,
  284. const upb_msglayout_field *f) {
  285. const upb_map *map = *(const upb_map**)field_mem;
  286. const upb_msglayout *entry = m->submsgs[f->submsg_index];
  287. const upb_msglayout_field *key_field = &entry->fields[0];
  288. const upb_msglayout_field *val_field = &entry->fields[1];
  289. upb_strtable_iter i;
  290. if (map == NULL) {
  291. return true;
  292. }
  293. upb_strtable_begin(&i, &map->table);
  294. for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
  295. size_t pre_len = e->limit - e->ptr;
  296. size_t size;
  297. upb_strview key = upb_strtable_iter_key(&i);
  298. const upb_value val = upb_strtable_iter_value(&i);
  299. const void *keyp =
  300. map->key_size == UPB_MAPTYPE_STRING ? (void *)&key : key.data;
  301. const void *valp =
  302. map->val_size == UPB_MAPTYPE_STRING ? upb_value_getptr(val) : &val;
  303. CHK(upb_encode_scalarfield(e, valp, entry, val_field, false));
  304. CHK(upb_encode_scalarfield(e, keyp, entry, key_field, false));
  305. size = (e->limit - e->ptr) - pre_len;
  306. CHK(upb_put_varint(e, size));
  307. CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
  308. }
  309. return true;
  310. }
  311. bool upb_encode_message(upb_encstate *e, const char *msg,
  312. const upb_msglayout *m, size_t *size) {
  313. int i;
  314. size_t pre_len = e->limit - e->ptr;
  315. const char *unknown;
  316. size_t unknown_size;
  317. unknown = upb_msg_getunknown(msg, &unknown_size);
  318. if (unknown) {
  319. upb_put_bytes(e, unknown, unknown_size);
  320. }
  321. for (i = m->field_count - 1; i >= 0; i--) {
  322. const upb_msglayout_field *f = &m->fields[i];
  323. if (f->label == UPB_LABEL_REPEATED) {
  324. CHK(upb_encode_array(e, msg + f->offset, m, f));
  325. } else if (f->label == UPB_LABEL_MAP) {
  326. CHK(upb_encode_map(e, msg + f->offset, m, f));
  327. } else {
  328. bool skip_empty = false;
  329. if (f->presence == 0) {
  330. /* Proto3 presence. */
  331. skip_empty = true;
  332. } else if (f->presence > 0) {
  333. /* Proto2 presence: hasbit. */
  334. if (!upb_readhasbit(msg, f)) {
  335. continue;
  336. }
  337. } else {
  338. /* Field is in a oneof. */
  339. if (upb_readcase(msg, f) != f->number) {
  340. continue;
  341. }
  342. }
  343. CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
  344. }
  345. }
  346. *size = (e->limit - e->ptr) - pre_len;
  347. return true;
  348. }
  349. char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
  350. size_t *size) {
  351. upb_encstate e;
  352. e.alloc = upb_arena_alloc(arena);
  353. e.buf = NULL;
  354. e.limit = NULL;
  355. e.ptr = NULL;
  356. if (!upb_encode_message(&e, msg, m, size)) {
  357. *size = 0;
  358. return NULL;
  359. }
  360. *size = e.limit - e.ptr;
  361. if (*size == 0) {
  362. static char ch;
  363. return &ch;
  364. } else {
  365. UPB_ASSERT(e.ptr);
  366. return e.ptr;
  367. }
  368. }
  369. #undef CHK