This commit is contained in:
J. Nick Koston 2025-07-10 15:51:13 -10:00
parent e4ea6c5eee
commit 084ecf93a7
No known key found for this signature in database

View File

@ -215,36 +215,8 @@ static void calculate_field_size(uint32_t &total_size, ProtoFieldType type, uint
} }
} }
// For decode, we still need separate functions because we're pushing to vectors vs assigning // Decode varint for single fields
static bool decode_varint_field(ProtoFieldType type, void *field_addr, const ProtoVarInt &value, bool is_repeated) { static bool decode_varint_field(ProtoFieldType type, void *field_addr, const ProtoVarInt &value) {
if (is_repeated) {
switch (type) {
case ProtoFieldType::TYPE_BOOL:
static_cast<std::vector<bool> *>(field_addr)->push_back(value.as_bool());
return true;
case ProtoFieldType::TYPE_INT32:
static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_int32());
return true;
case ProtoFieldType::TYPE_UINT32:
case ProtoFieldType::TYPE_ENUM:
static_cast<std::vector<uint32_t> *>(field_addr)->push_back(value.as_uint32());
return true;
case ProtoFieldType::TYPE_INT64:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_int64());
return true;
case ProtoFieldType::TYPE_UINT64:
static_cast<std::vector<uint64_t> *>(field_addr)->push_back(value.as_uint64());
return true;
case ProtoFieldType::TYPE_SINT32:
static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_sint32());
return true;
case ProtoFieldType::TYPE_SINT64:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_sint64());
return true;
default:
return false;
}
} else {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_BOOL: case ProtoFieldType::TYPE_BOOL:
*static_cast<bool *>(field_addr) = value.as_bool(); *static_cast<bool *>(field_addr) = value.as_bool();
@ -271,26 +243,40 @@ static bool decode_varint_field(ProtoFieldType type, void *field_addr, const Pro
default: default:
return false; return false;
} }
}
} }
// Decode for 32-bit fields // Decode varint for repeated fields
static bool decode_32bit_field(ProtoFieldType type, void *field_addr, const Proto32Bit &value, bool is_repeated) { static bool decode_repeated_varint_field(ProtoFieldType type, void *field_addr, const ProtoVarInt &value) {
if (is_repeated) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_FLOAT: case ProtoFieldType::TYPE_BOOL:
static_cast<std::vector<float> *>(field_addr)->push_back(value.as_float()); static_cast<std::vector<bool> *>(field_addr)->push_back(value.as_bool());
return true; return true;
case ProtoFieldType::TYPE_FIXED32: case ProtoFieldType::TYPE_INT32:
static_cast<std::vector<uint32_t> *>(field_addr)->push_back(value.as_fixed32()); static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_int32());
return true; return true;
case ProtoFieldType::TYPE_SFIXED32: case ProtoFieldType::TYPE_UINT32:
static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_sfixed32()); case ProtoFieldType::TYPE_ENUM:
static_cast<std::vector<uint32_t> *>(field_addr)->push_back(value.as_uint32());
return true;
case ProtoFieldType::TYPE_INT64:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_int64());
return true;
case ProtoFieldType::TYPE_UINT64:
static_cast<std::vector<uint64_t> *>(field_addr)->push_back(value.as_uint64());
return true;
case ProtoFieldType::TYPE_SINT32:
static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_sint32());
return true;
case ProtoFieldType::TYPE_SINT64:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_sint64());
return true; return true;
default: default:
return false; return false;
} }
} else { }
// Decode 32-bit for single fields
static bool decode_32bit_field(ProtoFieldType type, void *field_addr, const Proto32Bit &value) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_FLOAT: case ProtoFieldType::TYPE_FLOAT:
*static_cast<float *>(field_addr) = value.as_float(); *static_cast<float *>(field_addr) = value.as_float();
@ -304,26 +290,27 @@ static bool decode_32bit_field(ProtoFieldType type, void *field_addr, const Prot
default: default:
return false; return false;
} }
}
} }
// Decode for 64-bit fields // Decode 32-bit for repeated fields
static bool decode_64bit_field(ProtoFieldType type, void *field_addr, const Proto64Bit &value, bool is_repeated) { static bool decode_repeated_32bit_field(ProtoFieldType type, void *field_addr, const Proto32Bit &value) {
if (is_repeated) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_DOUBLE: case ProtoFieldType::TYPE_FLOAT:
static_cast<std::vector<double> *>(field_addr)->push_back(value.as_double()); static_cast<std::vector<float> *>(field_addr)->push_back(value.as_float());
return true; return true;
case ProtoFieldType::TYPE_FIXED64: case ProtoFieldType::TYPE_FIXED32:
static_cast<std::vector<uint64_t> *>(field_addr)->push_back(value.as_fixed64()); static_cast<std::vector<uint32_t> *>(field_addr)->push_back(value.as_fixed32());
return true; return true;
case ProtoFieldType::TYPE_SFIXED64: case ProtoFieldType::TYPE_SFIXED32:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_sfixed64()); static_cast<std::vector<int32_t> *>(field_addr)->push_back(value.as_sfixed32());
return true; return true;
default: default:
return false; return false;
} }
} else { }
// Decode 64-bit for single fields
static bool decode_64bit_field(ProtoFieldType type, void *field_addr, const Proto64Bit &value) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_DOUBLE: case ProtoFieldType::TYPE_DOUBLE:
*static_cast<double *>(field_addr) = value.as_double(); *static_cast<double *>(field_addr) = value.as_double();
@ -337,27 +324,28 @@ static bool decode_64bit_field(ProtoFieldType type, void *field_addr, const Prot
default: default:
return false; return false;
} }
}
} }
// Decode for length-delimited fields // Decode 64-bit for repeated fields
static bool decode_length_field(ProtoFieldType type, void *field_addr, const ProtoLengthDelimited &value, static bool decode_repeated_64bit_field(ProtoFieldType type, void *field_addr, const Proto64Bit &value) {
bool is_repeated, uint8_t message_type_id) {
if (is_repeated) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_STRING: case ProtoFieldType::TYPE_DOUBLE:
static_cast<std::vector<std::string> *>(field_addr)->push_back(value.as_string()); static_cast<std::vector<double> *>(field_addr)->push_back(value.as_double());
return true;
case ProtoFieldType::TYPE_FIXED64:
static_cast<std::vector<uint64_t> *>(field_addr)->push_back(value.as_fixed64());
return true;
case ProtoFieldType::TYPE_SFIXED64:
static_cast<std::vector<int64_t> *>(field_addr)->push_back(value.as_sfixed64());
return true; return true;
case ProtoFieldType::TYPE_MESSAGE:
if (message_type_id < REPEATED_MESSAGE_HANDLER_COUNT &&
REPEATED_MESSAGE_HANDLERS[message_type_id].decode != nullptr) {
return REPEATED_MESSAGE_HANDLERS[message_type_id].decode(field_addr, value);
}
return false;
default: default:
return false; return false;
} }
} else { }
// Decode length-delimited for single fields
static bool decode_length_field(ProtoFieldType type, void *field_addr, const ProtoLengthDelimited &value,
uint8_t message_type_id) {
switch (type) { switch (type) {
case ProtoFieldType::TYPE_STRING: case ProtoFieldType::TYPE_STRING:
case ProtoFieldType::TYPE_BYTES: case ProtoFieldType::TYPE_BYTES:
@ -371,6 +359,24 @@ static bool decode_length_field(ProtoFieldType type, void *field_addr, const Pro
default: default:
return false; return false;
} }
}
// Decode length-delimited for repeated fields
static bool decode_repeated_length_field(ProtoFieldType type, void *field_addr, const ProtoLengthDelimited &value,
uint8_t message_type_id) {
switch (type) {
case ProtoFieldType::TYPE_STRING:
case ProtoFieldType::TYPE_BYTES:
static_cast<std::vector<std::string> *>(field_addr)->push_back(value.as_string());
return true;
case ProtoFieldType::TYPE_MESSAGE:
if (message_type_id < REPEATED_MESSAGE_HANDLER_COUNT &&
REPEATED_MESSAGE_HANDLERS[message_type_id].decode != nullptr) {
return REPEATED_MESSAGE_HANDLERS[message_type_id].decode(field_addr, value);
}
return false;
default:
return false;
} }
} }
@ -421,7 +427,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < field_count; j++) { for (size_t j = 0; j < field_count; j++) {
if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 0) { if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 0) {
void *field_addr = base + fields[j].get_offset(); void *field_addr = base + fields[j].get_offset();
decoded = decode_varint_field(fields[j].get_type(), field_addr, value, false); decoded = decode_varint_field(fields[j].get_type(), field_addr, value);
break; break;
} }
} }
@ -431,7 +437,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < repeated_count; j++) { for (size_t j = 0; j < repeated_count; j++) {
if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 0) { if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 0) {
void *field_addr = base + repeated_fields[j].get_offset(); void *field_addr = base + repeated_fields[j].get_offset();
decoded = decode_varint_field(repeated_fields[j].get_type(), field_addr, value, true); decoded = decode_repeated_varint_field(repeated_fields[j].get_type(), field_addr, value);
break; break;
} }
} }
@ -461,8 +467,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < field_count; j++) { for (size_t j = 0; j < field_count; j++) {
if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 2) { if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 2) {
void *field_addr = base + fields[j].get_offset(); void *field_addr = base + fields[j].get_offset();
decoded = decoded = decode_length_field(fields[j].get_type(), field_addr, value, fields[j].get_message_type_id());
decode_length_field(fields[j].get_type(), field_addr, value, false, fields[j].get_message_type_id());
break; break;
} }
} }
@ -472,7 +477,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < repeated_count; j++) { for (size_t j = 0; j < repeated_count; j++) {
if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 2) { if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 2) {
void *field_addr = base + repeated_fields[j].get_offset(); void *field_addr = base + repeated_fields[j].get_offset();
decoded = decode_length_field(repeated_fields[j].get_type(), field_addr, value, true, decoded = decode_repeated_length_field(repeated_fields[j].get_type(), field_addr, value,
repeated_fields[j].get_message_type_id()); repeated_fields[j].get_message_type_id());
break; break;
} }
@ -500,7 +505,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < field_count; j++) { for (size_t j = 0; j < field_count; j++) {
if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 5) { if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 5) {
void *field_addr = base + fields[j].get_offset(); void *field_addr = base + fields[j].get_offset();
decoded = decode_32bit_field(fields[j].get_type(), field_addr, value, false); decoded = decode_32bit_field(fields[j].get_type(), field_addr, value);
break; break;
} }
} }
@ -510,7 +515,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < repeated_count; j++) { for (size_t j = 0; j < repeated_count; j++) {
if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 5) { if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 5) {
void *field_addr = base + repeated_fields[j].get_offset(); void *field_addr = base + repeated_fields[j].get_offset();
decoded = decode_32bit_field(repeated_fields[j].get_type(), field_addr, value, true); decoded = decode_repeated_32bit_field(repeated_fields[j].get_type(), field_addr, value);
break; break;
} }
} }
@ -541,7 +546,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < field_count; j++) { for (size_t j = 0; j < field_count; j++) {
if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 1) { if (fields[j].field_num == field_id && get_wire_type(fields[j].get_type()) == 1) {
void *field_addr = base + fields[j].get_offset(); void *field_addr = base + fields[j].get_offset();
decoded = decode_64bit_field(fields[j].get_type(), field_addr, value, false); decoded = decode_64bit_field(fields[j].get_type(), field_addr, value);
break; break;
} }
} }
@ -551,7 +556,7 @@ void ProtoMessage::decode(const uint8_t *buffer, size_t length) {
for (size_t j = 0; j < repeated_count; j++) { for (size_t j = 0; j < repeated_count; j++) {
if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 1) { if (repeated_fields[j].field_num == field_id && get_wire_type(repeated_fields[j].get_type()) == 1) {
void *field_addr = base + repeated_fields[j].get_offset(); void *field_addr = base + repeated_fields[j].get_offset();
decoded = decode_64bit_field(repeated_fields[j].get_type(), field_addr, value, true); decoded = decode_repeated_64bit_field(repeated_fields[j].get_type(), field_addr, value);
break; break;
} }
} }