encode_decode.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include "protobuf.h"
  31. #include "utf8.h"
  32. /* stringsink *****************************************************************/
  33. typedef struct {
  34. upb_byteshandler handler;
  35. upb_bytessink sink;
  36. char *ptr;
  37. size_t len, size;
  38. } stringsink;
  39. static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
  40. stringsink *sink = _sink;
  41. sink->len = 0;
  42. return sink;
  43. }
  44. static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
  45. size_t len, const upb_bufhandle *handle) {
  46. stringsink *sink = _sink;
  47. size_t new_size = sink->size;
  48. UPB_UNUSED(hd);
  49. UPB_UNUSED(handle);
  50. while (sink->len + len > new_size) {
  51. new_size *= 2;
  52. }
  53. if (new_size != sink->size) {
  54. sink->ptr = realloc(sink->ptr, new_size);
  55. sink->size = new_size;
  56. }
  57. memcpy(sink->ptr + sink->len, ptr, len);
  58. sink->len += len;
  59. return len;
  60. }
  61. void stringsink_init(stringsink *sink) {
  62. upb_byteshandler_init(&sink->handler);
  63. upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
  64. upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
  65. upb_bytessink_reset(&sink->sink, &sink->handler, sink);
  66. sink->size = 32;
  67. sink->ptr = malloc(sink->size);
  68. sink->len = 0;
  69. }
  70. void stringsink_uninit(stringsink *sink) { free(sink->ptr); }
  71. /* stackenv *****************************************************************/
  72. // Stack-allocated context during an encode/decode operation. Contains the upb
  73. // environment and its stack-based allocator, an initial buffer for allocations
  74. // to avoid malloc() when possible, and a template for PHP exception messages
  75. // if any error occurs.
  76. #define STACK_ENV_STACKBYTES 4096
  77. typedef struct {
  78. upb_env env;
  79. const char *php_error_template;
  80. char allocbuf[STACK_ENV_STACKBYTES];
  81. } stackenv;
  82. static void stackenv_init(stackenv* se, const char* errmsg);
  83. static void stackenv_uninit(stackenv* se);
  84. // Callback invoked by upb if any error occurs during parsing or serialization.
  85. static bool env_error_func(void* ud, const upb_status* status) {
  86. stackenv* se = ud;
  87. // Free the env -- zend_error will longjmp up the stack past the
  88. // encode/decode function so it would not otherwise have been freed.
  89. stackenv_uninit(se);
  90. // TODO(teboring): have a way to verify that this is actually a parse error,
  91. // instead of just throwing "parse error" unconditionally.
  92. zend_error(E_ERROR, se->php_error_template, upb_status_errmsg(status));
  93. // Never reached.
  94. return false;
  95. }
  96. static void stackenv_init(stackenv* se, const char* errmsg) {
  97. se->php_error_template = errmsg;
  98. upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
  99. upb_env_seterrorfunc(&se->env, env_error_func, se);
  100. }
  101. static void stackenv_uninit(stackenv* se) {
  102. upb_env_uninit(&se->env);
  103. }
  104. // -----------------------------------------------------------------------------
  105. // Parsing.
  106. // -----------------------------------------------------------------------------
  107. #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
  108. // Creates a handlerdata that simply contains the offset for this field.
  109. static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
  110. size_t* hd_ofs = (size_t*)malloc(sizeof(size_t));
  111. *hd_ofs = ofs;
  112. upb_handlers_addcleanup(h, hd_ofs, free);
  113. return hd_ofs;
  114. }
  115. typedef struct {
  116. size_t ofs;
  117. const upb_msgdef *md;
  118. } submsg_handlerdata_t;
  119. // Creates a handlerdata that contains offset and submessage type information.
  120. static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
  121. const upb_fielddef* f) {
  122. submsg_handlerdata_t* hd =
  123. (submsg_handlerdata_t*)malloc(sizeof(submsg_handlerdata_t));
  124. hd->ofs = ofs;
  125. hd->md = upb_fielddef_msgsubdef(f);
  126. upb_handlers_addcleanup(h, hd, free);
  127. return hd;
  128. }
  129. typedef struct {
  130. size_t ofs; // union data slot
  131. size_t case_ofs; // oneof_case field
  132. int property_ofs; // properties table cache
  133. uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
  134. const upb_msgdef *md; // msgdef, for oneof submessage handler
  135. } oneof_handlerdata_t;
  136. static const void *newoneofhandlerdata(upb_handlers *h,
  137. uint32_t ofs,
  138. uint32_t case_ofs,
  139. int property_ofs,
  140. const upb_fielddef *f) {
  141. oneof_handlerdata_t* hd =
  142. (oneof_handlerdata_t*)malloc(sizeof(oneof_handlerdata_t));
  143. hd->ofs = ofs;
  144. hd->case_ofs = case_ofs;
  145. hd->property_ofs = property_ofs;
  146. // We reuse the field tag number as a oneof union discriminant tag. Note that
  147. // we don't expose these numbers to the user, so the only requirement is that
  148. // we have some unique ID for each union case/possibility. The field tag
  149. // numbers are already present and are easy to use so there's no reason to
  150. // create a separate ID space. In addition, using the field tag number here
  151. // lets us easily look up the field in the oneof accessor.
  152. hd->oneof_case_num = upb_fielddef_number(f);
  153. if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
  154. hd->md = upb_fielddef_msgsubdef(f);
  155. } else {
  156. hd->md = NULL;
  157. }
  158. upb_handlers_addcleanup(h, hd, free);
  159. return hd;
  160. }
  161. // A handler that starts a repeated field. Gets the Repeated*Field instance for
  162. // this field (such an instance always exists even in an empty message).
  163. static void *startseq_handler(void* closure, const void* hd) {
  164. MessageHeader* msg = closure;
  165. const size_t *ofs = hd;
  166. return (void*)(*DEREF(msg, *ofs, zval**));
  167. }
  168. // Handlers that append primitive values to a repeated field.
  169. #define DEFINE_APPEND_HANDLER(type, ctype) \
  170. static bool append##type##_handler(void* closure, const void* hd, \
  171. ctype val) { \
  172. zval* array = (zval*)closure; \
  173. TSRMLS_FETCH(); \
  174. RepeatedField* intern = \
  175. (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); \
  176. repeated_field_push_native(intern, &val TSRMLS_CC); \
  177. return true; \
  178. }
  179. DEFINE_APPEND_HANDLER(bool, bool)
  180. DEFINE_APPEND_HANDLER(int32, int32_t)
  181. DEFINE_APPEND_HANDLER(uint32, uint32_t)
  182. DEFINE_APPEND_HANDLER(float, float)
  183. DEFINE_APPEND_HANDLER(int64, int64_t)
  184. DEFINE_APPEND_HANDLER(uint64, uint64_t)
  185. DEFINE_APPEND_HANDLER(double, double)
  186. // Appends a string to a repeated field.
  187. static void* appendstr_handler(void *closure,
  188. const void *hd,
  189. size_t size_hint) {
  190. zval* array = (zval*)closure;
  191. TSRMLS_FETCH();
  192. RepeatedField* intern =
  193. (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
  194. zval* str;
  195. MAKE_STD_ZVAL(str);
  196. ZVAL_STRING(str, "", 1);
  197. repeated_field_push_native(intern, &str TSRMLS_CC);
  198. return (void*)str;
  199. }
  200. // Appends a 'bytes' string to a repeated field.
  201. static void* appendbytes_handler(void *closure,
  202. const void *hd,
  203. size_t size_hint) {
  204. zval* array = (zval*)closure;
  205. TSRMLS_FETCH();
  206. RepeatedField* intern =
  207. (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
  208. zval* str;
  209. MAKE_STD_ZVAL(str);
  210. ZVAL_STRING(str, "", 1);
  211. repeated_field_push_native(intern, &str TSRMLS_CC);
  212. return (void*)str;
  213. }
  214. static void *empty_php_string(zval** value_ptr) {
  215. SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
  216. zval* str = *value_ptr;
  217. zval_dtor(str);
  218. ZVAL_STRINGL(str, "", 0, 1);
  219. return (void*)str;
  220. }
  221. // Sets a non-repeated string field in a message.
  222. static void* str_handler(void *closure,
  223. const void *hd,
  224. size_t size_hint) {
  225. MessageHeader* msg = closure;
  226. const size_t *ofs = hd;
  227. return empty_php_string(DEREF(msg, *ofs, zval**));
  228. }
  229. // Sets a non-repeated 'bytes' field in a message.
  230. static void* bytes_handler(void *closure,
  231. const void *hd,
  232. size_t size_hint) {
  233. MessageHeader* msg = closure;
  234. const size_t *ofs = hd;
  235. return empty_php_string(DEREF(msg, *ofs, zval**));
  236. }
  237. static size_t stringdata_handler(void* closure, const void* hd,
  238. const char* str, size_t len,
  239. const upb_bufhandle* handle) {
  240. zval* php_str = (zval*)closure;
  241. char* old_str = Z_STRVAL_P(php_str);
  242. size_t old_len = Z_STRLEN_P(php_str);
  243. assert(old_str != NULL);
  244. char* new_str = emalloc(old_len + len + 1);
  245. memcpy(new_str, old_str, old_len);
  246. memcpy(new_str + old_len, str, len);
  247. new_str[old_len + len] = 0;
  248. FREE(old_str);
  249. Z_STRVAL_P(php_str) = new_str;
  250. Z_STRLEN_P(php_str) = old_len + len;
  251. return len;
  252. }
  253. // Appends a submessage to a repeated field.
  254. static void *appendsubmsg_handler(void *closure, const void *hd) {
  255. zval* array = (zval*)closure;
  256. TSRMLS_FETCH();
  257. RepeatedField* intern =
  258. (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
  259. const submsg_handlerdata_t *submsgdata = hd;
  260. zval* subdesc_php = get_def_obj((void*)submsgdata->md);
  261. Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
  262. zend_class_entry* subklass = subdesc->klass;
  263. MessageHeader* submsg;
  264. zval* val = NULL;
  265. MAKE_STD_ZVAL(val);
  266. Z_TYPE_P(val) = IS_OBJECT;
  267. Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
  268. repeated_field_push_native(intern, &val TSRMLS_CC);
  269. submsg = zend_object_store_get_object(val TSRMLS_CC);
  270. return submsg;
  271. }
  272. // Sets a non-repeated submessage field in a message.
  273. static void *submsg_handler(void *closure, const void *hd) {
  274. MessageHeader* msg = closure;
  275. const submsg_handlerdata_t* submsgdata = hd;
  276. zval* subdesc_php = get_def_obj((void*)submsgdata->md);
  277. TSRMLS_FETCH();
  278. Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
  279. zend_class_entry* subklass = subdesc->klass;
  280. zval* submsg_php;
  281. MessageHeader* submsg;
  282. if (Z_TYPE_P(*DEREF(msg, submsgdata->ofs, zval**)) == IS_NULL) {
  283. zval* val = NULL;
  284. MAKE_STD_ZVAL(val);
  285. Z_TYPE_P(val) = IS_OBJECT;
  286. Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
  287. zval_ptr_dtor(DEREF(msg, submsgdata->ofs, zval**));
  288. *DEREF(msg, submsgdata->ofs, zval**) = val;
  289. }
  290. submsg_php = *DEREF(msg, submsgdata->ofs, zval**);
  291. submsg = zend_object_store_get_object(submsg_php TSRMLS_CC);
  292. return submsg;
  293. }
  294. // Handler data for startmap/endmap handlers.
  295. typedef struct {
  296. size_t ofs;
  297. upb_fieldtype_t key_field_type;
  298. upb_fieldtype_t value_field_type;
  299. // We know that we can hold this reference because the handlerdata has the
  300. // same lifetime as the upb_handlers struct, and the upb_handlers struct holds
  301. // a reference to the upb_msgdef, which in turn has references to its subdefs.
  302. const upb_def* value_field_subdef;
  303. } map_handlerdata_t;
  304. // Temporary frame for map parsing: at the beginning of a map entry message, a
  305. // submsg handler allocates a frame to hold (i) a reference to the Map object
  306. // into which this message will be inserted and (ii) storage slots to
  307. // temporarily hold the key and value for this map entry until the end of the
  308. // submessage. When the submessage ends, another handler is called to insert the
  309. // value into the map.
  310. typedef struct {
  311. zval* map;
  312. char key_storage[NATIVE_SLOT_MAX_SIZE];
  313. char value_storage[NATIVE_SLOT_MAX_SIZE];
  314. } map_parse_frame_t;
  315. static void map_slot_init(void* memory, upb_fieldtype_t type) {
  316. switch (type) {
  317. case UPB_TYPE_STRING:
  318. case UPB_TYPE_BYTES: {
  319. // Store zval** in memory in order to be consistent with the layout of
  320. // singular fields.
  321. zval** holder = ALLOC(zval*);
  322. zval* tmp;
  323. MAKE_STD_ZVAL(tmp);
  324. ZVAL_STRINGL(tmp, "", 0, 1);
  325. *holder = tmp;
  326. *(zval***)memory = holder;
  327. break;
  328. }
  329. case UPB_TYPE_MESSAGE: {
  330. zval** holder = ALLOC(zval*);
  331. zval* tmp;
  332. MAKE_STD_ZVAL(tmp);
  333. ZVAL_NULL(tmp);
  334. *holder = tmp;
  335. *(zval***)memory = holder;
  336. break;
  337. }
  338. default:
  339. native_slot_init(type, memory, NULL);
  340. }
  341. }
  342. static void map_slot_uninit(void* memory, upb_fieldtype_t type) {
  343. switch (type) {
  344. case UPB_TYPE_MESSAGE:
  345. case UPB_TYPE_STRING:
  346. case UPB_TYPE_BYTES: {
  347. zval** holder = *(zval***)memory;
  348. zval_ptr_dtor(holder);
  349. FREE(holder);
  350. break;
  351. }
  352. default:
  353. break;
  354. }
  355. }
  356. static void map_slot_key(upb_fieldtype_t type, const void* from,
  357. const char** keyval,
  358. size_t* length) {
  359. if (type == UPB_TYPE_STRING) {
  360. zval* key_php = **(zval***)from;
  361. *keyval = Z_STRVAL_P(key_php);
  362. *length = Z_STRLEN_P(key_php);
  363. } else {
  364. *keyval = from;
  365. *length = native_slot_size(type);
  366. }
  367. }
  368. static void map_slot_value(upb_fieldtype_t type, const void* from,
  369. upb_value* v) {
  370. size_t len;
  371. void* to = upb_value_memory(v);
  372. #ifndef NDEBUG
  373. v->ctype = UPB_CTYPE_UINT64;
  374. #endif
  375. memset(to, 0, native_slot_size(type));
  376. switch (type) {
  377. case UPB_TYPE_STRING:
  378. case UPB_TYPE_BYTES:
  379. case UPB_TYPE_MESSAGE: {
  380. *(zval**)to = **(zval***)from;
  381. Z_ADDREF_PP((zval**)to);
  382. break;
  383. }
  384. default:
  385. len = native_slot_size(type);
  386. memcpy(to, from, len);
  387. }
  388. }
  389. // Handler to begin a map entry: allocates a temporary frame. This is the
  390. // 'startsubmsg' handler on the msgdef that contains the map field.
  391. static void *startmapentry_handler(void *closure, const void *hd) {
  392. MessageHeader* msg = closure;
  393. const map_handlerdata_t* mapdata = hd;
  394. zval* map = *DEREF(msg, mapdata->ofs, zval**);
  395. map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
  396. frame->map = map;
  397. map_slot_init(&frame->key_storage, mapdata->key_field_type);
  398. map_slot_init(&frame->value_storage, mapdata->value_field_type);
  399. return frame;
  400. }
  401. // Handler to end a map entry: inserts the value defined during the message into
  402. // the map. This is the 'endmsg' handler on the map entry msgdef.
  403. static bool endmap_handler(void* closure, const void* hd, upb_status* s) {
  404. map_parse_frame_t* frame = closure;
  405. const map_handlerdata_t* mapdata = hd;
  406. TSRMLS_FETCH();
  407. Map *map = (Map *)zend_object_store_get_object(frame->map TSRMLS_CC);
  408. const char* keyval = NULL;
  409. upb_value v;
  410. size_t length;
  411. map_slot_key(map->key_type, &frame->key_storage, &keyval, &length);
  412. map_slot_value(map->value_type, &frame->value_storage, &v);
  413. map_index_set(map, keyval, length, v);
  414. map_slot_uninit(&frame->key_storage, mapdata->key_field_type);
  415. map_slot_uninit(&frame->value_storage, mapdata->value_field_type);
  416. FREE(frame);
  417. return true;
  418. }
  419. // Allocates a new map_handlerdata_t given the map entry message definition. If
  420. // the offset of the field within the parent message is also given, that is
  421. // added to the handler data as well. Note that this is called *twice* per map
  422. // field: once in the parent message handler setup when setting the startsubmsg
  423. // handler and once in the map entry message handler setup when setting the
  424. // key/value and endmsg handlers. The reason is that there is no easy way to
  425. // pass the handlerdata down to the sub-message handler setup.
  426. static map_handlerdata_t* new_map_handlerdata(
  427. size_t ofs,
  428. const upb_msgdef* mapentry_def,
  429. Descriptor* desc) {
  430. const upb_fielddef* key_field;
  431. const upb_fielddef* value_field;
  432. // TODO(teboring): Use emalloc and efree.
  433. map_handlerdata_t* hd =
  434. (map_handlerdata_t*)malloc(sizeof(map_handlerdata_t));
  435. hd->ofs = ofs;
  436. key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
  437. assert(key_field != NULL);
  438. hd->key_field_type = upb_fielddef_type(key_field);
  439. value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
  440. assert(value_field != NULL);
  441. hd->value_field_type = upb_fielddef_type(value_field);
  442. hd->value_field_subdef = upb_fielddef_subdef(value_field);
  443. return hd;
  444. }
  445. // Handlers that set primitive values in oneofs.
  446. #define DEFINE_ONEOF_HANDLER(type, ctype) \
  447. static bool oneof##type##_handler(void *closure, const void *hd, \
  448. ctype val) { \
  449. const oneof_handlerdata_t *oneofdata = hd; \
  450. DEREF(closure, oneofdata->case_ofs, uint32_t) = \
  451. oneofdata->oneof_case_num; \
  452. DEREF(closure, oneofdata->ofs, ctype) = val; \
  453. return true; \
  454. }
  455. DEFINE_ONEOF_HANDLER(bool, bool)
  456. DEFINE_ONEOF_HANDLER(int32, int32_t)
  457. DEFINE_ONEOF_HANDLER(uint32, uint32_t)
  458. DEFINE_ONEOF_HANDLER(float, float)
  459. DEFINE_ONEOF_HANDLER(int64, int64_t)
  460. DEFINE_ONEOF_HANDLER(uint64, uint64_t)
  461. DEFINE_ONEOF_HANDLER(double, double)
  462. #undef DEFINE_ONEOF_HANDLER
  463. // Handlers for strings in a oneof.
  464. static void *oneofstr_handler(void *closure,
  465. const void *hd,
  466. size_t size_hint) {
  467. MessageHeader* msg = closure;
  468. const oneof_handlerdata_t *oneofdata = hd;
  469. DEREF(msg, oneofdata->case_ofs, uint32_t) =
  470. oneofdata->oneof_case_num;
  471. DEREF(msg, oneofdata->ofs, zval**) =
  472. &(msg->std.properties_table)[oneofdata->property_ofs];
  473. return empty_php_string(DEREF(msg, oneofdata->ofs, zval**));
  474. }
  475. static void *oneofbytes_handler(void *closure,
  476. const void *hd,
  477. size_t size_hint) {
  478. MessageHeader* msg = closure;
  479. const oneof_handlerdata_t *oneofdata = hd;
  480. DEREF(msg, oneofdata->case_ofs, uint32_t) =
  481. oneofdata->oneof_case_num;
  482. DEREF(msg, oneofdata->ofs, zval**) =
  483. &(msg->std.properties_table)[oneofdata->property_ofs];
  484. // TODO(teboring): Add it back.
  485. // rb_enc_associate(str, kRubyString8bitEncoding);
  486. SEPARATE_ZVAL_IF_NOT_REF(DEREF(msg, oneofdata->ofs, zval**));
  487. zval* str = *DEREF(msg, oneofdata->ofs, zval**);
  488. zval_dtor(str);
  489. ZVAL_STRINGL(str, "", 0, 1);
  490. return (void*)str;
  491. }
  492. // Handler for a submessage field in a oneof.
  493. static void* oneofsubmsg_handler(void* closure, const void* hd) {
  494. MessageHeader* msg = closure;
  495. const oneof_handlerdata_t *oneofdata = hd;
  496. uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
  497. zval* subdesc_php = get_def_obj((void*)oneofdata->md);
  498. TSRMLS_FETCH();
  499. Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
  500. zend_class_entry* subklass = subdesc->klass;
  501. zval* submsg_php;
  502. MessageHeader* submsg;
  503. if (oldcase != oneofdata->oneof_case_num) {
  504. DEREF(msg, oneofdata->ofs, zval**) =
  505. &(msg->std.properties_table)[oneofdata->property_ofs];
  506. }
  507. if (Z_TYPE_P(*DEREF(msg, oneofdata->ofs, zval**)) == IS_NULL) {
  508. zval* val = NULL;
  509. MAKE_STD_ZVAL(val);
  510. Z_TYPE_P(val) = IS_OBJECT;
  511. Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
  512. zval_ptr_dtor(DEREF(msg, oneofdata->ofs, zval**));
  513. *DEREF(msg, oneofdata->ofs, zval**) = val;
  514. }
  515. DEREF(msg, oneofdata->case_ofs, uint32_t) =
  516. oneofdata->oneof_case_num;
  517. submsg_php = *DEREF(msg, oneofdata->ofs, zval**);
  518. submsg = zend_object_store_get_object(submsg_php TSRMLS_CC);
  519. return submsg;
  520. }
  521. // Set up handlers for a repeated field.
  522. static void add_handlers_for_repeated_field(upb_handlers *h,
  523. const upb_fielddef *f,
  524. size_t offset) {
  525. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  526. upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
  527. upb_handlers_setstartseq(h, f, startseq_handler, &attr);
  528. upb_handlerattr_uninit(&attr);
  529. switch (upb_fielddef_type(f)) {
  530. #define SET_HANDLER(utype, ltype) \
  531. case utype: \
  532. upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
  533. break;
  534. SET_HANDLER(UPB_TYPE_BOOL, bool);
  535. SET_HANDLER(UPB_TYPE_INT32, int32);
  536. SET_HANDLER(UPB_TYPE_UINT32, uint32);
  537. SET_HANDLER(UPB_TYPE_ENUM, int32);
  538. SET_HANDLER(UPB_TYPE_FLOAT, float);
  539. SET_HANDLER(UPB_TYPE_INT64, int64);
  540. SET_HANDLER(UPB_TYPE_UINT64, uint64);
  541. SET_HANDLER(UPB_TYPE_DOUBLE, double);
  542. #undef SET_HANDLER
  543. case UPB_TYPE_STRING:
  544. case UPB_TYPE_BYTES: {
  545. bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
  546. upb_handlers_setstartstr(h, f, is_bytes ?
  547. appendbytes_handler : appendstr_handler,
  548. NULL);
  549. upb_handlers_setstring(h, f, stringdata_handler, NULL);
  550. break;
  551. }
  552. case UPB_TYPE_MESSAGE: {
  553. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  554. upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
  555. upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
  556. upb_handlerattr_uninit(&attr);
  557. break;
  558. }
  559. }
  560. }
  561. // Set up handlers for a singular field.
  562. static void add_handlers_for_singular_field(upb_handlers *h,
  563. const upb_fielddef *f,
  564. size_t offset) {
  565. switch (upb_fielddef_type(f)) {
  566. case UPB_TYPE_BOOL:
  567. case UPB_TYPE_INT32:
  568. case UPB_TYPE_UINT32:
  569. case UPB_TYPE_ENUM:
  570. case UPB_TYPE_FLOAT:
  571. case UPB_TYPE_INT64:
  572. case UPB_TYPE_UINT64:
  573. case UPB_TYPE_DOUBLE:
  574. upb_shim_set(h, f, offset, -1);
  575. break;
  576. case UPB_TYPE_STRING:
  577. case UPB_TYPE_BYTES: {
  578. bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
  579. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  580. upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
  581. upb_handlers_setstartstr(h, f,
  582. is_bytes ? bytes_handler : str_handler,
  583. &attr);
  584. upb_handlers_setstring(h, f, stringdata_handler, &attr);
  585. upb_handlerattr_uninit(&attr);
  586. break;
  587. }
  588. case UPB_TYPE_MESSAGE: {
  589. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  590. upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
  591. upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
  592. upb_handlerattr_uninit(&attr);
  593. break;
  594. }
  595. }
  596. }
  597. // Adds handlers to a map field.
  598. static void add_handlers_for_mapfield(upb_handlers* h,
  599. const upb_fielddef* fielddef,
  600. size_t offset,
  601. Descriptor* desc) {
  602. const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
  603. map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
  604. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  605. upb_handlers_addcleanup(h, hd, free);
  606. upb_handlerattr_sethandlerdata(&attr, hd);
  607. upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
  608. upb_handlerattr_uninit(&attr);
  609. }
  610. // Adds handlers to a map-entry msgdef.
  611. static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h,
  612. Descriptor* desc) {
  613. const upb_fielddef* key_field = map_entry_key(msgdef);
  614. const upb_fielddef* value_field = map_entry_value(msgdef);
  615. map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
  616. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  617. upb_handlers_addcleanup(h, hd, free);
  618. upb_handlerattr_sethandlerdata(&attr, hd);
  619. upb_handlers_setendmsg(h, endmap_handler, &attr);
  620. add_handlers_for_singular_field(h, key_field,
  621. offsetof(map_parse_frame_t, key_storage));
  622. add_handlers_for_singular_field(h, value_field,
  623. offsetof(map_parse_frame_t, value_storage));
  624. }
  625. // Set up handlers for a oneof field.
  626. static void add_handlers_for_oneof_field(upb_handlers *h,
  627. const upb_fielddef *f,
  628. size_t offset,
  629. size_t oneof_case_offset,
  630. int property_cache_offset) {
  631. upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  632. upb_handlerattr_sethandlerdata(
  633. &attr, newoneofhandlerdata(h, offset, oneof_case_offset,
  634. property_cache_offset, f));
  635. switch (upb_fielddef_type(f)) {
  636. #define SET_HANDLER(utype, ltype) \
  637. case utype: \
  638. upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
  639. break;
  640. SET_HANDLER(UPB_TYPE_BOOL, bool);
  641. SET_HANDLER(UPB_TYPE_INT32, int32);
  642. SET_HANDLER(UPB_TYPE_UINT32, uint32);
  643. SET_HANDLER(UPB_TYPE_ENUM, int32);
  644. SET_HANDLER(UPB_TYPE_FLOAT, float);
  645. SET_HANDLER(UPB_TYPE_INT64, int64);
  646. SET_HANDLER(UPB_TYPE_UINT64, uint64);
  647. SET_HANDLER(UPB_TYPE_DOUBLE, double);
  648. #undef SET_HANDLER
  649. case UPB_TYPE_STRING:
  650. case UPB_TYPE_BYTES: {
  651. bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
  652. upb_handlers_setstartstr(h, f, is_bytes ?
  653. oneofbytes_handler : oneofstr_handler,
  654. &attr);
  655. upb_handlers_setstring(h, f, stringdata_handler, NULL);
  656. break;
  657. }
  658. case UPB_TYPE_MESSAGE: {
  659. upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
  660. break;
  661. }
  662. }
  663. upb_handlerattr_uninit(&attr);
  664. }
  665. static void add_handlers_for_message(const void* closure,
  666. upb_handlers* h) {
  667. const upb_msgdef* msgdef = upb_handlers_msgdef(h);
  668. TSRMLS_FETCH();
  669. Descriptor* desc = (Descriptor*)zend_object_store_get_object(
  670. get_def_obj((void*)msgdef) TSRMLS_CC);
  671. upb_msg_field_iter i;
  672. // If this is a mapentry message type, set up a special set of handlers and
  673. // bail out of the normal (user-defined) message type handling.
  674. if (upb_msgdef_mapentry(msgdef)) {
  675. add_handlers_for_mapentry(msgdef, h, desc);
  676. return;
  677. }
  678. // Ensure layout exists. We may be invoked to create handlers for a given
  679. // message if we are included as a submsg of another message type before our
  680. // class is actually built, so to work around this, we just create the layout
  681. // (and handlers, in the class-building function) on-demand.
  682. if (desc->layout == NULL) {
  683. desc->layout = create_layout(desc->msgdef);
  684. }
  685. for (upb_msg_field_begin(&i, desc->msgdef);
  686. !upb_msg_field_done(&i);
  687. upb_msg_field_next(&i)) {
  688. const upb_fielddef *f = upb_msg_iter_field(&i);
  689. size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
  690. sizeof(MessageHeader);
  691. if (upb_fielddef_containingoneof(f)) {
  692. size_t oneof_case_offset =
  693. desc->layout->fields[upb_fielddef_index(f)].case_offset +
  694. sizeof(MessageHeader);
  695. int property_cache_index =
  696. desc->layout->fields[upb_fielddef_index(f)].cache_index;
  697. add_handlers_for_oneof_field(h, f, offset, oneof_case_offset,
  698. property_cache_index);
  699. } else if (is_map_field(f)) {
  700. add_handlers_for_mapfield(h, f, offset, desc);
  701. } else if (upb_fielddef_isseq(f)) {
  702. add_handlers_for_repeated_field(h, f, offset);
  703. } else {
  704. add_handlers_for_singular_field(h, f, offset);
  705. }
  706. }
  707. }
  708. // Creates upb handlers for populating a message.
  709. static const upb_handlers *new_fill_handlers(Descriptor* desc,
  710. const void* owner) {
  711. // TODO(cfallin, haberman): once upb gets a caching/memoization layer for
  712. // handlers, reuse subdef handlers so that e.g. if we already parse
  713. // B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
  714. // parse A-with-field-of-type-B-with-field-of-type-C.
  715. return upb_handlers_newfrozen(desc->msgdef, owner,
  716. add_handlers_for_message, NULL);
  717. }
  718. // Constructs the handlers for filling a message's data into an in-memory
  719. // object.
  720. const upb_handlers* get_fill_handlers(Descriptor* desc) {
  721. if (!desc->fill_handlers) {
  722. desc->fill_handlers =
  723. new_fill_handlers(desc, &desc->fill_handlers);
  724. }
  725. return desc->fill_handlers;
  726. }
  727. const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
  728. const void* owner) {
  729. const upb_handlers* handlers = get_fill_handlers(desc);
  730. upb_pbdecodermethodopts opts;
  731. upb_pbdecodermethodopts_init(&opts, handlers);
  732. return upb_pbdecodermethod_new(&opts, owner);
  733. }
  734. static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
  735. if (desc->fill_method == NULL) {
  736. desc->fill_method = new_fillmsg_decodermethod(
  737. desc, &desc->fill_method);
  738. }
  739. return desc->fill_method;
  740. }
  741. // -----------------------------------------------------------------------------
  742. // Serializing.
  743. // -----------------------------------------------------------------------------
  744. static void putmsg(zval* msg, const Descriptor* desc, upb_sink* sink,
  745. int depth TSRMLS_DC);
  746. static void putstr(zval* str, const upb_fielddef* f, upb_sink* sink);
  747. static void putrawstr(const char* str, int len, const upb_fielddef* f,
  748. upb_sink* sink);
  749. static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink,
  750. int depth TSRMLS_DC);
  751. static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
  752. int depth TSRMLS_DC);
  753. static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int depth
  754. TSRMLS_DC);
  755. static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) {
  756. upb_selector_t ret;
  757. bool ok = upb_handlers_getselector(f, type, &ret);
  758. UPB_ASSERT(ok);
  759. return ret;
  760. }
  761. static void put_optional_value(const void* memory, int len, const upb_fielddef* f,
  762. int depth, upb_sink* sink TSRMLS_DC) {
  763. assert(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL);
  764. switch (upb_fielddef_type(f)) {
  765. #define T(upbtypeconst, upbtype, ctype, default_value) \
  766. case upbtypeconst: { \
  767. ctype value = DEREF(memory, 0, ctype); \
  768. if (value != default_value) { \
  769. upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); \
  770. upb_sink_put##upbtype(sink, sel, value); \
  771. } \
  772. } break;
  773. T(UPB_TYPE_FLOAT, float, float, 0.0)
  774. T(UPB_TYPE_DOUBLE, double, double, 0.0)
  775. T(UPB_TYPE_BOOL, bool, uint8_t, 0)
  776. T(UPB_TYPE_ENUM, int32, int32_t, 0)
  777. T(UPB_TYPE_INT32, int32, int32_t, 0)
  778. T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
  779. T(UPB_TYPE_INT64, int64, int64_t, 0)
  780. T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
  781. #undef T
  782. case UPB_TYPE_STRING:
  783. case UPB_TYPE_BYTES:
  784. putrawstr(memory, len, f, sink);
  785. break;
  786. case UPB_TYPE_MESSAGE: {
  787. zval* submsg = *(zval**)memory;
  788. putsubmsg(submsg, f, sink, depth TSRMLS_CC);
  789. break;
  790. }
  791. default:
  792. assert(false);
  793. }
  794. }
  795. // Only string/bytes fields are stored as zval.
  796. static const char* raw_value(void* memory, const upb_fielddef* f) {
  797. switch (upb_fielddef_type(f)) {
  798. case UPB_TYPE_STRING:
  799. case UPB_TYPE_BYTES:
  800. return Z_STRVAL_PP((zval**)memory);
  801. break;
  802. default:
  803. return memory;
  804. }
  805. }
  806. static int raw_value_len(void* memory, int len, const upb_fielddef* f) {
  807. switch (upb_fielddef_type(f)) {
  808. case UPB_TYPE_STRING:
  809. case UPB_TYPE_BYTES:
  810. return Z_STRLEN_PP((zval**)memory);
  811. break;
  812. default:
  813. return len;
  814. }
  815. }
  816. static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink,
  817. int depth TSRMLS_DC) {
  818. Map* self;
  819. upb_sink subsink;
  820. const upb_fielddef* key_field;
  821. const upb_fielddef* value_field;
  822. MapIter it;
  823. int len;
  824. if (map == NULL) return;
  825. self = UNBOX(Map, map);
  826. upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
  827. assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
  828. key_field = map_field_key(f);
  829. value_field = map_field_value(f);
  830. for (map_begin(map, &it TSRMLS_CC); !map_done(&it); map_next(&it)) {
  831. upb_status status;
  832. upb_sink entry_sink;
  833. upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
  834. &entry_sink);
  835. upb_sink_startmsg(&entry_sink);
  836. // Serialize key.
  837. const char *key = map_iter_key(&it, &len);
  838. put_optional_value(key, len, key_field, depth + 1, &entry_sink TSRMLS_CC);
  839. // Serialize value.
  840. upb_value value = map_iter_value(&it, &len);
  841. put_optional_value(raw_value(upb_value_memory(&value), value_field),
  842. raw_value_len(upb_value_memory(&value), len, value_field),
  843. value_field, depth + 1, &entry_sink TSRMLS_CC);
  844. upb_sink_endmsg(&entry_sink, &status);
  845. upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
  846. }
  847. upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
  848. }
  849. static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink,
  850. int depth TSRMLS_DC) {
  851. upb_msg_field_iter i;
  852. upb_status status;
  853. upb_sink_startmsg(sink);
  854. // Protect against cycles (possible because users may freely reassign message
  855. // and repeated fields) by imposing a maximum recursion depth.
  856. if (depth > ENCODE_MAX_NESTING) {
  857. zend_error(E_ERROR,
  858. "Maximum recursion depth exceeded during encoding.");
  859. }
  860. MessageHeader* msg = zend_object_store_get_object(msg_php TSRMLS_CC);
  861. for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i);
  862. upb_msg_field_next(&i)) {
  863. upb_fielddef* f = upb_msg_iter_field(&i);
  864. uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
  865. sizeof(MessageHeader);
  866. if (upb_fielddef_containingoneof(f)) {
  867. uint32_t oneof_case_offset =
  868. desc->layout->fields[upb_fielddef_index(f)].case_offset +
  869. sizeof(MessageHeader);
  870. // For a oneof, check that this field is actually present -- skip all the
  871. // below if not.
  872. if (DEREF(msg, oneof_case_offset, uint32_t) != upb_fielddef_number(f)) {
  873. continue;
  874. }
  875. // Otherwise, fall through to the appropriate singular-field handler
  876. // below.
  877. }
  878. if (is_map_field(f)) {
  879. zval* map = *DEREF(msg, offset, zval**);
  880. if (map != NULL) {
  881. putmap(map, f, sink, depth TSRMLS_CC);
  882. }
  883. } else if (upb_fielddef_isseq(f)) {
  884. zval* array = *DEREF(msg, offset, zval**);
  885. if (array != NULL) {
  886. putarray(array, f, sink, depth TSRMLS_CC);
  887. }
  888. } else if (upb_fielddef_isstring(f)) {
  889. zval* str = *DEREF(msg, offset, zval**);
  890. if (Z_STRLEN_P(str) > 0) {
  891. putstr(str, f, sink);
  892. }
  893. } else if (upb_fielddef_issubmsg(f)) {
  894. putsubmsg(*DEREF(msg, offset, zval**), f, sink, depth TSRMLS_CC);
  895. } else {
  896. upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
  897. #define T(upbtypeconst, upbtype, ctype, default_value) \
  898. case upbtypeconst: { \
  899. ctype value = DEREF(msg, offset, ctype); \
  900. if (value != default_value) { \
  901. upb_sink_put##upbtype(sink, sel, value); \
  902. } \
  903. } break;
  904. switch (upb_fielddef_type(f)) {
  905. T(UPB_TYPE_FLOAT, float, float, 0.0)
  906. T(UPB_TYPE_DOUBLE, double, double, 0.0)
  907. T(UPB_TYPE_BOOL, bool, uint8_t, 0)
  908. case UPB_TYPE_ENUM:
  909. T(UPB_TYPE_INT32, int32, int32_t, 0)
  910. T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
  911. T(UPB_TYPE_INT64, int64, int64_t, 0)
  912. T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
  913. case UPB_TYPE_STRING:
  914. case UPB_TYPE_BYTES:
  915. case UPB_TYPE_MESSAGE:
  916. zend_error(E_ERROR, "Internal error.");
  917. }
  918. #undef T
  919. }
  920. }
  921. upb_sink_endmsg(sink, &status);
  922. }
  923. static void putstr(zval* str, const upb_fielddef *f, upb_sink *sink) {
  924. upb_sink subsink;
  925. if (ZVAL_IS_NULL(str)) return;
  926. assert(Z_TYPE_P(str) == IS_STRING);
  927. // Ensure that the string has the correct encoding. We also check at field-set
  928. // time, but the user may have mutated the string object since then.
  929. if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
  930. !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) {
  931. zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
  932. return;
  933. }
  934. upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), Z_STRLEN_P(str),
  935. &subsink);
  936. upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str),
  937. Z_STRLEN_P(str), NULL);
  938. upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
  939. }
  940. static void putrawstr(const char* str, int len, const upb_fielddef* f,
  941. upb_sink* sink) {
  942. upb_sink subsink;
  943. if (len == 0) return;
  944. // Ensure that the string has the correct encoding. We also check at field-set
  945. // time, but the user may have mutated the string object since then.
  946. if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
  947. !is_structurally_valid_utf8(str, len)) {
  948. zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
  949. return;
  950. }
  951. upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), len, &subsink);
  952. upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), str, len, NULL);
  953. upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
  954. }
  955. static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink,
  956. int depth TSRMLS_DC) {
  957. upb_sink subsink;
  958. if (Z_TYPE_P(submsg) == IS_NULL) return;
  959. zval* php_descriptor = get_def_obj(upb_fielddef_msgsubdef(f));
  960. Descriptor* subdesc =
  961. (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
  962. upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
  963. putmsg(submsg, subdesc, &subsink, depth + 1 TSRMLS_CC);
  964. upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
  965. }
  966. static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
  967. int depth TSRMLS_DC) {
  968. upb_sink subsink;
  969. upb_fieldtype_t type = upb_fielddef_type(f);
  970. upb_selector_t sel = 0;
  971. int size, i;
  972. assert(array != NULL);
  973. RepeatedField* intern =
  974. (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
  975. size = zend_hash_num_elements(HASH_OF(intern->array));
  976. if (size == 0) return;
  977. upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
  978. if (upb_fielddef_isprimitive(f)) {
  979. sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
  980. }
  981. for (i = 0; i < size; i++) {
  982. void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
  983. switch (type) {
  984. #define T(upbtypeconst, upbtype, ctype) \
  985. case upbtypeconst: \
  986. upb_sink_put##upbtype(&subsink, sel, *((ctype*)memory)); \
  987. break;
  988. T(UPB_TYPE_FLOAT, float, float)
  989. T(UPB_TYPE_DOUBLE, double, double)
  990. T(UPB_TYPE_BOOL, bool, int8_t)
  991. case UPB_TYPE_ENUM:
  992. T(UPB_TYPE_INT32, int32, int32_t)
  993. T(UPB_TYPE_UINT32, uint32, uint32_t)
  994. T(UPB_TYPE_INT64, int64, int64_t)
  995. T(UPB_TYPE_UINT64, uint64, uint64_t)
  996. case UPB_TYPE_STRING:
  997. case UPB_TYPE_BYTES:
  998. putstr(*((zval**)memory), f, &subsink);
  999. break;
  1000. case UPB_TYPE_MESSAGE:
  1001. putsubmsg(*((zval**)memory), f, &subsink, depth TSRMLS_CC);
  1002. break;
  1003. #undef T
  1004. }
  1005. }
  1006. upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
  1007. }
  1008. static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
  1009. if (desc->pb_serialize_handlers == NULL) {
  1010. desc->pb_serialize_handlers =
  1011. upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
  1012. }
  1013. return desc->pb_serialize_handlers;
  1014. }
  1015. // -----------------------------------------------------------------------------
  1016. // PHP encode/decode methods
  1017. // -----------------------------------------------------------------------------
  1018. PHP_METHOD(Message, encode) {
  1019. zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis()));
  1020. Descriptor* desc =
  1021. (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
  1022. stringsink sink;
  1023. stringsink_init(&sink);
  1024. {
  1025. const upb_handlers* serialize_handlers = msgdef_pb_serialize_handlers(desc);
  1026. stackenv se;
  1027. upb_pb_encoder* encoder;
  1028. stackenv_init(&se, "Error occurred during encoding: %s");
  1029. encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
  1030. putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC);
  1031. RETVAL_STRINGL(sink.ptr, sink.len, 1);
  1032. stackenv_uninit(&se);
  1033. stringsink_uninit(&sink);
  1034. }
  1035. }
  1036. PHP_METHOD(Message, decode) {
  1037. zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis()));
  1038. Descriptor* desc =
  1039. (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
  1040. MessageHeader* msg = zend_object_store_get_object(getThis() TSRMLS_CC);
  1041. char *data = NULL;
  1042. int data_len;
  1043. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
  1044. FAILURE) {
  1045. return;
  1046. }
  1047. {
  1048. const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
  1049. const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
  1050. stackenv se;
  1051. upb_sink sink;
  1052. upb_pbdecoder* decoder;
  1053. stackenv_init(&se, "Error occurred during parsing: %s");
  1054. upb_sink_reset(&sink, h, msg);
  1055. decoder = upb_pbdecoder_create(&se.env, method, &sink);
  1056. upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder));
  1057. stackenv_uninit(&se);
  1058. }
  1059. }