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

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

Issue 2599263002: third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Address comments Created 3 years, 12 months 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 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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/protobuf/ruby/Rakefile ('k') | third_party/protobuf/ruby/ext/google/protobuf_c/map.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698