OLD | NEW |
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 2014 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. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 // ----------------------------------------------------------------------------- | 47 // ----------------------------------------------------------------------------- |
48 // Parsing. | 48 // Parsing. |
49 // ----------------------------------------------------------------------------- | 49 // ----------------------------------------------------------------------------- |
50 | 50 |
51 #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs) | 51 #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs) |
52 | 52 |
53 // Creates a handlerdata that simply contains the offset for this field. | 53 // Creates a handlerdata that simply contains the offset for this field. |
54 static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) { | 54 static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) { |
55 size_t* hd_ofs = ALLOC(size_t); | 55 size_t* hd_ofs = ALLOC(size_t); |
56 *hd_ofs = ofs; | 56 *hd_ofs = ofs; |
57 upb_handlers_addcleanup(h, hd_ofs, xfree); | 57 upb_handlers_addcleanup(h, hd_ofs, free); |
58 return hd_ofs; | 58 return hd_ofs; |
59 } | 59 } |
60 | 60 |
61 typedef struct { | 61 typedef struct { |
62 size_t ofs; | 62 size_t ofs; |
63 const upb_msgdef *md; | 63 const upb_msgdef *md; |
64 } submsg_handlerdata_t; | 64 } submsg_handlerdata_t; |
65 | 65 |
66 // Creates a handlerdata that contains offset and submessage type information. | 66 // Creates a handlerdata that contains offset and submessage type information. |
67 static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs, | 67 static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs, |
68 const upb_fielddef* f) { | 68 const upb_fielddef* f) { |
69 submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t); | 69 submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t); |
70 hd->ofs = ofs; | 70 hd->ofs = ofs; |
71 hd->md = upb_fielddef_msgsubdef(f); | 71 hd->md = upb_fielddef_msgsubdef(f); |
72 upb_handlers_addcleanup(h, hd, xfree); | 72 upb_handlers_addcleanup(h, hd, free); |
73 return hd; | 73 return hd; |
74 } | 74 } |
75 | 75 |
76 typedef struct { | 76 typedef struct { |
77 size_t ofs; // union data slot | 77 size_t ofs; // union data slot |
78 size_t case_ofs; // oneof_case field | 78 size_t case_ofs; // oneof_case field |
79 uint32_t oneof_case_num; // oneof-case number to place in oneof_case field | 79 uint32_t oneof_case_num; // oneof-case number to place in oneof_case field |
80 const upb_msgdef *md; // msgdef, for oneof submessage handler | 80 const upb_msgdef *md; // msgdef, for oneof submessage handler |
81 } oneof_handlerdata_t; | 81 } oneof_handlerdata_t; |
82 | 82 |
83 static const void *newoneofhandlerdata(upb_handlers *h, | 83 static const void *newoneofhandlerdata(upb_handlers *h, |
84 uint32_t ofs, | 84 uint32_t ofs, |
85 uint32_t case_ofs, | 85 uint32_t case_ofs, |
86 const upb_fielddef *f) { | 86 const upb_fielddef *f) { |
87 oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t); | 87 oneof_handlerdata_t *hd = ALLOC(oneof_handlerdata_t); |
88 hd->ofs = ofs; | 88 hd->ofs = ofs; |
89 hd->case_ofs = case_ofs; | 89 hd->case_ofs = case_ofs; |
90 // We reuse the field tag number as a oneof union discriminant tag. Note that | 90 // 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 | 91 // 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 | 92 // 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 | 93 // 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 | 94 // 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. | 95 // lets us easily look up the field in the oneof accessor. |
96 hd->oneof_case_num = upb_fielddef_number(f); | 96 hd->oneof_case_num = upb_fielddef_number(f); |
97 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) { | 97 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) { |
98 hd->md = upb_fielddef_msgsubdef(f); | 98 hd->md = upb_fielddef_msgsubdef(f); |
99 } else { | 99 } else { |
100 hd->md = NULL; | 100 hd->md = NULL; |
101 } | 101 } |
102 upb_handlers_addcleanup(h, hd, xfree); | 102 upb_handlers_addcleanup(h, hd, free); |
103 return hd; | 103 return hd; |
104 } | 104 } |
105 | 105 |
106 // A handler that starts a repeated field. Gets the Repeated*Field instance for | 106 // 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). | 107 // this field (such an instance always exists even in an empty message). |
108 static void *startseq_handler(void* closure, const void* hd) { | 108 static void *startseq_handler(void* closure, const void* hd) { |
109 MessageHeader* msg = closure; | 109 MessageHeader* msg = closure; |
110 const size_t *ofs = hd; | 110 const size_t *ofs = hd; |
111 return (void*)DEREF(msg, *ofs, VALUE); | 111 return (void*)DEREF(msg, *ofs, VALUE); |
112 } | 112 } |
(...skipping 15 matching lines...) Expand all Loading... |
128 DEFINE_APPEND_HANDLER(uint64, uint64_t) | 128 DEFINE_APPEND_HANDLER(uint64, uint64_t) |
129 DEFINE_APPEND_HANDLER(double, double) | 129 DEFINE_APPEND_HANDLER(double, double) |
130 | 130 |
131 // Appends a string to a repeated field. | 131 // Appends a string to a repeated field. |
132 static void* appendstr_handler(void *closure, | 132 static void* appendstr_handler(void *closure, |
133 const void *hd, | 133 const void *hd, |
134 size_t size_hint) { | 134 size_t size_hint) { |
135 VALUE ary = (VALUE)closure; | 135 VALUE ary = (VALUE)closure; |
136 VALUE str = rb_str_new2(""); | 136 VALUE str = rb_str_new2(""); |
137 rb_enc_associate(str, kRubyStringUtf8Encoding); | 137 rb_enc_associate(str, kRubyStringUtf8Encoding); |
138 RepeatedField_push_native(ary, &str); | 138 RepeatedField_push(ary, str); |
139 return (void*)str; | 139 return (void*)str; |
140 } | 140 } |
141 | 141 |
142 // Appends a 'bytes' string to a repeated field. | 142 // Appends a 'bytes' string to a repeated field. |
143 static void* appendbytes_handler(void *closure, | 143 static void* appendbytes_handler(void *closure, |
144 const void *hd, | 144 const void *hd, |
145 size_t size_hint) { | 145 size_t size_hint) { |
146 VALUE ary = (VALUE)closure; | 146 VALUE ary = (VALUE)closure; |
147 VALUE str = rb_str_new2(""); | 147 VALUE str = rb_str_new2(""); |
148 rb_enc_associate(str, kRubyString8bitEncoding); | 148 rb_enc_associate(str, kRubyString8bitEncoding); |
149 RepeatedField_push_native(ary, &str); | 149 RepeatedField_push(ary, str); |
150 return (void*)str; | 150 return (void*)str; |
151 } | 151 } |
152 | 152 |
153 // Sets a non-repeated string field in a message. | 153 // Sets a non-repeated string field in a message. |
154 static void* str_handler(void *closure, | 154 static void* str_handler(void *closure, |
155 const void *hd, | 155 const void *hd, |
156 size_t size_hint) { | 156 size_t size_hint) { |
157 MessageHeader* msg = closure; | 157 MessageHeader* msg = closure; |
158 const size_t *ofs = hd; | 158 const size_t *ofs = hd; |
159 VALUE str = rb_str_new2(""); | 159 VALUE str = rb_str_new2(""); |
(...skipping 15 matching lines...) Expand all Loading... |
175 } | 175 } |
176 | 176 |
177 static size_t stringdata_handler(void* closure, const void* hd, | 177 static size_t stringdata_handler(void* closure, const void* hd, |
178 const char* str, size_t len, | 178 const char* str, size_t len, |
179 const upb_bufhandle* handle) { | 179 const upb_bufhandle* handle) { |
180 VALUE rb_str = (VALUE)closure; | 180 VALUE rb_str = (VALUE)closure; |
181 noleak_rb_str_cat(rb_str, str, len); | 181 noleak_rb_str_cat(rb_str, str, len); |
182 return len; | 182 return len; |
183 } | 183 } |
184 | 184 |
185 static bool stringdata_end_handler(void* closure, const void* hd) { | |
186 MessageHeader* msg = closure; | |
187 const size_t *ofs = hd; | |
188 VALUE rb_str = DEREF(msg, *ofs, VALUE); | |
189 rb_obj_freeze(rb_str); | |
190 return true; | |
191 } | |
192 | |
193 static bool appendstring_end_handler(void* closure, const void* hd) { | |
194 VALUE ary = (VALUE)closure; | |
195 int size = RepeatedField_size(ary); | |
196 VALUE* last = RepeatedField_index_native(ary, size - 1); | |
197 VALUE rb_str = *last; | |
198 rb_obj_freeze(rb_str); | |
199 return true; | |
200 } | |
201 | |
202 // Appends a submessage to a repeated field (a regular Ruby array for now). | 185 // Appends a submessage to a repeated field (a regular Ruby array for now). |
203 static void *appendsubmsg_handler(void *closure, const void *hd) { | 186 static void *appendsubmsg_handler(void *closure, const void *hd) { |
204 VALUE ary = (VALUE)closure; | 187 VALUE ary = (VALUE)closure; |
205 const submsg_handlerdata_t *submsgdata = hd; | 188 const submsg_handlerdata_t *submsgdata = hd; |
206 VALUE subdesc = | 189 VALUE subdesc = |
207 get_def_obj((void*)submsgdata->md); | 190 get_def_obj((void*)submsgdata->md); |
208 VALUE subklass = Descriptor_msgclass(subdesc); | 191 VALUE subklass = Descriptor_msgclass(subdesc); |
209 MessageHeader* submsg; | 192 MessageHeader* submsg; |
210 | 193 |
211 VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); | 194 VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 } map_handlerdata_t; | 231 } map_handlerdata_t; |
249 | 232 |
250 // Temporary frame for map parsing: at the beginning of a map entry message, a | 233 // Temporary frame for map parsing: at the beginning of a map entry message, a |
251 // submsg handler allocates a frame to hold (i) a reference to the Map object | 234 // submsg handler allocates a frame to hold (i) a reference to the Map object |
252 // into which this message will be inserted and (ii) storage slots to | 235 // into which this message will be inserted and (ii) storage slots to |
253 // temporarily hold the key and value for this map entry until the end of the | 236 // temporarily hold the key and value for this map entry until the end of the |
254 // submessage. When the submessage ends, another handler is called to insert the | 237 // submessage. When the submessage ends, another handler is called to insert the |
255 // value into the map. | 238 // value into the map. |
256 typedef struct { | 239 typedef struct { |
257 VALUE map; | 240 VALUE map; |
258 const map_handlerdata_t* handlerdata; | |
259 char key_storage[NATIVE_SLOT_MAX_SIZE]; | 241 char key_storage[NATIVE_SLOT_MAX_SIZE]; |
260 char value_storage[NATIVE_SLOT_MAX_SIZE]; | 242 char value_storage[NATIVE_SLOT_MAX_SIZE]; |
261 } map_parse_frame_t; | 243 } map_parse_frame_t; |
262 | 244 |
263 static void MapParseFrame_mark(void* _self) { | |
264 map_parse_frame_t* frame = _self; | |
265 | |
266 // This shouldn't strictly be necessary since this should be rooted by the | |
267 // message itself, but it can't hurt. | |
268 rb_gc_mark(frame->map); | |
269 | |
270 native_slot_mark(frame->handlerdata->key_field_type, &frame->key_storage); | |
271 native_slot_mark(frame->handlerdata->value_field_type, &frame->value_storage); | |
272 } | |
273 | |
274 void MapParseFrame_free(void* self) { | |
275 xfree(self); | |
276 } | |
277 | |
278 rb_data_type_t MapParseFrame_type = { | |
279 "MapParseFrame", | |
280 { MapParseFrame_mark, MapParseFrame_free, NULL }, | |
281 }; | |
282 | |
283 // Array of Ruby objects wrapping map_parse_frame_t. | |
284 // We don't allow multiple concurrent decodes, so we assume that this global | |
285 // variable is specific to the "current" decode. | |
286 VALUE map_parse_frames; | |
287 | |
288 static map_parse_frame_t* map_push_frame(VALUE map, | |
289 const map_handlerdata_t* handlerdata) { | |
290 map_parse_frame_t* frame = ALLOC(map_parse_frame_t); | |
291 frame->handlerdata = handlerdata; | |
292 frame->map = map; | |
293 native_slot_init(handlerdata->key_field_type, &frame->key_storage); | |
294 native_slot_init(handlerdata->value_field_type, &frame->value_storage); | |
295 | |
296 rb_ary_push(map_parse_frames, | |
297 TypedData_Wrap_Struct(rb_cObject, &MapParseFrame_type, frame)); | |
298 | |
299 return frame; | |
300 } | |
301 | |
302 static void map_pop_frame() { | |
303 rb_ary_pop(map_parse_frames); | |
304 } | |
305 | |
306 // Handler to begin a map entry: allocates a temporary frame. This is the | 245 // Handler to begin a map entry: allocates a temporary frame. This is the |
307 // 'startsubmsg' handler on the msgdef that contains the map field. | 246 // 'startsubmsg' handler on the msgdef that contains the map field. |
308 static void *startmapentry_handler(void *closure, const void *hd) { | 247 static void *startmapentry_handler(void *closure, const void *hd) { |
309 MessageHeader* msg = closure; | 248 MessageHeader* msg = closure; |
310 const map_handlerdata_t* mapdata = hd; | 249 const map_handlerdata_t* mapdata = hd; |
311 VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); | 250 VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); |
312 | 251 |
313 return map_push_frame(map_rb, mapdata); | 252 map_parse_frame_t* frame = ALLOC(map_parse_frame_t); |
| 253 frame->map = map_rb; |
| 254 |
| 255 native_slot_init(mapdata->key_field_type, &frame->key_storage); |
| 256 native_slot_init(mapdata->value_field_type, &frame->value_storage); |
| 257 |
| 258 return frame; |
314 } | 259 } |
315 | 260 |
316 // Handler to end a map entry: inserts the value defined during the message into | 261 // Handler to end a map entry: inserts the value defined during the message into |
317 // the map. This is the 'endmsg' handler on the map entry msgdef. | 262 // the map. This is the 'endmsg' handler on the map entry msgdef. |
318 static bool endmap_handler(void *closure, const void *hd, upb_status* s) { | 263 static bool endmap_handler(void *closure, const void *hd, upb_status* s) { |
319 map_parse_frame_t* frame = closure; | 264 map_parse_frame_t* frame = closure; |
320 const map_handlerdata_t* mapdata = hd; | 265 const map_handlerdata_t* mapdata = hd; |
321 | 266 |
322 VALUE key = native_slot_get( | 267 VALUE key = native_slot_get( |
323 mapdata->key_field_type, Qnil, | 268 mapdata->key_field_type, Qnil, |
324 &frame->key_storage); | 269 &frame->key_storage); |
325 | 270 |
326 VALUE value_field_typeclass = Qnil; | 271 VALUE value_field_typeclass = Qnil; |
327 VALUE value; | 272 VALUE value; |
328 | 273 |
329 if (mapdata->value_field_type == UPB_TYPE_MESSAGE || | 274 if (mapdata->value_field_type == UPB_TYPE_MESSAGE || |
330 mapdata->value_field_type == UPB_TYPE_ENUM) { | 275 mapdata->value_field_type == UPB_TYPE_ENUM) { |
331 value_field_typeclass = get_def_obj(mapdata->value_field_subdef); | 276 value_field_typeclass = get_def_obj(mapdata->value_field_subdef); |
332 } | 277 } |
333 | 278 |
334 value = native_slot_get( | 279 value = native_slot_get( |
335 mapdata->value_field_type, value_field_typeclass, | 280 mapdata->value_field_type, value_field_typeclass, |
336 &frame->value_storage); | 281 &frame->value_storage); |
337 | 282 |
338 Map_index_set(frame->map, key, value); | 283 Map_index_set(frame->map, key, value); |
339 map_pop_frame(); | 284 free(frame); |
340 | 285 |
341 return true; | 286 return true; |
342 } | 287 } |
343 | 288 |
344 // Allocates a new map_handlerdata_t given the map entry message definition. If | 289 // Allocates a new map_handlerdata_t given the map entry message definition. If |
345 // the offset of the field within the parent message is also given, that is | 290 // the offset of the field within the parent message is also given, that is |
346 // added to the handler data as well. Note that this is called *twice* per map | 291 // added to the handler data as well. Note that this is called *twice* per map |
347 // field: once in the parent message handler setup when setting the startsubmsg | 292 // field: once in the parent message handler setup when setting the startsubmsg |
348 // handler and once in the map entry message handler setup when setting the | 293 // handler and once in the map entry message handler setup when setting the |
349 // key/value and endmsg handlers. The reason is that there is no easy way to | 294 // key/value and endmsg handlers. The reason is that there is no easy way to |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 MessageHeader* msg = closure; | 353 MessageHeader* msg = closure; |
409 const oneof_handlerdata_t *oneofdata = hd; | 354 const oneof_handlerdata_t *oneofdata = hd; |
410 VALUE str = rb_str_new2(""); | 355 VALUE str = rb_str_new2(""); |
411 rb_enc_associate(str, kRubyString8bitEncoding); | 356 rb_enc_associate(str, kRubyString8bitEncoding); |
412 DEREF(msg, oneofdata->case_ofs, uint32_t) = | 357 DEREF(msg, oneofdata->case_ofs, uint32_t) = |
413 oneofdata->oneof_case_num; | 358 oneofdata->oneof_case_num; |
414 DEREF(msg, oneofdata->ofs, VALUE) = str; | 359 DEREF(msg, oneofdata->ofs, VALUE) = str; |
415 return (void*)str; | 360 return (void*)str; |
416 } | 361 } |
417 | 362 |
418 static bool oneofstring_end_handler(void* closure, const void* hd) { | |
419 MessageHeader* msg = closure; | |
420 const oneof_handlerdata_t *oneofdata = hd; | |
421 rb_obj_freeze(DEREF(msg, oneofdata->ofs, VALUE)); | |
422 return true; | |
423 } | |
424 | |
425 // Handler for a submessage field in a oneof. | 363 // Handler for a submessage field in a oneof. |
426 static void *oneofsubmsg_handler(void *closure, | 364 static void *oneofsubmsg_handler(void *closure, |
427 const void *hd) { | 365 const void *hd) { |
428 MessageHeader* msg = closure; | 366 MessageHeader* msg = closure; |
429 const oneof_handlerdata_t *oneofdata = hd; | 367 const oneof_handlerdata_t *oneofdata = hd; |
430 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); | 368 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); |
431 | 369 |
432 VALUE subdesc = | 370 VALUE subdesc = |
433 get_def_obj((void*)oneofdata->md); | 371 get_def_obj((void*)oneofdata->md); |
434 VALUE subklass = Descriptor_msgclass(subdesc); | 372 VALUE subklass = Descriptor_msgclass(subdesc); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 419 |
482 #undef SET_HANDLER | 420 #undef SET_HANDLER |
483 | 421 |
484 case UPB_TYPE_STRING: | 422 case UPB_TYPE_STRING: |
485 case UPB_TYPE_BYTES: { | 423 case UPB_TYPE_BYTES: { |
486 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 424 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
487 upb_handlers_setstartstr(h, f, is_bytes ? | 425 upb_handlers_setstartstr(h, f, is_bytes ? |
488 appendbytes_handler : appendstr_handler, | 426 appendbytes_handler : appendstr_handler, |
489 NULL); | 427 NULL); |
490 upb_handlers_setstring(h, f, stringdata_handler, NULL); | 428 upb_handlers_setstring(h, f, stringdata_handler, NULL); |
491 upb_handlers_setendstr(h, f, appendstring_end_handler, NULL); | |
492 break; | 429 break; |
493 } | 430 } |
494 case UPB_TYPE_MESSAGE: { | 431 case UPB_TYPE_MESSAGE: { |
495 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 432 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
496 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f)); | 433 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f)); |
497 upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); | 434 upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); |
498 upb_handlerattr_uninit(&attr); | 435 upb_handlerattr_uninit(&attr); |
499 break; | 436 break; |
500 } | 437 } |
501 } | 438 } |
(...skipping 16 matching lines...) Expand all Loading... |
518 break; | 455 break; |
519 case UPB_TYPE_STRING: | 456 case UPB_TYPE_STRING: |
520 case UPB_TYPE_BYTES: { | 457 case UPB_TYPE_BYTES: { |
521 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 458 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
522 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 459 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
523 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); | 460 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); |
524 upb_handlers_setstartstr(h, f, | 461 upb_handlers_setstartstr(h, f, |
525 is_bytes ? bytes_handler : str_handler, | 462 is_bytes ? bytes_handler : str_handler, |
526 &attr); | 463 &attr); |
527 upb_handlers_setstring(h, f, stringdata_handler, &attr); | 464 upb_handlers_setstring(h, f, stringdata_handler, &attr); |
528 upb_handlers_setendstr(h, f, stringdata_end_handler, &attr); | |
529 upb_handlerattr_uninit(&attr); | 465 upb_handlerattr_uninit(&attr); |
530 break; | 466 break; |
531 } | 467 } |
532 case UPB_TYPE_MESSAGE: { | 468 case UPB_TYPE_MESSAGE: { |
533 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 469 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
534 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f)); | 470 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f)); |
535 upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); | 471 upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); |
536 upb_handlerattr_uninit(&attr); | 472 upb_handlerattr_uninit(&attr); |
537 break; | 473 break; |
538 } | 474 } |
539 } | 475 } |
540 } | 476 } |
541 | 477 |
542 // Adds handlers to a map field. | 478 // Adds handlers to a map field. |
543 static void add_handlers_for_mapfield(upb_handlers* h, | 479 static void add_handlers_for_mapfield(upb_handlers* h, |
544 const upb_fielddef* fielddef, | 480 const upb_fielddef* fielddef, |
545 size_t offset, | 481 size_t offset, |
546 Descriptor* desc) { | 482 Descriptor* desc) { |
547 const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); | 483 const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); |
548 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); | 484 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); |
549 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 485 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
550 | 486 |
551 upb_handlers_addcleanup(h, hd, xfree); | 487 upb_handlers_addcleanup(h, hd, free); |
552 upb_handlerattr_sethandlerdata(&attr, hd); | 488 upb_handlerattr_sethandlerdata(&attr, hd); |
553 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); | 489 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); |
554 upb_handlerattr_uninit(&attr); | 490 upb_handlerattr_uninit(&attr); |
555 } | 491 } |
556 | 492 |
557 // Adds handlers to a map-entry msgdef. | 493 // Adds handlers to a map-entry msgdef. |
558 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, | 494 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
559 upb_handlers* h, | 495 upb_handlers* h, |
560 Descriptor* desc) { | 496 Descriptor* desc) { |
561 const upb_fielddef* key_field = map_entry_key(msgdef); | 497 const upb_fielddef* key_field = map_entry_key(msgdef); |
562 const upb_fielddef* value_field = map_entry_value(msgdef); | 498 const upb_fielddef* value_field = map_entry_value(msgdef); |
563 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); | 499 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); |
564 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 500 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
565 | 501 |
566 upb_handlers_addcleanup(h, hd, xfree); | 502 upb_handlers_addcleanup(h, hd, free); |
567 upb_handlerattr_sethandlerdata(&attr, hd); | 503 upb_handlerattr_sethandlerdata(&attr, hd); |
568 upb_handlers_setendmsg(h, endmap_handler, &attr); | 504 upb_handlers_setendmsg(h, endmap_handler, &attr); |
569 | 505 |
570 add_handlers_for_singular_field( | 506 add_handlers_for_singular_field( |
571 h, key_field, | 507 h, key_field, |
572 offsetof(map_parse_frame_t, key_storage)); | 508 offsetof(map_parse_frame_t, key_storage)); |
573 add_handlers_for_singular_field( | 509 add_handlers_for_singular_field( |
574 h, value_field, | 510 h, value_field, |
575 offsetof(map_parse_frame_t, value_storage)); | 511 offsetof(map_parse_frame_t, value_storage)); |
576 } | 512 } |
(...skipping 26 matching lines...) Expand all Loading... |
603 | 539 |
604 #undef SET_HANDLER | 540 #undef SET_HANDLER |
605 | 541 |
606 case UPB_TYPE_STRING: | 542 case UPB_TYPE_STRING: |
607 case UPB_TYPE_BYTES: { | 543 case UPB_TYPE_BYTES: { |
608 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 544 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
609 upb_handlers_setstartstr(h, f, is_bytes ? | 545 upb_handlers_setstartstr(h, f, is_bytes ? |
610 oneofbytes_handler : oneofstr_handler, | 546 oneofbytes_handler : oneofstr_handler, |
611 &attr); | 547 &attr); |
612 upb_handlers_setstring(h, f, stringdata_handler, NULL); | 548 upb_handlers_setstring(h, f, stringdata_handler, NULL); |
613 upb_handlers_setendstr(h, f, oneofstring_end_handler, &attr); | |
614 break; | 549 break; |
615 } | 550 } |
616 case UPB_TYPE_MESSAGE: { | 551 case UPB_TYPE_MESSAGE: { |
617 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); | 552 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); |
618 break; | 553 break; |
619 } | 554 } |
620 } | 555 } |
621 | 556 |
622 upb_handlerattr_uninit(&attr); | 557 upb_handlerattr_uninit(&attr); |
623 } | 558 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 VALUE msg_rb; | 703 VALUE msg_rb; |
769 MessageHeader* msg; | 704 MessageHeader* msg; |
770 | 705 |
771 if (TYPE(data) != T_STRING) { | 706 if (TYPE(data) != T_STRING) { |
772 rb_raise(rb_eArgError, "Expected string for binary protobuf data."); | 707 rb_raise(rb_eArgError, "Expected string for binary protobuf data."); |
773 } | 708 } |
774 | 709 |
775 msg_rb = rb_class_new_instance(0, NULL, msgklass); | 710 msg_rb = rb_class_new_instance(0, NULL, msgklass); |
776 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); | 711 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
777 | 712 |
778 // We generally expect this to be clear already, but clear it in case parsing | |
779 // previously got interrupted somehow. | |
780 rb_ary_clear(map_parse_frames); | |
781 | |
782 { | 713 { |
783 const upb_pbdecodermethod* method = msgdef_decodermethod(desc); | 714 const upb_pbdecodermethod* method = msgdef_decodermethod(desc); |
784 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); | 715 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); |
785 stackenv se; | 716 stackenv se; |
786 upb_sink sink; | 717 upb_sink sink; |
787 upb_pbdecoder* decoder; | 718 upb_pbdecoder* decoder; |
788 stackenv_init(&se, "Error occurred during parsing: %s"); | 719 stackenv_init(&se, "Error occurred during parsing: %s"); |
789 | 720 |
790 upb_sink_reset(&sink, h, msg); | 721 upb_sink_reset(&sink, h, msg); |
791 decoder = upb_pbdecoder_create(&se.env, method, &sink); | 722 decoder = upb_pbdecoder_create(&se.env, method, &sink); |
(...skipping 24 matching lines...) Expand all Loading... |
816 if (TYPE(data) != T_STRING) { | 747 if (TYPE(data) != T_STRING) { |
817 rb_raise(rb_eArgError, "Expected string for JSON data."); | 748 rb_raise(rb_eArgError, "Expected string for JSON data."); |
818 } | 749 } |
819 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to | 750 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to |
820 // convert, because string handlers pass data directly to message string | 751 // convert, because string handlers pass data directly to message string |
821 // fields. | 752 // fields. |
822 | 753 |
823 msg_rb = rb_class_new_instance(0, NULL, msgklass); | 754 msg_rb = rb_class_new_instance(0, NULL, msgklass); |
824 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); | 755 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
825 | 756 |
826 // We generally expect this to be clear already, but clear it in case parsing | |
827 // previously got interrupted somehow. | |
828 rb_ary_clear(map_parse_frames); | |
829 | |
830 { | 757 { |
831 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); | 758 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); |
832 stackenv se; | 759 stackenv se; |
833 upb_sink sink; | 760 upb_sink sink; |
834 upb_json_parser* parser; | 761 upb_json_parser* parser; |
835 stackenv_init(&se, "Error occurred during parsing: %s"); | 762 stackenv_init(&se, "Error occurred during parsing: %s"); |
836 | 763 |
837 upb_sink_reset(&sink, get_fill_handlers(desc), msg); | 764 upb_sink_reset(&sink, get_fill_handlers(desc), msg); |
838 parser = upb_json_parser_create(&se.env, method, &sink); | 765 parser = upb_json_parser_create(&se.env, method, &sink); |
839 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), | 766 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 return ret; | 856 return ret; |
930 } | 857 } |
931 | 858 |
932 static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { | 859 static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { |
933 upb_sink subsink; | 860 upb_sink subsink; |
934 | 861 |
935 if (str == Qnil) return; | 862 if (str == Qnil) return; |
936 | 863 |
937 assert(BUILTIN_TYPE(str) == RUBY_T_STRING); | 864 assert(BUILTIN_TYPE(str) == RUBY_T_STRING); |
938 | 865 |
939 // We should be guaranteed that the string has the correct encoding because | 866 // Ensure that the string has the correct encoding. We also check at field-set |
940 // we ensured this at assignment time and then froze the string. | 867 // time, but the user may have mutated the string object since then. |
941 if (upb_fielddef_type(f) == UPB_TYPE_STRING) { | 868 native_slot_validate_string_encoding(upb_fielddef_type(f), str); |
942 assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyStringUtf8Encoding); | |
943 } else { | |
944 assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyString8bitEncoding); | |
945 } | |
946 | 869 |
947 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), | 870 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), |
948 &subsink); | 871 &subsink); |
949 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str), | 872 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str), |
950 RSTRING_LEN(str), NULL); | 873 RSTRING_LEN(str), NULL); |
951 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); | 874 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); |
952 } | 875 } |
953 | 876 |
954 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, | 877 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, |
955 int depth) { | 878 int depth) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 | 1224 |
1302 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding()); | 1225 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding()); |
1303 | 1226 |
1304 stackenv_uninit(&se); | 1227 stackenv_uninit(&se); |
1305 stringsink_uninit(&sink); | 1228 stringsink_uninit(&sink); |
1306 | 1229 |
1307 return ret; | 1230 return ret; |
1308 } | 1231 } |
1309 } | 1232 } |
1310 | 1233 |
OLD | NEW |