size_t mcnet_slot_parser_parse(mcnet_slot_parser_t* parser, uint8_t* data, size_t len) { mcnet_slot_t slot; size_t nparsed = 0; slot.item = 0; slot.count = 0; slot.meta = 0; slot.data_len = 0; slot.data = NULL; if (len < nparsed + 2) { return MCNET_EAGAIN; } slot.item = mcnet_read_int16(data + nparsed); nparsed += 2; if (slot.item == -1) { if (parser && parser->on_complete) { parser->on_complete(parser, &slot); } return nparsed; } if (len < nparsed + 3) { return MCNET_EAGAIN; } slot.count = mcnet_read_int8(data + nparsed); nparsed += 1; slot.meta = mcnet_read_int16(data + nparsed); nparsed += 2; if (!((slot.item == 256) || (slot.item == 257) || (slot.item == 258) || (slot.item == 259) || (slot.item == 261) || (slot.item == 267) || (slot.item == 268) || (slot.item == 269) || (slot.item == 270) || (slot.item == 271) || (slot.item == 272) || (slot.item == 273) || (slot.item == 274) || (slot.item == 275) || (slot.item == 276) || (slot.item == 277) || (slot.item == 278) || (slot.item == 279) || (slot.item == 283) || (slot.item == 284) || (slot.item == 285) || (slot.item == 286) || (slot.item == 290) || (slot.item == 291) || (slot.item == 292) || (slot.item == 293) || (slot.item == 294) || (slot.item == 298) || (slot.item == 299) || (slot.item == 300) || (slot.item == 301) || (slot.item == 302) || (slot.item == 303) || (slot.item == 304) || (slot.item == 305) || (slot.item == 306) || (slot.item == 307) || (slot.item == 308) || (slot.item == 309) || (slot.item == 310) || (slot.item == 311) || (slot.item == 312) || (slot.item == 313) || (slot.item == 314) || (slot.item == 315) || (slot.item == 316) || (slot.item == 317) || (slot.item == 346) || (slot.item == 359))) { if (parser && parser->on_complete) { parser->on_complete(parser, &slot); } return nparsed; } if (len < nparsed + 2) { return MCNET_EAGAIN; } slot.data_len = mcnet_read_int16(data + nparsed); nparsed += 2; if (slot.data_len != -1) { if (len < nparsed + slot.data_len) { return MCNET_EAGAIN; } slot.data = data + nparsed; nparsed += slot.data_len; } if (parser && parser->on_complete) { parser->on_complete(parser, &slot); } return nparsed; }
size_t mcnet_metadata_parser_execute(mcnet_metadata_parser_t* parser, uint8_t* data, size_t len) { size_t nparsed = 0; if (len < nparsed + 1) { return MCNET_EAGAIN; } uint8_t x = *(data + nparsed); nparsed += 1; if (x == 127) { return nparsed; } uint8_t index = x & 0x1F, type = x >> 5; switch (type) { case MCNET_METADATA_TYPE_BYTE: { mcnet_metadata_entry_byte_t entry; entry.type = type; entry.index = index; if (len < nparsed + 1) { return MCNET_EAGAIN; } entry.data = mcnet_read_int8(data + nparsed); nparsed += 1; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_SHORT: { mcnet_metadata_entry_short_t entry; entry.type = type; entry.index = index; if (len < nparsed + 2) { return MCNET_EAGAIN; } entry.data = mcnet_read_int16(data + nparsed); nparsed += 2; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_INT: { mcnet_metadata_entry_int_t entry; entry.type = type; entry.index = index; if (len < nparsed + 4) { return MCNET_EAGAIN; } entry.data = mcnet_read_int32(data + nparsed); nparsed += 4; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_FLOAT: { mcnet_metadata_entry_float_t entry; entry.type = type; entry.index = index; if (len < nparsed + 4) { return MCNET_EAGAIN; } entry.data = mcnet_read_float(data + nparsed); nparsed += 4; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_STRING16: { mcnet_metadata_entry_string16_t entry; entry.type = type; entry.index = index; if (len < nparsed + 2) { return MCNET_EAGAIN; } entry.data_length = mcnet_read_int16(data + nparsed); nparsed += 2; if (len < nparsed + entry.data_length * 2) { return MCNET_EAGAIN; } entry.data = data + nparsed; nparsed += entry.data_length * 2; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_SLOT: { mcnet_metadata_entry_sbs_t entry; entry.type = type; entry.index = index; if (len < nparsed + 5) { return MCNET_EAGAIN; } entry.id = mcnet_read_int16(data + nparsed); nparsed += 2; entry.count = mcnet_read_int8(data + nparsed); nparsed += 1; entry.damage = mcnet_read_int16(data + nparsed); nparsed += 2; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } case MCNET_METADATA_TYPE_INTS: { mcnet_metadata_entry_iii_t entry; entry.type = type; entry.index = index; if (len < nparsed + 12) { return MCNET_EAGAIN; } entry.data[0] = mcnet_read_int32(data + nparsed); nparsed += 4; entry.data[1] = mcnet_read_int32(data + nparsed); nparsed += 4; entry.data[2] = mcnet_read_int32(data + nparsed); nparsed += 4; if (parser && parser->on_entry) { parser->on_entry(parser, (mcnet_metadata_entry_t*)&entry); } return nparsed; } default: { if (parser && parser->on_error) { parser->on_error(parser, MCNET_EINVALID); } return MCNET_EINVALID; } } }