Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: third_party/protobuf/php/ext/google/protobuf/encode_decode.c

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above 11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer 12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the 13 // in the documentation and/or other materials provided with the
14 // distribution. 14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its 15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from 16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission. 17 // this software without specific prior written permission.
18 // 18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 #include "protobuf.h" 31 #include "protobuf.h"
32 #include "utf8.h"
32 33
33 // This function is equivalent to rb_str_cat(), but unlike the real 34 /* stringsink *****************************************************************/
34 // rb_str_cat(), it doesn't leak memory in some versions of Ruby. 35
35 // For more information, see: 36 typedef struct {
36 // https://bugs.ruby-lang.org/issues/11328 37 upb_byteshandler handler;
37 VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) { 38 upb_bytessink sink;
38 char *p; 39 char *ptr;
39 size_t oldlen = RSTRING_LEN(rb_str); 40 size_t len, size;
40 rb_str_modify_expand(rb_str, len); 41 } stringsink;
41 p = RSTRING_PTR(rb_str); 42
42 memcpy(p + oldlen, str, len); 43
43 rb_str_set_len(rb_str, oldlen + len); 44 static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
44 return rb_str; 45 stringsink *sink = _sink;
46 sink->len = 0;
47 return sink;
48 }
49
50 static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
51 size_t len, const upb_bufhandle *handle) {
52 stringsink *sink = _sink;
53 size_t new_size = sink->size;
54
55 UPB_UNUSED(hd);
56 UPB_UNUSED(handle);
57
58 while (sink->len + len > new_size) {
59 new_size *= 2;
60 }
61
62 if (new_size != sink->size) {
63 sink->ptr = realloc(sink->ptr, new_size);
64 sink->size = new_size;
65 }
66
67 memcpy(sink->ptr + sink->len, ptr, len);
68 sink->len += len;
69
70 return len;
71 }
72
73 void stringsink_init(stringsink *sink) {
74 upb_byteshandler_init(&sink->handler);
75 upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
76 upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
77
78 upb_bytessink_reset(&sink->sink, &sink->handler, sink);
79
80 sink->size = 32;
81 sink->ptr = malloc(sink->size);
82 sink->len = 0;
83 }
84
85 void stringsink_uninit(stringsink *sink) { free(sink->ptr); }
86
87 /* stackenv *****************************************************************/
88
89 // Stack-allocated context during an encode/decode operation. Contains the upb
90 // environment and its stack-based allocator, an initial buffer for allocations
91 // to avoid malloc() when possible, and a template for PHP exception messages
92 // if any error occurs.
93 #define STACK_ENV_STACKBYTES 4096
94 typedef struct {
95 upb_env env;
96 const char *php_error_template;
97 char allocbuf[STACK_ENV_STACKBYTES];
98 } stackenv;
99
100
101 static void stackenv_init(stackenv* se, const char* errmsg);
102 static void stackenv_uninit(stackenv* se);
103
104 // Callback invoked by upb if any error occurs during parsing or serialization.
105 static bool env_error_func(void* ud, const upb_status* status) {
106 stackenv* se = ud;
107 // Free the env -- zend_error will longjmp up the stack past the
108 // encode/decode function so it would not otherwise have been freed.
109 stackenv_uninit(se);
110
111 // TODO(teboring): have a way to verify that this is actually a parse error,
112 // instead of just throwing "parse error" unconditionally.
113 zend_error(E_ERROR, se->php_error_template, upb_status_errmsg(status));
114 // Never reached.
115 return false;
116 }
117
118 static void stackenv_init(stackenv* se, const char* errmsg) {
119 se->php_error_template = errmsg;
120 upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
121 upb_env_seterrorfunc(&se->env, env_error_func, se);
122 }
123
124 static void stackenv_uninit(stackenv* se) {
125 upb_env_uninit(&se->env);
45 } 126 }
46 127
47 // ----------------------------------------------------------------------------- 128 // -----------------------------------------------------------------------------
48 // Parsing. 129 // Parsing.
49 // ----------------------------------------------------------------------------- 130 // -----------------------------------------------------------------------------
50 131
51 #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs) 132 #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
52 133
53 // Creates a handlerdata that simply contains the offset for this field. 134 // Creates a handlerdata that simply contains the offset for this field.
54 static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) { 135 static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
55 size_t* hd_ofs = ALLOC(size_t); 136 size_t* hd_ofs = (size_t*)malloc(sizeof(size_t));
56 *hd_ofs = ofs; 137 *hd_ofs = ofs;
57 upb_handlers_addcleanup(h, hd_ofs, free); 138 upb_handlers_addcleanup(h, hd_ofs, free);
58 return hd_ofs; 139 return hd_ofs;
59 } 140 }
60 141
61 typedef struct { 142 typedef struct {
62 size_t ofs; 143 size_t ofs;
63 const upb_msgdef *md; 144 const upb_msgdef *md;
64 } submsg_handlerdata_t; 145 } submsg_handlerdata_t;
65 146
66 // Creates a handlerdata that contains offset and submessage type information. 147 // Creates a handlerdata that contains offset and submessage type information.
67 static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs, 148 static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
68 const upb_fielddef* f) { 149 const upb_fielddef* f) {
69 submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t); 150 submsg_handlerdata_t* hd =
151 (submsg_handlerdata_t*)malloc(sizeof(submsg_handlerdata_t));
70 hd->ofs = ofs; 152 hd->ofs = ofs;
71 hd->md = upb_fielddef_msgsubdef(f); 153 hd->md = upb_fielddef_msgsubdef(f);
72 upb_handlers_addcleanup(h, hd, free); 154 upb_handlers_addcleanup(h, hd, free);
73 return hd; 155 return hd;
74 } 156 }
75 157
76 typedef struct { 158 typedef struct {
77 size_t ofs; // union data slot 159 size_t ofs; // union data slot
78 size_t case_ofs; // oneof_case field 160 size_t case_ofs; // oneof_case field
161 int property_ofs; // properties table cache
79 uint32_t oneof_case_num; // oneof-case number to place in oneof_case field 162 uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
80 const upb_msgdef *md; // msgdef, for oneof submessage handler 163 const upb_msgdef *md; // msgdef, for oneof submessage handler
81 } oneof_handlerdata_t; 164 } oneof_handlerdata_t;
82 165
83 static const void *newoneofhandlerdata(upb_handlers *h, 166 static const void *newoneofhandlerdata(upb_handlers *h,
84 uint32_t ofs, 167 uint32_t ofs,
85 uint32_t case_ofs, 168 uint32_t case_ofs,
169 int property_ofs,
86 const upb_fielddef *f) { 170 const upb_fielddef *f) {
87 oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t); 171 oneof_handlerdata_t* hd =
172 (oneof_handlerdata_t*)malloc(sizeof(oneof_handlerdata_t));
88 hd->ofs = ofs; 173 hd->ofs = ofs;
89 hd->case_ofs = case_ofs; 174 hd->case_ofs = case_ofs;
175 hd->property_ofs = property_ofs;
90 // We reuse the field tag number as a oneof union discriminant tag. Note that 176 // We reuse the field tag number as a oneof union discriminant tag. Note that
91 // we don't expose these numbers to the user, so the only requirement is that 177 // we don't expose these numbers to the user, so the only requirement is that
92 // we have some unique ID for each union case/possibility. The field tag 178 // we have some unique ID for each union case/possibility. The field tag
93 // numbers are already present and are easy to use so there's no reason to 179 // numbers are already present and are easy to use so there's no reason to
94 // create a separate ID space. In addition, using the field tag number here 180 // create a separate ID space. In addition, using the field tag number here
95 // lets us easily look up the field in the oneof accessor. 181 // lets us easily look up the field in the oneof accessor.
96 hd->oneof_case_num = upb_fielddef_number(f); 182 hd->oneof_case_num = upb_fielddef_number(f);
97 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) { 183 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
98 hd->md = upb_fielddef_msgsubdef(f); 184 hd->md = upb_fielddef_msgsubdef(f);
99 } else { 185 } else {
100 hd->md = NULL; 186 hd->md = NULL;
101 } 187 }
102 upb_handlers_addcleanup(h, hd, free); 188 upb_handlers_addcleanup(h, hd, free);
103 return hd; 189 return hd;
104 } 190 }
105 191
106 // A handler that starts a repeated field. Gets the Repeated*Field instance for 192 // A handler that starts a repeated field. Gets the Repeated*Field instance for
107 // this field (such an instance always exists even in an empty message). 193 // this field (such an instance always exists even in an empty message).
108 static void *startseq_handler(void* closure, const void* hd) { 194 static void *startseq_handler(void* closure, const void* hd) {
109 MessageHeader* msg = closure; 195 MessageHeader* msg = closure;
110 const size_t *ofs = hd; 196 const size_t *ofs = hd;
111 return (void*)DEREF(msg, *ofs, VALUE); 197 return (void*)(*DEREF(msg, *ofs, zval**));
112 } 198 }
113 199
114 // Handlers that append primitive values to a repeated field. 200 // Handlers that append primitive values to a repeated field.
115 #define DEFINE_APPEND_HANDLER(type, ctype) \ 201 #define DEFINE_APPEND_HANDLER(type, ctype) \
116 static bool append##type##_handler(void *closure, const void *hd, \ 202 static bool append##type##_handler(void* closure, const void* hd, \
117 ctype val) { \ 203 ctype val) { \
118 VALUE ary = (VALUE)closure; \ 204 zval* array = (zval*)closure; \
119 RepeatedField_push_native(ary, &val); \ 205 TSRMLS_FETCH(); \
120 return true; \ 206 RepeatedField* intern = \
207 (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); \
208 repeated_field_push_native(intern, &val TSRMLS_CC); \
209 return true; \
121 } 210 }
122 211
123 DEFINE_APPEND_HANDLER(bool, bool) 212 DEFINE_APPEND_HANDLER(bool, bool)
124 DEFINE_APPEND_HANDLER(int32, int32_t) 213 DEFINE_APPEND_HANDLER(int32, int32_t)
125 DEFINE_APPEND_HANDLER(uint32, uint32_t) 214 DEFINE_APPEND_HANDLER(uint32, uint32_t)
126 DEFINE_APPEND_HANDLER(float, float) 215 DEFINE_APPEND_HANDLER(float, float)
127 DEFINE_APPEND_HANDLER(int64, int64_t) 216 DEFINE_APPEND_HANDLER(int64, int64_t)
128 DEFINE_APPEND_HANDLER(uint64, uint64_t) 217 DEFINE_APPEND_HANDLER(uint64, uint64_t)
129 DEFINE_APPEND_HANDLER(double, double) 218 DEFINE_APPEND_HANDLER(double, double)
130 219
131 // Appends a string to a repeated field. 220 // Appends a string to a repeated field.
132 static void* appendstr_handler(void *closure, 221 static void* appendstr_handler(void *closure,
133 const void *hd, 222 const void *hd,
134 size_t size_hint) { 223 size_t size_hint) {
135 VALUE ary = (VALUE)closure; 224 zval* array = (zval*)closure;
136 VALUE str = rb_str_new2(""); 225 TSRMLS_FETCH();
137 rb_enc_associate(str, kRubyStringUtf8Encoding); 226 RepeatedField* intern =
138 RepeatedField_push(ary, str); 227 (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
228
229 zval* str;
230 MAKE_STD_ZVAL(str);
231 ZVAL_STRING(str, "", 1);
232
233 repeated_field_push_native(intern, &str TSRMLS_CC);
139 return (void*)str; 234 return (void*)str;
140 } 235 }
141 236
142 // Appends a 'bytes' string to a repeated field. 237 // Appends a 'bytes' string to a repeated field.
143 static void* appendbytes_handler(void *closure, 238 static void* appendbytes_handler(void *closure,
144 const void *hd, 239 const void *hd,
145 size_t size_hint) { 240 size_t size_hint) {
146 VALUE ary = (VALUE)closure; 241 zval* array = (zval*)closure;
147 VALUE str = rb_str_new2(""); 242 TSRMLS_FETCH();
148 rb_enc_associate(str, kRubyString8bitEncoding); 243 RepeatedField* intern =
149 RepeatedField_push(ary, str); 244 (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
245
246 zval* str;
247 MAKE_STD_ZVAL(str);
248 ZVAL_STRING(str, "", 1);
249
250 repeated_field_push_native(intern, &str TSRMLS_CC);
150 return (void*)str; 251 return (void*)str;
151 } 252 }
152 253
254 static void *empty_php_string(zval** value_ptr) {
255 SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
256 zval* str = *value_ptr;
257 zval_dtor(str);
258 ZVAL_STRINGL(str, "", 0, 1);
259 return (void*)str;
260 }
261
153 // Sets a non-repeated string field in a message. 262 // Sets a non-repeated string field in a message.
154 static void* str_handler(void *closure, 263 static void* str_handler(void *closure,
155 const void *hd, 264 const void *hd,
156 size_t size_hint) { 265 size_t size_hint) {
157 MessageHeader* msg = closure; 266 MessageHeader* msg = closure;
158 const size_t *ofs = hd; 267 const size_t *ofs = hd;
159 VALUE str = rb_str_new2(""); 268 return empty_php_string(DEREF(msg, *ofs, zval**));
160 rb_enc_associate(str, kRubyStringUtf8Encoding);
161 DEREF(msg, *ofs, VALUE) = str;
162 return (void*)str;
163 } 269 }
164 270
165 // Sets a non-repeated 'bytes' field in a message. 271 // Sets a non-repeated 'bytes' field in a message.
166 static void* bytes_handler(void *closure, 272 static void* bytes_handler(void *closure,
167 const void *hd, 273 const void *hd,
168 size_t size_hint) { 274 size_t size_hint) {
169 MessageHeader* msg = closure; 275 MessageHeader* msg = closure;
170 const size_t *ofs = hd; 276 const size_t *ofs = hd;
171 VALUE str = rb_str_new2(""); 277 return empty_php_string(DEREF(msg, *ofs, zval**));
172 rb_enc_associate(str, kRubyString8bitEncoding);
173 DEREF(msg, *ofs, VALUE) = str;
174 return (void*)str;
175 } 278 }
176 279
177 static size_t stringdata_handler(void* closure, const void* hd, 280 static size_t stringdata_handler(void* closure, const void* hd,
178 const char* str, size_t len, 281 const char* str, size_t len,
179 const upb_bufhandle* handle) { 282 const upb_bufhandle* handle) {
180 VALUE rb_str = (VALUE)closure; 283 zval* php_str = (zval*)closure;
181 noleak_rb_str_cat(rb_str, str, len); 284
285 char* old_str = Z_STRVAL_P(php_str);
286 size_t old_len = Z_STRLEN_P(php_str);
287 assert(old_str != NULL);
288
289 char* new_str = emalloc(old_len + len + 1);
290
291 memcpy(new_str, old_str, old_len);
292 memcpy(new_str + old_len, str, len);
293 new_str[old_len + len] = 0;
294 FREE(old_str);
295
296 Z_STRVAL_P(php_str) = new_str;
297 Z_STRLEN_P(php_str) = old_len + len;
298
182 return len; 299 return len;
183 } 300 }
184 301
185 // Appends a submessage to a repeated field (a regular Ruby array for now). 302 // Appends a submessage to a repeated field.
186 static void *appendsubmsg_handler(void *closure, const void *hd) { 303 static void *appendsubmsg_handler(void *closure, const void *hd) {
187 VALUE ary = (VALUE)closure; 304 zval* array = (zval*)closure;
305 TSRMLS_FETCH();
306 RepeatedField* intern =
307 (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
308
188 const submsg_handlerdata_t *submsgdata = hd; 309 const submsg_handlerdata_t *submsgdata = hd;
189 VALUE subdesc = 310 zval* subdesc_php = get_def_obj((void*)submsgdata->md);
190 get_def_obj((void*)submsgdata->md); 311 Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
191 VALUE subklass = Descriptor_msgclass(subdesc); 312 zend_class_entry* subklass = subdesc->klass;
192 MessageHeader* submsg; 313 MessageHeader* submsg;
193 314
194 VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); 315 zval* val = NULL;
195 RepeatedField_push(ary, submsg_rb); 316 MAKE_STD_ZVAL(val);
317 Z_TYPE_P(val) = IS_OBJECT;
318 Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
196 319
197 TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); 320 repeated_field_push_native(intern, &val TSRMLS_CC);
321
322 submsg = zend_object_store_get_object(val TSRMLS_CC);
198 return submsg; 323 return submsg;
199 } 324 }
200 325
201 // Sets a non-repeated submessage field in a message. 326 // Sets a non-repeated submessage field in a message.
202 static void *submsg_handler(void *closure, const void *hd) { 327 static void *submsg_handler(void *closure, const void *hd) {
203 MessageHeader* msg = closure; 328 MessageHeader* msg = closure;
204 const submsg_handlerdata_t* submsgdata = hd; 329 const submsg_handlerdata_t* submsgdata = hd;
205 VALUE subdesc = 330 zval* subdesc_php = get_def_obj((void*)submsgdata->md);
206 get_def_obj((void*)submsgdata->md); 331 TSRMLS_FETCH();
207 VALUE subklass = Descriptor_msgclass(subdesc); 332 Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
208 VALUE submsg_rb; 333 zend_class_entry* subklass = subdesc->klass;
334 zval* submsg_php;
209 MessageHeader* submsg; 335 MessageHeader* submsg;
210 336
211 if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) { 337 if (Z_TYPE_P(*DEREF(msg, submsgdata->ofs, zval**)) == IS_NULL) {
212 DEREF(msg, submsgdata->ofs, VALUE) = 338 zval* val = NULL;
213 rb_class_new_instance(0, NULL, subklass); 339 MAKE_STD_ZVAL(val);
340 Z_TYPE_P(val) = IS_OBJECT;
341 Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
342
343 zval_ptr_dtor(DEREF(msg, submsgdata->ofs, zval**));
344 *DEREF(msg, submsgdata->ofs, zval**) = val;
214 } 345 }
215 346
216 submsg_rb = DEREF(msg, submsgdata->ofs, VALUE); 347 submsg_php = *DEREF(msg, submsgdata->ofs, zval**);
217 TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); 348
349 submsg = zend_object_store_get_object(submsg_php TSRMLS_CC);
218 return submsg; 350 return submsg;
219 } 351 }
220 352
221 // Handler data for startmap/endmap handlers. 353 // Handler data for startmap/endmap handlers.
222 typedef struct { 354 typedef struct {
223 size_t ofs; 355 size_t ofs;
224 upb_fieldtype_t key_field_type; 356 upb_fieldtype_t key_field_type;
225 upb_fieldtype_t value_field_type; 357 upb_fieldtype_t value_field_type;
226 358
227 // We know that we can hold this reference because the handlerdata has the 359 // We know that we can hold this reference because the handlerdata has the
228 // same lifetime as the upb_handlers struct, and the upb_handlers struct holds 360 // same lifetime as the upb_handlers struct, and the upb_handlers struct holds
229 // a reference to the upb_msgdef, which in turn has references to its subdefs. 361 // a reference to the upb_msgdef, which in turn has references to its subdefs.
230 const upb_def* value_field_subdef; 362 const upb_def* value_field_subdef;
231 } map_handlerdata_t; 363 } map_handlerdata_t;
232 364
233 // Temporary frame for map parsing: at the beginning of a map entry message, a 365 // Temporary frame for map parsing: at the beginning of a map entry message, a
234 // submsg handler allocates a frame to hold (i) a reference to the Map object 366 // submsg handler allocates a frame to hold (i) a reference to the Map object
235 // into which this message will be inserted and (ii) storage slots to 367 // into which this message will be inserted and (ii) storage slots to
236 // temporarily hold the key and value for this map entry until the end of the 368 // temporarily hold the key and value for this map entry until the end of the
237 // submessage. When the submessage ends, another handler is called to insert the 369 // submessage. When the submessage ends, another handler is called to insert the
238 // value into the map. 370 // value into the map.
239 typedef struct { 371 typedef struct {
240 VALUE map; 372 zval* map;
241 char key_storage[NATIVE_SLOT_MAX_SIZE]; 373 char key_storage[NATIVE_SLOT_MAX_SIZE];
242 char value_storage[NATIVE_SLOT_MAX_SIZE]; 374 char value_storage[NATIVE_SLOT_MAX_SIZE];
243 } map_parse_frame_t; 375 } map_parse_frame_t;
244 376
377 static void map_slot_init(void* memory, upb_fieldtype_t type) {
378 switch (type) {
379 case UPB_TYPE_STRING:
380 case UPB_TYPE_BYTES: {
381 // Store zval** in memory in order to be consistent with the layout of
382 // singular fields.
383 zval** holder = ALLOC(zval*);
384 zval* tmp;
385 MAKE_STD_ZVAL(tmp);
386 ZVAL_STRINGL(tmp, "", 0, 1);
387 *holder = tmp;
388 *(zval***)memory = holder;
389 break;
390 }
391 case UPB_TYPE_MESSAGE: {
392 zval** holder = ALLOC(zval*);
393 zval* tmp;
394 MAKE_STD_ZVAL(tmp);
395 ZVAL_NULL(tmp);
396 *holder = tmp;
397 *(zval***)memory = holder;
398 break;
399 }
400 default:
401 native_slot_init(type, memory, NULL);
402 }
403 }
404
405 static void map_slot_uninit(void* memory, upb_fieldtype_t type) {
406 switch (type) {
407 case UPB_TYPE_MESSAGE:
408 case UPB_TYPE_STRING:
409 case UPB_TYPE_BYTES: {
410 zval** holder = *(zval***)memory;
411 zval_ptr_dtor(holder);
412 FREE(holder);
413 break;
414 }
415 default:
416 break;
417 }
418 }
419
420 static void map_slot_key(upb_fieldtype_t type, const void* from,
421 const char** keyval,
422 size_t* length) {
423 if (type == UPB_TYPE_STRING) {
424 zval* key_php = **(zval***)from;
425 *keyval = Z_STRVAL_P(key_php);
426 *length = Z_STRLEN_P(key_php);
427 } else {
428 *keyval = from;
429 *length = native_slot_size(type);
430 }
431 }
432
433 static void map_slot_value(upb_fieldtype_t type, const void* from,
434 upb_value* v) {
435 size_t len;
436 void* to = upb_value_memory(v);
437 #ifndef NDEBUG
438 v->ctype = UPB_CTYPE_UINT64;
439 #endif
440
441 memset(to, 0, native_slot_size(type));
442
443 switch (type) {
444 case UPB_TYPE_STRING:
445 case UPB_TYPE_BYTES:
446 case UPB_TYPE_MESSAGE: {
447 *(zval**)to = **(zval***)from;
448 Z_ADDREF_PP((zval**)to);
449 break;
450 }
451 default:
452 len = native_slot_size(type);
453 memcpy(to, from, len);
454 }
455 }
456
245 // Handler to begin a map entry: allocates a temporary frame. This is the 457 // Handler to begin a map entry: allocates a temporary frame. This is the
246 // 'startsubmsg' handler on the msgdef that contains the map field. 458 // 'startsubmsg' handler on the msgdef that contains the map field.
247 static void *startmapentry_handler(void *closure, const void *hd) { 459 static void *startmapentry_handler(void *closure, const void *hd) {
248 MessageHeader* msg = closure; 460 MessageHeader* msg = closure;
249 const map_handlerdata_t* mapdata = hd; 461 const map_handlerdata_t* mapdata = hd;
250 VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); 462 zval* map = *DEREF(msg, mapdata->ofs, zval**);
251 463
252 map_parse_frame_t* frame = ALLOC(map_parse_frame_t); 464 map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
253 frame->map = map_rb; 465 frame->map = map;
254 466
255 native_slot_init(mapdata->key_field_type, &frame->key_storage); 467 map_slot_init(&frame->key_storage, mapdata->key_field_type);
256 native_slot_init(mapdata->value_field_type, &frame->value_storage); 468 map_slot_init(&frame->value_storage, mapdata->value_field_type);
257 469
258 return frame; 470 return frame;
259 } 471 }
260 472
261 // Handler to end a map entry: inserts the value defined during the message into 473 // Handler to end a map entry: inserts the value defined during the message into
262 // the map. This is the 'endmsg' handler on the map entry msgdef. 474 // the map. This is the 'endmsg' handler on the map entry msgdef.
263 static bool endmap_handler(void *closure, const void *hd, upb_status* s) { 475 static bool endmap_handler(void* closure, const void* hd, upb_status* s) {
264 map_parse_frame_t* frame = closure; 476 map_parse_frame_t* frame = closure;
265 const map_handlerdata_t* mapdata = hd; 477 const map_handlerdata_t* mapdata = hd;
266 478
267 VALUE key = native_slot_get( 479 TSRMLS_FETCH();
268 mapdata->key_field_type, Qnil, 480 Map *map = (Map *)zend_object_store_get_object(frame->map TSRMLS_CC);
269 &frame->key_storage);
270 481
271 VALUE value_field_typeclass = Qnil; 482 const char* keyval = NULL;
272 VALUE value; 483 upb_value v;
484 size_t length;
273 485
274 if (mapdata->value_field_type == UPB_TYPE_MESSAGE || 486 map_slot_key(map->key_type, &frame->key_storage, &keyval, &length);
275 mapdata->value_field_type == UPB_TYPE_ENUM) { 487 map_slot_value(map->value_type, &frame->value_storage, &v);
276 value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
277 }
278 488
279 value = native_slot_get( 489 map_index_set(map, keyval, length, v);
280 mapdata->value_field_type, value_field_typeclass,
281 &frame->value_storage);
282 490
283 Map_index_set(frame->map, key, value); 491 map_slot_uninit(&frame->key_storage, mapdata->key_field_type);
284 free(frame); 492 map_slot_uninit(&frame->value_storage, mapdata->value_field_type);
493 FREE(frame);
285 494
286 return true; 495 return true;
287 } 496 }
288 497
289 // Allocates a new map_handlerdata_t given the map entry message definition. If 498 // Allocates a new map_handlerdata_t given the map entry message definition. If
290 // the offset of the field within the parent message is also given, that is 499 // the offset of the field within the parent message is also given, that is
291 // added to the handler data as well. Note that this is called *twice* per map 500 // added to the handler data as well. Note that this is called *twice* per map
292 // field: once in the parent message handler setup when setting the startsubmsg 501 // field: once in the parent message handler setup when setting the startsubmsg
293 // handler and once in the map entry message handler setup when setting the 502 // handler and once in the map entry message handler setup when setting the
294 // key/value and endmsg handlers. The reason is that there is no easy way to 503 // key/value and endmsg handlers. The reason is that there is no easy way to
295 // pass the handlerdata down to the sub-message handler setup. 504 // pass the handlerdata down to the sub-message handler setup.
296 static map_handlerdata_t* new_map_handlerdata( 505 static map_handlerdata_t* new_map_handlerdata(
297 size_t ofs, 506 size_t ofs,
298 const upb_msgdef* mapentry_def, 507 const upb_msgdef* mapentry_def,
299 Descriptor* desc) { 508 Descriptor* desc) {
300 const upb_fielddef* key_field; 509 const upb_fielddef* key_field;
301 const upb_fielddef* value_field; 510 const upb_fielddef* value_field;
302 map_handlerdata_t* hd = ALLOC(map_handlerdata_t); 511 // TODO(teboring): Use emalloc and efree.
512 map_handlerdata_t* hd =
513 (map_handlerdata_t*)malloc(sizeof(map_handlerdata_t));
514
303 hd->ofs = ofs; 515 hd->ofs = ofs;
304 key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD); 516 key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
305 assert(key_field != NULL); 517 assert(key_field != NULL);
306 hd->key_field_type = upb_fielddef_type(key_field); 518 hd->key_field_type = upb_fielddef_type(key_field);
307 value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD); 519 value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
308 assert(value_field != NULL); 520 assert(value_field != NULL);
309 hd->value_field_type = upb_fielddef_type(value_field); 521 hd->value_field_type = upb_fielddef_type(value_field);
310 hd->value_field_subdef = upb_fielddef_subdef(value_field); 522 hd->value_field_subdef = upb_fielddef_subdef(value_field);
311 523
312 return hd; 524 return hd;
(...skipping 19 matching lines...) Expand all
332 DEFINE_ONEOF_HANDLER(double, double) 544 DEFINE_ONEOF_HANDLER(double, double)
333 545
334 #undef DEFINE_ONEOF_HANDLER 546 #undef DEFINE_ONEOF_HANDLER
335 547
336 // Handlers for strings in a oneof. 548 // Handlers for strings in a oneof.
337 static void *oneofstr_handler(void *closure, 549 static void *oneofstr_handler(void *closure,
338 const void *hd, 550 const void *hd,
339 size_t size_hint) { 551 size_t size_hint) {
340 MessageHeader* msg = closure; 552 MessageHeader* msg = closure;
341 const oneof_handlerdata_t *oneofdata = hd; 553 const oneof_handlerdata_t *oneofdata = hd;
342 VALUE str = rb_str_new2(""); 554
343 rb_enc_associate(str, kRubyStringUtf8Encoding);
344 DEREF(msg, oneofdata->case_ofs, uint32_t) = 555 DEREF(msg, oneofdata->case_ofs, uint32_t) =
345 oneofdata->oneof_case_num; 556 oneofdata->oneof_case_num;
346 DEREF(msg, oneofdata->ofs, VALUE) = str; 557 DEREF(msg, oneofdata->ofs, zval**) =
347 return (void*)str; 558 &(msg->std.properties_table)[oneofdata->property_ofs];
559
560 return empty_php_string(DEREF(msg, oneofdata->ofs, zval**));
348 } 561 }
349 562
350 static void *oneofbytes_handler(void *closure, 563 static void *oneofbytes_handler(void *closure,
351 const void *hd, 564 const void *hd,
352 size_t size_hint) { 565 size_t size_hint) {
353 MessageHeader* msg = closure; 566 MessageHeader* msg = closure;
354 const oneof_handlerdata_t *oneofdata = hd; 567 const oneof_handlerdata_t *oneofdata = hd;
355 VALUE str = rb_str_new2(""); 568
356 rb_enc_associate(str, kRubyString8bitEncoding);
357 DEREF(msg, oneofdata->case_ofs, uint32_t) = 569 DEREF(msg, oneofdata->case_ofs, uint32_t) =
358 oneofdata->oneof_case_num; 570 oneofdata->oneof_case_num;
359 DEREF(msg, oneofdata->ofs, VALUE) = str; 571 DEREF(msg, oneofdata->ofs, zval**) =
572 &(msg->std.properties_table)[oneofdata->property_ofs];
573
574 // TODO(teboring): Add it back.
575 // rb_enc_associate(str, kRubyString8bitEncoding);
576
577 SEPARATE_ZVAL_IF_NOT_REF(DEREF(msg, oneofdata->ofs, zval**));
578 zval* str = *DEREF(msg, oneofdata->ofs, zval**);
579 zval_dtor(str);
580 ZVAL_STRINGL(str, "", 0, 1);
360 return (void*)str; 581 return (void*)str;
361 } 582 }
362 583
363 // Handler for a submessage field in a oneof. 584 // Handler for a submessage field in a oneof.
364 static void *oneofsubmsg_handler(void *closure, 585 static void* oneofsubmsg_handler(void* closure, const void* hd) {
365 const void *hd) {
366 MessageHeader* msg = closure; 586 MessageHeader* msg = closure;
367 const oneof_handlerdata_t *oneofdata = hd; 587 const oneof_handlerdata_t *oneofdata = hd;
368 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); 588 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t);
369 589 zval* subdesc_php = get_def_obj((void*)oneofdata->md);
370 VALUE subdesc = 590 TSRMLS_FETCH();
371 get_def_obj((void*)oneofdata->md); 591 Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC);
372 VALUE subklass = Descriptor_msgclass(subdesc); 592 zend_class_entry* subklass = subdesc->klass;
373 VALUE submsg_rb; 593 zval* submsg_php;
374 MessageHeader* submsg; 594 MessageHeader* submsg;
375 595
376 if (oldcase != oneofdata->oneof_case_num || 596 if (oldcase != oneofdata->oneof_case_num) {
377 DEREF(msg, oneofdata->ofs, VALUE) == Qnil) { 597 DEREF(msg, oneofdata->ofs, zval**) =
378 DEREF(msg, oneofdata->ofs, VALUE) = 598 &(msg->std.properties_table)[oneofdata->property_ofs];
379 rb_class_new_instance(0, NULL, subklass);
380 } 599 }
381 // Set the oneof case *after* allocating the new class instance -- otherwise, 600
382 // if the Ruby GC is invoked as part of a call into the VM, it might invoke 601 if (Z_TYPE_P(*DEREF(msg, oneofdata->ofs, zval**)) == IS_NULL) {
383 // our mark routines, and our mark routines might see the case value 602 zval* val = NULL;
384 // indicating a VALUE is present and expect a valid VALUE. See comment in 603 MAKE_STD_ZVAL(val);
385 // layout_set() for more detail: basically, the change to the value and the 604 Z_TYPE_P(val) = IS_OBJECT;
386 // case must be atomic w.r.t. the Ruby VM. 605 Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC);
606
607 zval_ptr_dtor(DEREF(msg, oneofdata->ofs, zval**));
608 *DEREF(msg, oneofdata->ofs, zval**) = val;
609 }
610
387 DEREF(msg, oneofdata->case_ofs, uint32_t) = 611 DEREF(msg, oneofdata->case_ofs, uint32_t) =
388 oneofdata->oneof_case_num; 612 oneofdata->oneof_case_num;
389 613
390 submsg_rb = DEREF(msg, oneofdata->ofs, VALUE); 614 submsg_php = *DEREF(msg, oneofdata->ofs, zval**);
391 TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); 615 submsg = zend_object_store_get_object(submsg_php TSRMLS_CC);
392 return submsg; 616 return submsg;
393 } 617 }
394 618
395 // Set up handlers for a repeated field. 619 // Set up handlers for a repeated field.
396 static void add_handlers_for_repeated_field(upb_handlers *h, 620 static void add_handlers_for_repeated_field(upb_handlers *h,
397 const upb_fielddef *f, 621 const upb_fielddef *f,
398 size_t offset) { 622 size_t offset) {
399 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; 623 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
400 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); 624 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
401 upb_handlers_setstartseq(h, f, startseq_handler, &attr); 625 upb_handlers_setstartseq(h, f, startseq_handler, &attr);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); 708 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
485 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; 709 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
486 710
487 upb_handlers_addcleanup(h, hd, free); 711 upb_handlers_addcleanup(h, hd, free);
488 upb_handlerattr_sethandlerdata(&attr, hd); 712 upb_handlerattr_sethandlerdata(&attr, hd);
489 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); 713 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
490 upb_handlerattr_uninit(&attr); 714 upb_handlerattr_uninit(&attr);
491 } 715 }
492 716
493 // Adds handlers to a map-entry msgdef. 717 // Adds handlers to a map-entry msgdef.
494 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, 718 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h,
495 upb_handlers* h,
496 Descriptor* desc) { 719 Descriptor* desc) {
497 const upb_fielddef* key_field = map_entry_key(msgdef); 720 const upb_fielddef* key_field = map_entry_key(msgdef);
498 const upb_fielddef* value_field = map_entry_value(msgdef); 721 const upb_fielddef* value_field = map_entry_value(msgdef);
499 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); 722 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
500 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; 723 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
501 724
502 upb_handlers_addcleanup(h, hd, free); 725 upb_handlers_addcleanup(h, hd, free);
503 upb_handlerattr_sethandlerdata(&attr, hd); 726 upb_handlerattr_sethandlerdata(&attr, hd);
504 upb_handlers_setendmsg(h, endmap_handler, &attr); 727 upb_handlers_setendmsg(h, endmap_handler, &attr);
505 728
506 add_handlers_for_singular_field( 729 add_handlers_for_singular_field(h, key_field,
507 h, key_field, 730 offsetof(map_parse_frame_t, key_storage));
508 offsetof(map_parse_frame_t, key_storage)); 731 add_handlers_for_singular_field(h, value_field,
509 add_handlers_for_singular_field( 732 offsetof(map_parse_frame_t, value_storage));
510 h, value_field,
511 offsetof(map_parse_frame_t, value_storage));
512 } 733 }
513 734
514 // Set up handlers for a oneof field. 735 // Set up handlers for a oneof field.
515 static void add_handlers_for_oneof_field(upb_handlers *h, 736 static void add_handlers_for_oneof_field(upb_handlers *h,
516 const upb_fielddef *f, 737 const upb_fielddef *f,
517 size_t offset, 738 size_t offset,
518 size_t oneof_case_offset) { 739 size_t oneof_case_offset,
740 int property_cache_offset) {
519 741
520 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; 742 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
521 upb_handlerattr_sethandlerdata( 743 upb_handlerattr_sethandlerdata(
522 &attr, newoneofhandlerdata(h, offset, oneof_case_offset, f)); 744 &attr, newoneofhandlerdata(h, offset, oneof_case_offset,
745 property_cache_offset, f));
523 746
524 switch (upb_fielddef_type(f)) { 747 switch (upb_fielddef_type(f)) {
525 748
526 #define SET_HANDLER(utype, ltype) \ 749 #define SET_HANDLER(utype, ltype) \
527 case utype: \ 750 case utype: \
528 upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \ 751 upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
529 break; 752 break;
530 753
531 SET_HANDLER(UPB_TYPE_BOOL, bool); 754 SET_HANDLER(UPB_TYPE_BOOL, bool);
532 SET_HANDLER(UPB_TYPE_INT32, int32); 755 SET_HANDLER(UPB_TYPE_INT32, int32);
(...skipping 17 matching lines...) Expand all
550 } 773 }
551 case UPB_TYPE_MESSAGE: { 774 case UPB_TYPE_MESSAGE: {
552 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); 775 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
553 break; 776 break;
554 } 777 }
555 } 778 }
556 779
557 upb_handlerattr_uninit(&attr); 780 upb_handlerattr_uninit(&attr);
558 } 781 }
559 782
560 783 static void add_handlers_for_message(const void* closure,
561 static void add_handlers_for_message(const void *closure, upb_handlers *h) { 784 upb_handlers* h) {
562 const upb_msgdef* msgdef = upb_handlers_msgdef(h); 785 const upb_msgdef* msgdef = upb_handlers_msgdef(h);
563 Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef)); 786 TSRMLS_FETCH();
787 Descriptor* desc = (Descriptor*)zend_object_store_get_object(
788 get_def_obj((void*)msgdef) TSRMLS_CC);
564 upb_msg_field_iter i; 789 upb_msg_field_iter i;
565 790
566 // If this is a mapentry message type, set up a special set of handlers and 791 // If this is a mapentry message type, set up a special set of handlers and
567 // bail out of the normal (user-defined) message type handling. 792 // bail out of the normal (user-defined) message type handling.
568 if (upb_msgdef_mapentry(msgdef)) { 793 if (upb_msgdef_mapentry(msgdef)) {
569 add_handlers_for_mapentry(msgdef, h, desc); 794 add_handlers_for_mapentry(msgdef, h, desc);
570 return; 795 return;
571 } 796 }
572 797
573 // Ensure layout exists. We may be invoked to create handlers for a given 798 // Ensure layout exists. We may be invoked to create handlers for a given
574 // message if we are included as a submsg of another message type before our 799 // message if we are included as a submsg of another message type before our
575 // class is actually built, so to work around this, we just create the layout 800 // class is actually built, so to work around this, we just create the layout
576 // (and handlers, in the class-building function) on-demand. 801 // (and handlers, in the class-building function) on-demand.
577 if (desc->layout == NULL) { 802 if (desc->layout == NULL) {
578 desc->layout = create_layout(desc->msgdef); 803 desc->layout = create_layout(desc->msgdef);
579 } 804 }
580 805
581 for (upb_msg_field_begin(&i, desc->msgdef); 806 for (upb_msg_field_begin(&i, desc->msgdef);
582 !upb_msg_field_done(&i); 807 !upb_msg_field_done(&i);
583 upb_msg_field_next(&i)) { 808 upb_msg_field_next(&i)) {
584 const upb_fielddef *f = upb_msg_iter_field(&i); 809 const upb_fielddef *f = upb_msg_iter_field(&i);
585 size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + 810 size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
586 sizeof(MessageHeader); 811 sizeof(MessageHeader);
587 812
588 if (upb_fielddef_containingoneof(f)) { 813 if (upb_fielddef_containingoneof(f)) {
589 size_t oneof_case_offset = 814 size_t oneof_case_offset =
590 desc->layout->fields[upb_fielddef_index(f)].case_offset + 815 desc->layout->fields[upb_fielddef_index(f)].case_offset +
591 sizeof(MessageHeader); 816 sizeof(MessageHeader);
592 add_handlers_for_oneof_field(h, f, offset, oneof_case_offset); 817 int property_cache_index =
818 desc->layout->fields[upb_fielddef_index(f)].cache_index;
819 add_handlers_for_oneof_field(h, f, offset, oneof_case_offset,
820 property_cache_index);
593 } else if (is_map_field(f)) { 821 } else if (is_map_field(f)) {
594 add_handlers_for_mapfield(h, f, offset, desc); 822 add_handlers_for_mapfield(h, f, offset, desc);
595 } else if (upb_fielddef_isseq(f)) { 823 } else if (upb_fielddef_isseq(f)) {
596 add_handlers_for_repeated_field(h, f, offset); 824 add_handlers_for_repeated_field(h, f, offset);
597 } else { 825 } else {
598 add_handlers_for_singular_field(h, f, offset); 826 add_handlers_for_singular_field(h, f, offset);
599 } 827 }
600 } 828 }
601 } 829 }
602 830
(...skipping 11 matching lines...) Expand all
614 // Constructs the handlers for filling a message's data into an in-memory 842 // Constructs the handlers for filling a message's data into an in-memory
615 // object. 843 // object.
616 const upb_handlers* get_fill_handlers(Descriptor* desc) { 844 const upb_handlers* get_fill_handlers(Descriptor* desc) {
617 if (!desc->fill_handlers) { 845 if (!desc->fill_handlers) {
618 desc->fill_handlers = 846 desc->fill_handlers =
619 new_fill_handlers(desc, &desc->fill_handlers); 847 new_fill_handlers(desc, &desc->fill_handlers);
620 } 848 }
621 return desc->fill_handlers; 849 return desc->fill_handlers;
622 } 850 }
623 851
624 // Constructs the upb decoder method for parsing messages of this type.
625 // This is called from the message class creation code.
626 const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc, 852 const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
627 const void* owner) { 853 const void* owner) {
628 const upb_handlers* handlers = get_fill_handlers(desc); 854 const upb_handlers* handlers = get_fill_handlers(desc);
629 upb_pbdecodermethodopts opts; 855 upb_pbdecodermethodopts opts;
630 upb_pbdecodermethodopts_init(&opts, handlers); 856 upb_pbdecodermethodopts_init(&opts, handlers);
631 857
632 return upb_pbdecodermethod_new(&opts, owner); 858 return upb_pbdecodermethod_new(&opts, owner);
633 } 859 }
634 860
635 static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) { 861 static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
636 if (desc->fill_method == NULL) { 862 if (desc->fill_method == NULL) {
637 desc->fill_method = new_fillmsg_decodermethod( 863 desc->fill_method = new_fillmsg_decodermethod(
638 desc, &desc->fill_method); 864 desc, &desc->fill_method);
639 } 865 }
640 return desc->fill_method; 866 return desc->fill_method;
641 } 867 }
642 868
643 static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
644 if (desc->json_fill_method == NULL) {
645 desc->json_fill_method =
646 upb_json_parsermethod_new(desc->msgdef, &desc->json_fill_method);
647 }
648 return desc->json_fill_method;
649 }
650
651
652 // Stack-allocated context during an encode/decode operation. Contains the upb
653 // environment and its stack-based allocator, an initial buffer for allocations
654 // to avoid malloc() when possible, and a template for Ruby exception messages
655 // if any error occurs.
656 #define STACK_ENV_STACKBYTES 4096
657 typedef struct {
658 upb_env env;
659 const char* ruby_error_template;
660 char allocbuf[STACK_ENV_STACKBYTES];
661 } stackenv;
662
663 static void stackenv_init(stackenv* se, const char* errmsg);
664 static void stackenv_uninit(stackenv* se);
665
666 // Callback invoked by upb if any error occurs during parsing or serialization.
667 static bool env_error_func(void* ud, const upb_status* status) {
668 stackenv* se = ud;
669 // Free the env -- rb_raise will longjmp up the stack past the encode/decode
670 // function so it would not otherwise have been freed.
671 stackenv_uninit(se);
672
673 // TODO(haberman): have a way to verify that this is actually a parse error,
674 // instead of just throwing "parse error" unconditionally.
675 rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
676 // Never reached: rb_raise() always longjmp()s up the stack, past all of our
677 // code, back to Ruby.
678 return false;
679 }
680
681 static void stackenv_init(stackenv* se, const char* errmsg) {
682 se->ruby_error_template = errmsg;
683 upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
684 upb_env_seterrorfunc(&se->env, env_error_func, se);
685 }
686
687 static void stackenv_uninit(stackenv* se) {
688 upb_env_uninit(&se->env);
689 }
690
691 /*
692 * call-seq:
693 * MessageClass.decode(data) => message
694 *
695 * Decodes the given data (as a string containing bytes in protocol buffers wire
696 * format) under the interpretration given by this message class's definition
697 * and returns a message object with the corresponding field values.
698 */
699 VALUE Message_decode(VALUE klass, VALUE data) {
700 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
701 Descriptor* desc = ruby_to_Descriptor(descriptor);
702 VALUE msgklass = Descriptor_msgclass(descriptor);
703 VALUE msg_rb;
704 MessageHeader* msg;
705
706 if (TYPE(data) != T_STRING) {
707 rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
708 }
709
710 msg_rb = rb_class_new_instance(0, NULL, msgklass);
711 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
712
713 {
714 const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
715 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
716 stackenv se;
717 upb_sink sink;
718 upb_pbdecoder* decoder;
719 stackenv_init(&se, "Error occurred during parsing: %s");
720
721 upb_sink_reset(&sink, h, msg);
722 decoder = upb_pbdecoder_create(&se.env, method, &sink);
723 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
724 upb_pbdecoder_input(decoder));
725
726 stackenv_uninit(&se);
727 }
728
729 return msg_rb;
730 }
731
732 /*
733 * call-seq:
734 * MessageClass.decode_json(data) => message
735 *
736 * Decodes the given data (as a string containing bytes in protocol buffers wire
737 * format) under the interpretration given by this message class's definition
738 * and returns a message object with the corresponding field values.
739 */
740 VALUE Message_decode_json(VALUE klass, VALUE data) {
741 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
742 Descriptor* desc = ruby_to_Descriptor(descriptor);
743 VALUE msgklass = Descriptor_msgclass(descriptor);
744 VALUE msg_rb;
745 MessageHeader* msg;
746
747 if (TYPE(data) != T_STRING) {
748 rb_raise(rb_eArgError, "Expected string for JSON data.");
749 }
750 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
751 // convert, because string handlers pass data directly to message string
752 // fields.
753
754 msg_rb = rb_class_new_instance(0, NULL, msgklass);
755 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
756
757 {
758 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
759 stackenv se;
760 upb_sink sink;
761 upb_json_parser* parser;
762 stackenv_init(&se, "Error occurred during parsing: %s");
763
764 upb_sink_reset(&sink, get_fill_handlers(desc), msg);
765 parser = upb_json_parser_create(&se.env, method, &sink);
766 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
767 upb_json_parser_input(parser));
768
769 stackenv_uninit(&se);
770 }
771
772 return msg_rb;
773 }
774
775 // ----------------------------------------------------------------------------- 869 // -----------------------------------------------------------------------------
776 // Serializing. 870 // Serializing.
777 // ----------------------------------------------------------------------------- 871 // -----------------------------------------------------------------------------
778 //
779 // The code below also comes from upb's prototype Ruby binding, developed by
780 // haberman@.
781 872
782 /* stringsink *****************************************************************/ 873 static void putmsg(zval* msg, const Descriptor* desc, upb_sink* sink,
874 int depth TSRMLS_DC);
783 875
784 // This should probably be factored into a common upb component. 876 static void putstr(zval* str, const upb_fielddef* f, upb_sink* sink);
785 877
786 typedef struct { 878 static void putrawstr(const char* str, int len, const upb_fielddef* f,
787 upb_byteshandler handler; 879 upb_sink* sink);
788 upb_bytessink sink;
789 char *ptr;
790 size_t len, size;
791 } stringsink;
792 880
793 static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) { 881 static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink,
794 stringsink *sink = _sink; 882 int depth TSRMLS_DC);
795 sink->len = 0;
796 return sink;
797 }
798 883
799 static size_t stringsink_string(void *_sink, const void *hd, const char *ptr, 884 static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
800 size_t len, const upb_bufhandle *handle) { 885 int depth TSRMLS_DC);
801 stringsink *sink = _sink; 886 static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int depth
802 size_t new_size = sink->size; 887 » » TSRMLS_DC);
803 888
804 UPB_UNUSED(hd); 889 static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) {
805 UPB_UNUSED(handle);
806
807 while (sink->len + len > new_size) {
808 new_size *= 2;
809 }
810
811 if (new_size != sink->size) {
812 sink->ptr = realloc(sink->ptr, new_size);
813 sink->size = new_size;
814 }
815
816 memcpy(sink->ptr + sink->len, ptr, len);
817 sink->len += len;
818
819 return len;
820 }
821
822 void stringsink_init(stringsink *sink) {
823 upb_byteshandler_init(&sink->handler);
824 upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
825 upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
826
827 upb_bytessink_reset(&sink->sink, &sink->handler, sink);
828
829 sink->size = 32;
830 sink->ptr = malloc(sink->size);
831 sink->len = 0;
832 }
833
834 void stringsink_uninit(stringsink *sink) {
835 free(sink->ptr);
836 }
837
838 /* msgvisitor *****************************************************************/
839
840 // TODO: If/when we support proto2 semantics in addition to the current proto3
841 // semantics, which means that we have true field presence, we will want to
842 // modify msgvisitor so that it emits all present fields rather than all
843 // non-default-value fields.
844 //
845 // Likewise, when implementing JSON serialization, we may need to have a
846 // 'verbose' mode that outputs all fields and a 'concise' mode that outputs only
847 // those with non-default values.
848
849 static void putmsg(VALUE msg, const Descriptor* desc,
850 upb_sink *sink, int depth);
851
852 static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
853 upb_selector_t ret; 890 upb_selector_t ret;
854 bool ok = upb_handlers_getselector(f, type, &ret); 891 bool ok = upb_handlers_getselector(f, type, &ret);
855 UPB_ASSERT_VAR(ok, ok); 892 UPB_ASSERT(ok);
856 return ret; 893 return ret;
857 } 894 }
858 895
859 static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { 896 static void put_optional_value(const void* memory, int len, const upb_fielddef* f,
860 upb_sink subsink; 897 int depth, upb_sink* sink TSRMLS_DC) {
898 assert(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL);
861 899
862 if (str == Qnil) return; 900 switch (upb_fielddef_type(f)) {
901 #define T(upbtypeconst, upbtype, ctype, default_value) \
902 case upbtypeconst: { \
903 ctype value = DEREF(memory, 0, ctype); \
904 if (value != default_value) { \
905 upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); \
906 upb_sink_put##upbtype(sink, sel, value); \
907 } \
908 } break;
863 909
864 assert(BUILTIN_TYPE(str) == RUBY_T_STRING); 910 T(UPB_TYPE_FLOAT, float, float, 0.0)
865 911 T(UPB_TYPE_DOUBLE, double, double, 0.0)
866 // Ensure that the string has the correct encoding. We also check at field-set 912 T(UPB_TYPE_BOOL, bool, uint8_t, 0)
867 // time, but the user may have mutated the string object since then. 913 T(UPB_TYPE_ENUM, int32, int32_t, 0)
868 native_slot_validate_string_encoding(upb_fielddef_type(f), str); 914 T(UPB_TYPE_INT32, int32, int32_t, 0)
869 915 T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
870 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), 916 T(UPB_TYPE_INT64, int64, int64_t, 0)
871 &subsink); 917 T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
872 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
873 RSTRING_LEN(str), NULL);
874 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
875 }
876
877 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
878 int depth) {
879 upb_sink subsink;
880 VALUE descriptor;
881 Descriptor* subdesc;
882
883 if (submsg == Qnil) return;
884
885 descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
886 subdesc = ruby_to_Descriptor(descriptor);
887
888 upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
889 putmsg(submsg, subdesc, &subsink, depth + 1);
890 upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
891 }
892
893 static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
894 int depth) {
895 upb_sink subsink;
896 upb_fieldtype_t type = upb_fielddef_type(f);
897 upb_selector_t sel = 0;
898 int size;
899
900 if (ary == Qnil) return;
901
902 upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
903
904 if (upb_fielddef_isprimitive(f)) {
905 sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
906 }
907
908 size = NUM2INT(RepeatedField_length(ary));
909 for (int i = 0; i < size; i++) {
910 void* memory = RepeatedField_index_native(ary, i);
911 switch (type) {
912 #define T(upbtypeconst, upbtype, ctype) \
913 case upbtypeconst: \
914 upb_sink_put##upbtype(&subsink, sel, *((ctype *)memory)); \
915 break;
916
917 T(UPB_TYPE_FLOAT, float, float)
918 T(UPB_TYPE_DOUBLE, double, double)
919 T(UPB_TYPE_BOOL, bool, int8_t)
920 case UPB_TYPE_ENUM:
921 T(UPB_TYPE_INT32, int32, int32_t)
922 T(UPB_TYPE_UINT32, uint32, uint32_t)
923 T(UPB_TYPE_INT64, int64, int64_t)
924 T(UPB_TYPE_UINT64, uint64, uint64_t)
925
926 case UPB_TYPE_STRING:
927 case UPB_TYPE_BYTES:
928 putstr(*((VALUE *)memory), f, &subsink);
929 break;
930 case UPB_TYPE_MESSAGE:
931 putsubmsg(*((VALUE *)memory), f, &subsink, depth);
932 break;
933 918
934 #undef T 919 #undef T
935 920 case UPB_TYPE_STRING:
936 } 921 case UPB_TYPE_BYTES:
937 } 922 putrawstr(memory, len, f, sink);
938 upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
939 }
940
941 static void put_ruby_value(VALUE value,
942 const upb_fielddef *f,
943 VALUE type_class,
944 int depth,
945 upb_sink *sink) {
946 upb_selector_t sel = 0;
947 if (upb_fielddef_isprimitive(f)) {
948 sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
949 }
950
951 switch (upb_fielddef_type(f)) {
952 case UPB_TYPE_INT32:
953 upb_sink_putint32(sink, sel, NUM2INT(value));
954 break; 923 break;
955 case UPB_TYPE_INT64: 924 case UPB_TYPE_MESSAGE: {
956 upb_sink_putint64(sink, sel, NUM2LL(value)); 925 zval* submsg = *(zval**)memory;
957 break; 926 putsubmsg(submsg, f, sink, depth TSRMLS_CC);
958 case UPB_TYPE_UINT32:
959 upb_sink_putuint32(sink, sel, NUM2UINT(value));
960 break;
961 case UPB_TYPE_UINT64:
962 upb_sink_putuint64(sink, sel, NUM2ULL(value));
963 break;
964 case UPB_TYPE_FLOAT:
965 upb_sink_putfloat(sink, sel, NUM2DBL(value));
966 break;
967 case UPB_TYPE_DOUBLE:
968 upb_sink_putdouble(sink, sel, NUM2DBL(value));
969 break;
970 case UPB_TYPE_ENUM: {
971 if (TYPE(value) == T_SYMBOL) {
972 value = rb_funcall(type_class, rb_intern("resolve"), 1, value);
973 }
974 upb_sink_putint32(sink, sel, NUM2INT(value));
975 break; 927 break;
976 } 928 }
977 case UPB_TYPE_BOOL: 929 default:
978 upb_sink_putbool(sink, sel, value == Qtrue); 930 assert(false);
979 break;
980 case UPB_TYPE_STRING:
981 case UPB_TYPE_BYTES:
982 putstr(value, f, sink);
983 break;
984 case UPB_TYPE_MESSAGE:
985 putsubmsg(value, f, sink, depth);
986 } 931 }
987 } 932 }
988 933
989 static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink, 934 // Only string/bytes fields are stored as zval.
990 int depth) { 935 static const char* raw_value(void* memory, const upb_fielddef* f) {
936 switch (upb_fielddef_type(f)) {
937 case UPB_TYPE_STRING:
938 case UPB_TYPE_BYTES:
939 return Z_STRVAL_PP((zval**)memory);
940 break;
941 default:
942 return memory;
943 }
944 }
945
946 static int raw_value_len(void* memory, int len, const upb_fielddef* f) {
947 switch (upb_fielddef_type(f)) {
948 case UPB_TYPE_STRING:
949 case UPB_TYPE_BYTES:
950 return Z_STRLEN_PP((zval**)memory);
951 break;
952 default:
953 return len;
954 }
955 }
956
957 static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink,
958 int depth TSRMLS_DC) {
991 Map* self; 959 Map* self;
992 upb_sink subsink; 960 upb_sink subsink;
993 const upb_fielddef* key_field; 961 const upb_fielddef* key_field;
994 const upb_fielddef* value_field; 962 const upb_fielddef* value_field;
995 Map_iter it; 963 MapIter it;
964 int len;
996 965
997 if (map == Qnil) return; 966 if (map == NULL) return;
998 self = ruby_to_Map(map); 967 self = UNBOX(Map, map);
999 968
1000 upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); 969 upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
1001 970
1002 assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE); 971 assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
1003 key_field = map_field_key(f); 972 key_field = map_field_key(f);
1004 value_field = map_field_value(f); 973 value_field = map_field_value(f);
1005 974
1006 for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) { 975 for (map_begin(map, &it TSRMLS_CC); !map_done(&it); map_next(&it)) {
1007 VALUE key = Map_iter_key(&it);
1008 VALUE value = Map_iter_value(&it);
1009 upb_status status; 976 upb_status status;
1010 977
1011 upb_sink entry_sink; 978 upb_sink entry_sink;
1012 upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG), 979 upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
1013 &entry_sink); 980 &entry_sink);
1014 upb_sink_startmsg(&entry_sink); 981 upb_sink_startmsg(&entry_sink);
1015 982
1016 put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink); 983 // Serialize key.
1017 put_ruby_value(value, value_field, self->value_type_class, depth + 1, 984 const char *key = map_iter_key(&it, &len);
1018 &entry_sink); 985 put_optional_value(key, len, key_field, depth + 1, &entry_sink TSRMLS_CC);
986
987 // Serialize value.
988 upb_value value = map_iter_value(&it, &len);
989 put_optional_value(raw_value(upb_value_memory(&value), value_field),
990 raw_value_len(upb_value_memory(&value), len, value_field) ,
991 value_field, depth + 1, &entry_sink TSRMLS_CC);
1019 992
1020 upb_sink_endmsg(&entry_sink, &status); 993 upb_sink_endmsg(&entry_sink, &status);
1021 upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); 994 upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
1022 } 995 }
1023 996
1024 upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); 997 upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1025 } 998 }
1026 999
1027 static void putmsg(VALUE msg_rb, const Descriptor* desc, 1000 static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink,
1028 upb_sink *sink, int depth) { 1001 int depth TSRMLS_DC) {
1029 MessageHeader* msg;
1030 upb_msg_field_iter i; 1002 upb_msg_field_iter i;
1031 upb_status status; 1003 upb_status status;
1032 1004
1033 upb_sink_startmsg(sink); 1005 upb_sink_startmsg(sink);
1034 1006
1035 // Protect against cycles (possible because users may freely reassign message 1007 // Protect against cycles (possible because users may freely reassign message
1036 // and repeated fields) by imposing a maximum recursion depth. 1008 // and repeated fields) by imposing a maximum recursion depth.
1037 if (depth > ENCODE_MAX_NESTING) { 1009 if (depth > ENCODE_MAX_NESTING) {
1038 rb_raise(rb_eRuntimeError, 1010 zend_error(E_ERROR,
1039 "Maximum recursion depth exceeded during encoding."); 1011 "Maximum recursion depth exceeded during encoding.");
1040 } 1012 }
1041 1013
1042 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); 1014 MessageHeader* msg = zend_object_store_get_object(msg_php TSRMLS_CC);
1043 1015
1044 for (upb_msg_field_begin(&i, desc->msgdef); 1016 for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i);
1045 !upb_msg_field_done(&i);
1046 upb_msg_field_next(&i)) { 1017 upb_msg_field_next(&i)) {
1047 upb_fielddef *f = upb_msg_iter_field(&i); 1018 upb_fielddef* f = upb_msg_iter_field(&i);
1048 bool is_matching_oneof = false; 1019 uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset +
1049 uint32_t offset = 1020 sizeof(MessageHeader);
1050 desc->layout->fields[upb_fielddef_index(f)].offset +
1051 sizeof(MessageHeader);
1052 1021
1053 if (upb_fielddef_containingoneof(f)) { 1022 if (upb_fielddef_containingoneof(f)) {
1054 uint32_t oneof_case_offset = 1023 uint32_t oneof_case_offset =
1055 desc->layout->fields[upb_fielddef_index(f)].case_offset + 1024 desc->layout->fields[upb_fielddef_index(f)].case_offset +
1056 sizeof(MessageHeader); 1025 sizeof(MessageHeader);
1057 // For a oneof, check that this field is actually present -- skip all the 1026 // For a oneof, check that this field is actually present -- skip all the
1058 // below if not. 1027 // below if not.
1059 if (DEREF(msg, oneof_case_offset, uint32_t) != 1028 if (DEREF(msg, oneof_case_offset, uint32_t) != upb_fielddef_number(f)) {
1060 upb_fielddef_number(f)) {
1061 continue; 1029 continue;
1062 } 1030 }
1063 // Otherwise, fall through to the appropriate singular-field handler 1031 // Otherwise, fall through to the appropriate singular-field handler
1064 // below. 1032 // below.
1065 is_matching_oneof = true;
1066 } 1033 }
1067 1034
1068 if (is_map_field(f)) { 1035 if (is_map_field(f)) {
1069 VALUE map = DEREF(msg, offset, VALUE); 1036 zval* map = *DEREF(msg, offset, zval**);
1070 if (map != Qnil) { 1037 if (map != NULL) {
1071 putmap(map, f, sink, depth); 1038 putmap(map, f, sink, depth TSRMLS_CC);
1072 } 1039 }
1073 } else if (upb_fielddef_isseq(f)) { 1040 } else if (upb_fielddef_isseq(f)) {
1074 VALUE ary = DEREF(msg, offset, VALUE); 1041 zval* array = *DEREF(msg, offset, zval**);
1075 if (ary != Qnil) { 1042 if (array != NULL) {
1076 putary(ary, f, sink, depth); 1043 putarray(array, f, sink, depth TSRMLS_CC);
1077 } 1044 }
1078 } else if (upb_fielddef_isstring(f)) { 1045 } else if (upb_fielddef_isstring(f)) {
1079 VALUE str = DEREF(msg, offset, VALUE); 1046 zval* str = *DEREF(msg, offset, zval**);
1080 if (is_matching_oneof || RSTRING_LEN(str) > 0) { 1047 if (Z_STRLEN_P(str) > 0) {
1081 putstr(str, f, sink); 1048 putstr(str, f, sink);
1082 } 1049 }
1083 } else if (upb_fielddef_issubmsg(f)) { 1050 } else if (upb_fielddef_issubmsg(f)) {
1084 putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth); 1051 putsubmsg(*DEREF(msg, offset, zval**), f, sink, depth TSRMLS_CC);
1085 } else { 1052 } else {
1086 upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); 1053 upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1087 1054
1088 #define T(upbtypeconst, upbtype, ctype, default_value) \ 1055 #define T(upbtypeconst, upbtype, ctype, default_value) \
1089 case upbtypeconst: { \ 1056 case upbtypeconst: { \
1090 ctype value = DEREF(msg, offset, ctype); \ 1057 ctype value = DEREF(msg, offset, ctype); \
1091 if (is_matching_oneof || value != default_value) { \ 1058 if (value != default_value) { \
1092 upb_sink_put##upbtype(sink, sel, value); \ 1059 upb_sink_put##upbtype(sink, sel, value); \
1093 } \ 1060 } \
1094 } \ 1061 } break;
1095 break;
1096 1062
1097 switch (upb_fielddef_type(f)) { 1063 switch (upb_fielddef_type(f)) {
1098 T(UPB_TYPE_FLOAT, float, float, 0.0) 1064 T(UPB_TYPE_FLOAT, float, float, 0.0)
1099 T(UPB_TYPE_DOUBLE, double, double, 0.0) 1065 T(UPB_TYPE_DOUBLE, double, double, 0.0)
1100 T(UPB_TYPE_BOOL, bool, uint8_t, 0) 1066 T(UPB_TYPE_BOOL, bool, uint8_t, 0)
1101 case UPB_TYPE_ENUM: 1067 case UPB_TYPE_ENUM:
1102 T(UPB_TYPE_INT32, int32, int32_t, 0) 1068 T(UPB_TYPE_INT32, int32, int32_t, 0)
1103 T(UPB_TYPE_UINT32, uint32, uint32_t, 0) 1069 T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
1104 T(UPB_TYPE_INT64, int64, int64_t, 0) 1070 T(UPB_TYPE_INT64, int64, int64_t, 0)
1105 T(UPB_TYPE_UINT64, uint64, uint64_t, 0) 1071 T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
1106 1072
1107 case UPB_TYPE_STRING: 1073 case UPB_TYPE_STRING:
1108 case UPB_TYPE_BYTES: 1074 case UPB_TYPE_BYTES:
1109 case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error."); 1075 case UPB_TYPE_MESSAGE:
1076 zend_error(E_ERROR, "Internal error.");
1110 } 1077 }
1111 1078
1112 #undef T 1079 #undef T
1113
1114 } 1080 }
1115 } 1081 }
1116 1082
1117 upb_sink_endmsg(sink, &status); 1083 upb_sink_endmsg(sink, &status);
1118 } 1084 }
1119 1085
1086 static void putstr(zval* str, const upb_fielddef *f, upb_sink *sink) {
1087 upb_sink subsink;
1088
1089 if (ZVAL_IS_NULL(str)) return;
1090
1091 assert(Z_TYPE_P(str) == IS_STRING);
1092
1093 // Ensure that the string has the correct encoding. We also check at field-set
1094 // time, but the user may have mutated the string object since then.
1095 if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
1096 !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) {
1097 zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
1098 return;
1099 }
1100
1101 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), Z_STRLEN_P(str),
1102 &subsink);
1103 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str),
1104 Z_STRLEN_P(str), NULL);
1105 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
1106 }
1107
1108 static void putrawstr(const char* str, int len, const upb_fielddef* f,
1109 upb_sink* sink) {
1110 upb_sink subsink;
1111
1112 if (len == 0) return;
1113
1114 // Ensure that the string has the correct encoding. We also check at field-set
1115 // time, but the user may have mutated the string object since then.
1116 if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
1117 !is_structurally_valid_utf8(str, len)) {
1118 zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
1119 return;
1120 }
1121
1122 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), len, &subsink);
1123 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), str, len, NULL);
1124 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
1125 }
1126
1127 static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink,
1128 int depth TSRMLS_DC) {
1129 upb_sink subsink;
1130
1131 if (Z_TYPE_P(submsg) == IS_NULL) return;
1132
1133 zval* php_descriptor = get_def_obj(upb_fielddef_msgsubdef(f));
1134 Descriptor* subdesc =
1135 (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
1136
1137 upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
1138 putmsg(submsg, subdesc, &subsink, depth + 1 TSRMLS_CC);
1139 upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
1140 }
1141
1142 static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink,
1143 int depth TSRMLS_DC) {
1144 upb_sink subsink;
1145 upb_fieldtype_t type = upb_fielddef_type(f);
1146 upb_selector_t sel = 0;
1147 int size, i;
1148
1149 assert(array != NULL);
1150 RepeatedField* intern =
1151 (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC);
1152 size = zend_hash_num_elements(HASH_OF(intern->array));
1153 if (size == 0) return;
1154
1155 upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
1156
1157 if (upb_fielddef_isprimitive(f)) {
1158 sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1159 }
1160
1161 for (i = 0; i < size; i++) {
1162 void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
1163 switch (type) {
1164 #define T(upbtypeconst, upbtype, ctype) \
1165 case upbtypeconst: \
1166 upb_sink_put##upbtype(&subsink, sel, *((ctype*)memory)); \
1167 break;
1168
1169 T(UPB_TYPE_FLOAT, float, float)
1170 T(UPB_TYPE_DOUBLE, double, double)
1171 T(UPB_TYPE_BOOL, bool, int8_t)
1172 case UPB_TYPE_ENUM:
1173 T(UPB_TYPE_INT32, int32, int32_t)
1174 T(UPB_TYPE_UINT32, uint32, uint32_t)
1175 T(UPB_TYPE_INT64, int64, int64_t)
1176 T(UPB_TYPE_UINT64, uint64, uint64_t)
1177
1178 case UPB_TYPE_STRING:
1179 case UPB_TYPE_BYTES:
1180 putstr(*((zval**)memory), f, &subsink);
1181 break;
1182 case UPB_TYPE_MESSAGE:
1183 putsubmsg(*((zval**)memory), f, &subsink, depth TSRMLS_CC);
1184 break;
1185
1186 #undef T
1187 }
1188 }
1189 upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
1190 }
1191
1120 static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) { 1192 static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
1121 if (desc->pb_serialize_handlers == NULL) { 1193 if (desc->pb_serialize_handlers == NULL) {
1122 desc->pb_serialize_handlers = 1194 desc->pb_serialize_handlers =
1123 upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers); 1195 upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
1124 } 1196 }
1125 return desc->pb_serialize_handlers; 1197 return desc->pb_serialize_handlers;
1126 } 1198 }
1127 1199
1128 static const upb_handlers* msgdef_json_serialize_handlers( 1200 // -----------------------------------------------------------------------------
1129 Descriptor* desc, bool preserve_proto_fieldnames) { 1201 // PHP encode/decode methods
1130 if (preserve_proto_fieldnames) { 1202 // -----------------------------------------------------------------------------
1131 if (desc->json_serialize_handlers == NULL) {
1132 desc->json_serialize_handlers =
1133 upb_json_printer_newhandlers(
1134 desc->msgdef, true, &desc->json_serialize_handlers);
1135 }
1136 return desc->json_serialize_handlers;
1137 } else {
1138 if (desc->json_serialize_handlers_preserve == NULL) {
1139 desc->json_serialize_handlers_preserve =
1140 upb_json_printer_newhandlers(
1141 desc->msgdef, false, &desc->json_serialize_handlers_preserve);
1142 }
1143 return desc->json_serialize_handlers_preserve;
1144 }
1145 }
1146 1203
1147 /* 1204 PHP_METHOD(Message, encode) {
1148 * call-seq: 1205 zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis()));
1149 * MessageClass.encode(msg) => bytes 1206 Descriptor* desc =
1150 * 1207 (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
1151 * Encodes the given message object to its serialized form in protocol buffers
1152 * wire format.
1153 */
1154 VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1155 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1156 Descriptor* desc = ruby_to_Descriptor(descriptor);
1157 1208
1158 stringsink sink; 1209 stringsink sink;
1159 stringsink_init(&sink); 1210 stringsink_init(&sink);
1160 1211
1161 { 1212 {
1162 const upb_handlers* serialize_handlers = 1213 const upb_handlers* serialize_handlers = msgdef_pb_serialize_handlers(desc);
1163 msgdef_pb_serialize_handlers(desc);
1164 1214
1165 stackenv se; 1215 stackenv se;
1166 upb_pb_encoder* encoder; 1216 upb_pb_encoder* encoder;
1167 VALUE ret;
1168 1217
1169 stackenv_init(&se, "Error occurred during encoding: %s"); 1218 stackenv_init(&se, "Error occurred during encoding: %s");
1170 encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink); 1219 encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
1171 1220
1172 putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0); 1221 putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC);
1173 1222
1174 ret = rb_str_new(sink.ptr, sink.len); 1223 RETVAL_STRINGL(sink.ptr, sink.len, 1);
1175 1224
1176 stackenv_uninit(&se); 1225 stackenv_uninit(&se);
1177 stringsink_uninit(&sink); 1226 stringsink_uninit(&sink);
1178
1179 return ret;
1180 } 1227 }
1181 } 1228 }
1182 1229
1183 /* 1230 PHP_METHOD(Message, decode) {
1184 * call-seq: 1231 zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis()));
1185 * MessageClass.encode_json(msg) => json_string 1232 Descriptor* desc =
1186 * 1233 (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC);
1187 * Encodes the given message object into its serialized JSON representation. 1234 MessageHeader* msg = zend_object_store_get_object(getThis() TSRMLS_CC);
1188 */
1189 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1190 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1191 Descriptor* desc = ruby_to_Descriptor(descriptor);
1192 VALUE msg_rb;
1193 VALUE preserve_proto_fieldnames = Qfalse;
1194 stringsink sink;
1195 1235
1196 if (argc < 1 || argc > 2) { 1236 char *data = NULL;
1197 rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); 1237 int data_len;
1238 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
1239 FAILURE) {
1240 return;
1198 } 1241 }
1199 1242
1200 msg_rb = argv[0]; 1243 {
1244 const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
1245 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
1246 stackenv se;
1247 upb_sink sink;
1248 upb_pbdecoder* decoder;
1249 stackenv_init(&se, "Error occurred during parsing: %s");
1201 1250
1202 if (argc == 2) { 1251 upb_sink_reset(&sink, h, msg);
1203 VALUE hash_args = argv[1]; 1252 decoder = upb_pbdecoder_create(&se.env, method, &sink);
1204 if (TYPE(hash_args) != T_HASH) { 1253 upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder));
1205 rb_raise(rb_eArgError, "Expected hash arguments.");
1206 }
1207 preserve_proto_fieldnames = rb_hash_lookup2(
1208 hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
1209 }
1210
1211 stringsink_init(&sink);
1212
1213 {
1214 const upb_handlers* serialize_handlers =
1215 msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
1216 upb_json_printer* printer;
1217 stackenv se;
1218 VALUE ret;
1219
1220 stackenv_init(&se, "Error occurred during encoding: %s");
1221 printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
1222
1223 putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
1224
1225 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
1226 1254
1227 stackenv_uninit(&se); 1255 stackenv_uninit(&se);
1228 stringsink_uninit(&sink);
1229
1230 return ret;
1231 } 1256 }
1232 } 1257 }
1233
OLDNEW
« no previous file with comments | « third_party/protobuf/php/ext/google/protobuf/def.c ('k') | third_party/protobuf/php/ext/google/protobuf/map.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698