| 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 |