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, free); | 57 upb_handlers_addcleanup(h, hd_ofs, xfree); |
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, free); | 72 upb_handlers_addcleanup(h, hd, xfree); |
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, free); | 102 upb_handlers_addcleanup(h, hd, xfree); |
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(ary, str); | 138 RepeatedField_push_native(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(ary, str); | 149 RepeatedField_push_native(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 |
185 // Appends a submessage to a repeated field (a regular Ruby array for now). | 202 // Appends a submessage to a repeated field (a regular Ruby array for now). |
186 static void *appendsubmsg_handler(void *closure, const void *hd) { | 203 static void *appendsubmsg_handler(void *closure, const void *hd) { |
187 VALUE ary = (VALUE)closure; | 204 VALUE ary = (VALUE)closure; |
188 const submsg_handlerdata_t *submsgdata = hd; | 205 const submsg_handlerdata_t *submsgdata = hd; |
189 VALUE subdesc = | 206 VALUE subdesc = |
190 get_def_obj((void*)submsgdata->md); | 207 get_def_obj((void*)submsgdata->md); |
191 VALUE subklass = Descriptor_msgclass(subdesc); | 208 VALUE subklass = Descriptor_msgclass(subdesc); |
192 MessageHeader* submsg; | 209 MessageHeader* submsg; |
193 | 210 |
194 VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); | 211 VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 } map_handlerdata_t; | 248 } map_handlerdata_t; |
232 | 249 |
233 // Temporary frame for map parsing: at the beginning of a map entry message, a | 250 // 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 | 251 // 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 | 252 // 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 | 253 // 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 | 254 // submessage. When the submessage ends, another handler is called to insert the |
238 // value into the map. | 255 // value into the map. |
239 typedef struct { | 256 typedef struct { |
240 VALUE map; | 257 VALUE map; |
| 258 const map_handlerdata_t* handlerdata; |
241 char key_storage[NATIVE_SLOT_MAX_SIZE]; | 259 char key_storage[NATIVE_SLOT_MAX_SIZE]; |
242 char value_storage[NATIVE_SLOT_MAX_SIZE]; | 260 char value_storage[NATIVE_SLOT_MAX_SIZE]; |
243 } map_parse_frame_t; | 261 } map_parse_frame_t; |
244 | 262 |
| 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 |
245 // Handler to begin a map entry: allocates a temporary frame. This is the | 306 // Handler to begin a map entry: allocates a temporary frame. This is the |
246 // 'startsubmsg' handler on the msgdef that contains the map field. | 307 // 'startsubmsg' handler on the msgdef that contains the map field. |
247 static void *startmapentry_handler(void *closure, const void *hd) { | 308 static void *startmapentry_handler(void *closure, const void *hd) { |
248 MessageHeader* msg = closure; | 309 MessageHeader* msg = closure; |
249 const map_handlerdata_t* mapdata = hd; | 310 const map_handlerdata_t* mapdata = hd; |
250 VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); | 311 VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); |
251 | 312 |
252 map_parse_frame_t* frame = ALLOC(map_parse_frame_t); | 313 return map_push_frame(map_rb, mapdata); |
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; | |
259 } | 314 } |
260 | 315 |
261 // Handler to end a map entry: inserts the value defined during the message into | 316 // 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. | 317 // 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) { | 318 static bool endmap_handler(void *closure, const void *hd, upb_status* s) { |
264 map_parse_frame_t* frame = closure; | 319 map_parse_frame_t* frame = closure; |
265 const map_handlerdata_t* mapdata = hd; | 320 const map_handlerdata_t* mapdata = hd; |
266 | 321 |
267 VALUE key = native_slot_get( | 322 VALUE key = native_slot_get( |
268 mapdata->key_field_type, Qnil, | 323 mapdata->key_field_type, Qnil, |
269 &frame->key_storage); | 324 &frame->key_storage); |
270 | 325 |
271 VALUE value_field_typeclass = Qnil; | 326 VALUE value_field_typeclass = Qnil; |
272 VALUE value; | 327 VALUE value; |
273 | 328 |
274 if (mapdata->value_field_type == UPB_TYPE_MESSAGE || | 329 if (mapdata->value_field_type == UPB_TYPE_MESSAGE || |
275 mapdata->value_field_type == UPB_TYPE_ENUM) { | 330 mapdata->value_field_type == UPB_TYPE_ENUM) { |
276 value_field_typeclass = get_def_obj(mapdata->value_field_subdef); | 331 value_field_typeclass = get_def_obj(mapdata->value_field_subdef); |
277 } | 332 } |
278 | 333 |
279 value = native_slot_get( | 334 value = native_slot_get( |
280 mapdata->value_field_type, value_field_typeclass, | 335 mapdata->value_field_type, value_field_typeclass, |
281 &frame->value_storage); | 336 &frame->value_storage); |
282 | 337 |
283 Map_index_set(frame->map, key, value); | 338 Map_index_set(frame->map, key, value); |
284 free(frame); | 339 map_pop_frame(); |
285 | 340 |
286 return true; | 341 return true; |
287 } | 342 } |
288 | 343 |
289 // Allocates a new map_handlerdata_t given the map entry message definition. If | 344 // 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 | 345 // 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 | 346 // 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 | 347 // 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 | 348 // 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 | 349 // 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... |
353 MessageHeader* msg = closure; | 408 MessageHeader* msg = closure; |
354 const oneof_handlerdata_t *oneofdata = hd; | 409 const oneof_handlerdata_t *oneofdata = hd; |
355 VALUE str = rb_str_new2(""); | 410 VALUE str = rb_str_new2(""); |
356 rb_enc_associate(str, kRubyString8bitEncoding); | 411 rb_enc_associate(str, kRubyString8bitEncoding); |
357 DEREF(msg, oneofdata->case_ofs, uint32_t) = | 412 DEREF(msg, oneofdata->case_ofs, uint32_t) = |
358 oneofdata->oneof_case_num; | 413 oneofdata->oneof_case_num; |
359 DEREF(msg, oneofdata->ofs, VALUE) = str; | 414 DEREF(msg, oneofdata->ofs, VALUE) = str; |
360 return (void*)str; | 415 return (void*)str; |
361 } | 416 } |
362 | 417 |
| 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 |
363 // Handler for a submessage field in a oneof. | 425 // Handler for a submessage field in a oneof. |
364 static void *oneofsubmsg_handler(void *closure, | 426 static void *oneofsubmsg_handler(void *closure, |
365 const void *hd) { | 427 const void *hd) { |
366 MessageHeader* msg = closure; | 428 MessageHeader* msg = closure; |
367 const oneof_handlerdata_t *oneofdata = hd; | 429 const oneof_handlerdata_t *oneofdata = hd; |
368 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); | 430 uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); |
369 | 431 |
370 VALUE subdesc = | 432 VALUE subdesc = |
371 get_def_obj((void*)oneofdata->md); | 433 get_def_obj((void*)oneofdata->md); |
372 VALUE subklass = Descriptor_msgclass(subdesc); | 434 VALUE subklass = Descriptor_msgclass(subdesc); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 | 481 |
420 #undef SET_HANDLER | 482 #undef SET_HANDLER |
421 | 483 |
422 case UPB_TYPE_STRING: | 484 case UPB_TYPE_STRING: |
423 case UPB_TYPE_BYTES: { | 485 case UPB_TYPE_BYTES: { |
424 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 486 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
425 upb_handlers_setstartstr(h, f, is_bytes ? | 487 upb_handlers_setstartstr(h, f, is_bytes ? |
426 appendbytes_handler : appendstr_handler, | 488 appendbytes_handler : appendstr_handler, |
427 NULL); | 489 NULL); |
428 upb_handlers_setstring(h, f, stringdata_handler, NULL); | 490 upb_handlers_setstring(h, f, stringdata_handler, NULL); |
| 491 upb_handlers_setendstr(h, f, appendstring_end_handler, NULL); |
429 break; | 492 break; |
430 } | 493 } |
431 case UPB_TYPE_MESSAGE: { | 494 case UPB_TYPE_MESSAGE: { |
432 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 495 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
433 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f)); | 496 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f)); |
434 upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); | 497 upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); |
435 upb_handlerattr_uninit(&attr); | 498 upb_handlerattr_uninit(&attr); |
436 break; | 499 break; |
437 } | 500 } |
438 } | 501 } |
(...skipping 16 matching lines...) Expand all Loading... |
455 break; | 518 break; |
456 case UPB_TYPE_STRING: | 519 case UPB_TYPE_STRING: |
457 case UPB_TYPE_BYTES: { | 520 case UPB_TYPE_BYTES: { |
458 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 521 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
459 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 522 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
460 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); | 523 upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); |
461 upb_handlers_setstartstr(h, f, | 524 upb_handlers_setstartstr(h, f, |
462 is_bytes ? bytes_handler : str_handler, | 525 is_bytes ? bytes_handler : str_handler, |
463 &attr); | 526 &attr); |
464 upb_handlers_setstring(h, f, stringdata_handler, &attr); | 527 upb_handlers_setstring(h, f, stringdata_handler, &attr); |
| 528 upb_handlers_setendstr(h, f, stringdata_end_handler, &attr); |
465 upb_handlerattr_uninit(&attr); | 529 upb_handlerattr_uninit(&attr); |
466 break; | 530 break; |
467 } | 531 } |
468 case UPB_TYPE_MESSAGE: { | 532 case UPB_TYPE_MESSAGE: { |
469 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 533 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
470 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f)); | 534 upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f)); |
471 upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); | 535 upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); |
472 upb_handlerattr_uninit(&attr); | 536 upb_handlerattr_uninit(&attr); |
473 break; | 537 break; |
474 } | 538 } |
475 } | 539 } |
476 } | 540 } |
477 | 541 |
478 // Adds handlers to a map field. | 542 // Adds handlers to a map field. |
479 static void add_handlers_for_mapfield(upb_handlers* h, | 543 static void add_handlers_for_mapfield(upb_handlers* h, |
480 const upb_fielddef* fielddef, | 544 const upb_fielddef* fielddef, |
481 size_t offset, | 545 size_t offset, |
482 Descriptor* desc) { | 546 Descriptor* desc) { |
483 const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); | 547 const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); |
484 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); | 548 map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc); |
485 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 549 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
486 | 550 |
487 upb_handlers_addcleanup(h, hd, free); | 551 upb_handlers_addcleanup(h, hd, xfree); |
488 upb_handlerattr_sethandlerdata(&attr, hd); | 552 upb_handlerattr_sethandlerdata(&attr, hd); |
489 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); | 553 upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); |
490 upb_handlerattr_uninit(&attr); | 554 upb_handlerattr_uninit(&attr); |
491 } | 555 } |
492 | 556 |
493 // Adds handlers to a map-entry msgdef. | 557 // Adds handlers to a map-entry msgdef. |
494 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, | 558 static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
495 upb_handlers* h, | 559 upb_handlers* h, |
496 Descriptor* desc) { | 560 Descriptor* desc) { |
497 const upb_fielddef* key_field = map_entry_key(msgdef); | 561 const upb_fielddef* key_field = map_entry_key(msgdef); |
498 const upb_fielddef* value_field = map_entry_value(msgdef); | 562 const upb_fielddef* value_field = map_entry_value(msgdef); |
499 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); | 563 map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc); |
500 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; | 564 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
501 | 565 |
502 upb_handlers_addcleanup(h, hd, free); | 566 upb_handlers_addcleanup(h, hd, xfree); |
503 upb_handlerattr_sethandlerdata(&attr, hd); | 567 upb_handlerattr_sethandlerdata(&attr, hd); |
504 upb_handlers_setendmsg(h, endmap_handler, &attr); | 568 upb_handlers_setendmsg(h, endmap_handler, &attr); |
505 | 569 |
506 add_handlers_for_singular_field( | 570 add_handlers_for_singular_field( |
507 h, key_field, | 571 h, key_field, |
508 offsetof(map_parse_frame_t, key_storage)); | 572 offsetof(map_parse_frame_t, key_storage)); |
509 add_handlers_for_singular_field( | 573 add_handlers_for_singular_field( |
510 h, value_field, | 574 h, value_field, |
511 offsetof(map_parse_frame_t, value_storage)); | 575 offsetof(map_parse_frame_t, value_storage)); |
512 } | 576 } |
(...skipping 26 matching lines...) Expand all Loading... |
539 | 603 |
540 #undef SET_HANDLER | 604 #undef SET_HANDLER |
541 | 605 |
542 case UPB_TYPE_STRING: | 606 case UPB_TYPE_STRING: |
543 case UPB_TYPE_BYTES: { | 607 case UPB_TYPE_BYTES: { |
544 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; | 608 bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; |
545 upb_handlers_setstartstr(h, f, is_bytes ? | 609 upb_handlers_setstartstr(h, f, is_bytes ? |
546 oneofbytes_handler : oneofstr_handler, | 610 oneofbytes_handler : oneofstr_handler, |
547 &attr); | 611 &attr); |
548 upb_handlers_setstring(h, f, stringdata_handler, NULL); | 612 upb_handlers_setstring(h, f, stringdata_handler, NULL); |
| 613 upb_handlers_setendstr(h, f, oneofstring_end_handler, &attr); |
549 break; | 614 break; |
550 } | 615 } |
551 case UPB_TYPE_MESSAGE: { | 616 case UPB_TYPE_MESSAGE: { |
552 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); | 617 upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); |
553 break; | 618 break; |
554 } | 619 } |
555 } | 620 } |
556 | 621 |
557 upb_handlerattr_uninit(&attr); | 622 upb_handlerattr_uninit(&attr); |
558 } | 623 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 VALUE msg_rb; | 768 VALUE msg_rb; |
704 MessageHeader* msg; | 769 MessageHeader* msg; |
705 | 770 |
706 if (TYPE(data) != T_STRING) { | 771 if (TYPE(data) != T_STRING) { |
707 rb_raise(rb_eArgError, "Expected string for binary protobuf data."); | 772 rb_raise(rb_eArgError, "Expected string for binary protobuf data."); |
708 } | 773 } |
709 | 774 |
710 msg_rb = rb_class_new_instance(0, NULL, msgklass); | 775 msg_rb = rb_class_new_instance(0, NULL, msgklass); |
711 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); | 776 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
712 | 777 |
| 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 |
713 { | 782 { |
714 const upb_pbdecodermethod* method = msgdef_decodermethod(desc); | 783 const upb_pbdecodermethod* method = msgdef_decodermethod(desc); |
715 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); | 784 const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); |
716 stackenv se; | 785 stackenv se; |
717 upb_sink sink; | 786 upb_sink sink; |
718 upb_pbdecoder* decoder; | 787 upb_pbdecoder* decoder; |
719 stackenv_init(&se, "Error occurred during parsing: %s"); | 788 stackenv_init(&se, "Error occurred during parsing: %s"); |
720 | 789 |
721 upb_sink_reset(&sink, h, msg); | 790 upb_sink_reset(&sink, h, msg); |
722 decoder = upb_pbdecoder_create(&se.env, method, &sink); | 791 decoder = upb_pbdecoder_create(&se.env, method, &sink); |
(...skipping 24 matching lines...) Expand all Loading... |
747 if (TYPE(data) != T_STRING) { | 816 if (TYPE(data) != T_STRING) { |
748 rb_raise(rb_eArgError, "Expected string for JSON data."); | 817 rb_raise(rb_eArgError, "Expected string for JSON data."); |
749 } | 818 } |
750 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to | 819 // 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 | 820 // convert, because string handlers pass data directly to message string |
752 // fields. | 821 // fields. |
753 | 822 |
754 msg_rb = rb_class_new_instance(0, NULL, msgklass); | 823 msg_rb = rb_class_new_instance(0, NULL, msgklass); |
755 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); | 824 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); |
756 | 825 |
| 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 |
757 { | 830 { |
758 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); | 831 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); |
759 stackenv se; | 832 stackenv se; |
760 upb_sink sink; | 833 upb_sink sink; |
761 upb_json_parser* parser; | 834 upb_json_parser* parser; |
762 stackenv_init(&se, "Error occurred during parsing: %s"); | 835 stackenv_init(&se, "Error occurred during parsing: %s"); |
763 | 836 |
764 upb_sink_reset(&sink, get_fill_handlers(desc), msg); | 837 upb_sink_reset(&sink, get_fill_handlers(desc), msg); |
765 parser = upb_json_parser_create(&se.env, method, &sink); | 838 parser = upb_json_parser_create(&se.env, method, &sink); |
766 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), | 839 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 return ret; | 929 return ret; |
857 } | 930 } |
858 | 931 |
859 static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { | 932 static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) { |
860 upb_sink subsink; | 933 upb_sink subsink; |
861 | 934 |
862 if (str == Qnil) return; | 935 if (str == Qnil) return; |
863 | 936 |
864 assert(BUILTIN_TYPE(str) == RUBY_T_STRING); | 937 assert(BUILTIN_TYPE(str) == RUBY_T_STRING); |
865 | 938 |
866 // Ensure that the string has the correct encoding. We also check at field-set | 939 // We should be guaranteed that the string has the correct encoding because |
867 // time, but the user may have mutated the string object since then. | 940 // we ensured this at assignment time and then froze the string. |
868 native_slot_validate_string_encoding(upb_fielddef_type(f), str); | 941 if (upb_fielddef_type(f) == UPB_TYPE_STRING) { |
| 942 assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyStringUtf8Encoding); |
| 943 } else { |
| 944 assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyString8bitEncoding); |
| 945 } |
869 | 946 |
870 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), | 947 upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str), |
871 &subsink); | 948 &subsink); |
872 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str), | 949 upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str), |
873 RSTRING_LEN(str), NULL); | 950 RSTRING_LEN(str), NULL); |
874 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); | 951 upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); |
875 } | 952 } |
876 | 953 |
877 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, | 954 static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink, |
878 int depth) { | 955 int depth) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 | 1301 |
1225 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding()); | 1302 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding()); |
1226 | 1303 |
1227 stackenv_uninit(&se); | 1304 stackenv_uninit(&se); |
1228 stringsink_uninit(&sink); | 1305 stringsink_uninit(&sink); |
1229 | 1306 |
1230 return ret; | 1307 return ret; |
1231 } | 1308 } |
1232 } | 1309 } |
1233 | 1310 |
OLD | NEW |