|
|
|
@ -177,8 +177,8 @@ static void *submsg_handler(void *closure, const void *hd) { |
|
|
|
|
// Handler data for startmap/endmap handlers.
|
|
|
|
|
typedef struct { |
|
|
|
|
size_t ofs; |
|
|
|
|
const upb_fielddef* key_field; |
|
|
|
|
const upb_fielddef* value_field; |
|
|
|
|
upb_fieldtype_t key_field_type; |
|
|
|
|
upb_fieldtype_t value_field_type; |
|
|
|
|
VALUE value_field_typeclass; |
|
|
|
|
} map_handlerdata_t; |
|
|
|
|
|
|
|
|
@ -194,12 +194,6 @@ typedef struct { |
|
|
|
|
char value_storage[NATIVE_SLOT_MAX_SIZE]; |
|
|
|
|
} map_parse_frame_t; |
|
|
|
|
|
|
|
|
|
// Handler to begin a sequence of map entries: simple no-op that exists only to
|
|
|
|
|
// set context for the map entry handlers.
|
|
|
|
|
static void *startmap_handler(void *closure, const void *hd) { |
|
|
|
|
return closure; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Handler to begin a map entry: allocates a temporary frame. This is the
|
|
|
|
|
// 'startsubmsg' handler on the msgdef that contains the map field.
|
|
|
|
|
static void *startmapentry_handler(void *closure, const void *hd) { |
|
|
|
@ -210,10 +204,8 @@ static void *startmapentry_handler(void *closure, const void *hd) { |
|
|
|
|
map_parse_frame_t* frame = ALLOC(map_parse_frame_t); |
|
|
|
|
frame->map = map_rb; |
|
|
|
|
|
|
|
|
|
native_slot_init(upb_fielddef_type(mapdata->key_field), |
|
|
|
|
&frame->key_storage); |
|
|
|
|
native_slot_init(upb_fielddef_type(mapdata->value_field), |
|
|
|
|
&frame->value_storage); |
|
|
|
|
native_slot_init(mapdata->key_field_type, &frame->key_storage); |
|
|
|
|
native_slot_init(mapdata->value_field_type, &frame->value_storage); |
|
|
|
|
|
|
|
|
|
return frame; |
|
|
|
|
} |
|
|
|
@ -225,10 +217,10 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) { |
|
|
|
|
const map_handlerdata_t* mapdata = hd; |
|
|
|
|
|
|
|
|
|
VALUE key = native_slot_get( |
|
|
|
|
upb_fielddef_type(mapdata->key_field), Qnil, |
|
|
|
|
mapdata->key_field_type, Qnil, |
|
|
|
|
&frame->key_storage); |
|
|
|
|
VALUE value = native_slot_get( |
|
|
|
|
upb_fielddef_type(mapdata->value_field), mapdata->value_field_typeclass, |
|
|
|
|
mapdata->value_field_type, mapdata->value_field_typeclass, |
|
|
|
|
&frame->value_storage); |
|
|
|
|
|
|
|
|
|
Map_index_set(frame->map, key, value); |
|
|
|
@ -250,11 +242,15 @@ static map_handlerdata_t* new_map_handlerdata( |
|
|
|
|
|
|
|
|
|
map_handlerdata_t* hd = ALLOC(map_handlerdata_t); |
|
|
|
|
hd->ofs = ofs; |
|
|
|
|
hd->key_field = upb_msgdef_itof(mapentry_def, 1); |
|
|
|
|
assert(hd->key_field != NULL); |
|
|
|
|
hd->value_field = upb_msgdef_itof(mapentry_def, 2); |
|
|
|
|
assert(hd->value_field != NULL); |
|
|
|
|
hd->value_field_typeclass = field_type_class(hd->value_field); |
|
|
|
|
const upb_fielddef* key_field = upb_msgdef_itof(mapentry_def, |
|
|
|
|
MAP_KEY_FIELD); |
|
|
|
|
assert(key_field != NULL); |
|
|
|
|
hd->key_field_type = upb_fielddef_type(key_field); |
|
|
|
|
const upb_fielddef* value_field = upb_msgdef_itof(mapentry_def, |
|
|
|
|
MAP_VALUE_FIELD); |
|
|
|
|
assert(value_field != NULL); |
|
|
|
|
hd->value_field_type = upb_fielddef_type(value_field); |
|
|
|
|
hd->value_field_typeclass = field_type_class(value_field); |
|
|
|
|
|
|
|
|
|
return hd; |
|
|
|
|
} |
|
|
|
@ -293,6 +289,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h, |
|
|
|
|
appendbytes_handler : appendstr_handler, |
|
|
|
|
NULL); |
|
|
|
|
upb_handlers_setstring(h, f, stringdata_handler, NULL); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case UPB_TYPE_MESSAGE: { |
|
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
|
|
@ -352,7 +349,6 @@ static void add_handlers_for_mapfield(upb_handlers* h, |
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
|
|
|
upb_handlerattr_sethandlerdata(&attr, hd); |
|
|
|
|
upb_handlers_setstartseq(h, fielddef, startmap_handler, &attr); |
|
|
|
|
upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); |
|
|
|
|
upb_handlerattr_uninit(&attr); |
|
|
|
|
} |
|
|
|
@ -360,6 +356,8 @@ static void add_handlers_for_mapfield(upb_handlers* h, |
|
|
|
|
// Adds handlers to a map-entry msgdef.
|
|
|
|
|
static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
|
|
|
|
upb_handlers* h) { |
|
|
|
|
const upb_fielddef* key_field = map_entry_key(msgdef); |
|
|
|
|
const upb_fielddef* value_field = map_entry_value(msgdef); |
|
|
|
|
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef); |
|
|
|
|
upb_handlers_addcleanup(h, hd, free); |
|
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
|
|
@ -367,7 +365,7 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
|
|
|
|
upb_handlers_setendmsg(h, endmap_handler, &attr); |
|
|
|
|
|
|
|
|
|
add_handlers_for_singular_field( |
|
|
|
|
h, hd->key_field, |
|
|
|
|
h, key_field, |
|
|
|
|
// Convert the offset into map_parse_frame_t to an offset understood by the
|
|
|
|
|
// singular field handlers, so that we don't have to use special
|
|
|
|
|
// map-key/value-specific handlers. The ordinary singular field handlers expect
|
|
|
|
@ -375,7 +373,7 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, |
|
|
|
|
// we compensate for that addition.
|
|
|
|
|
offsetof(map_parse_frame_t, key_storage) - sizeof(MessageHeader)); |
|
|
|
|
add_handlers_for_singular_field( |
|
|
|
|
h, hd->value_field, |
|
|
|
|
h, value_field, |
|
|
|
|
offsetof(map_parse_frame_t, value_storage) - sizeof(MessageHeader)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|