<commit_before>#include "rpcruntime_protocol_description.h"

#include <QDebug>
#include <QXmlStreamReader>
#include <cassert>
#include <fstream>
#include <sstream>
#include <string>
#include <numeric>

struct Common_parameter_attributes {
	int bit_size;
	std::string parameter_name;
	std::string parameter_ctype;
	int parameter_position;
};

static RPCRuntimeParameterDescription parse_parameter(QXmlStreamReader &xml_reader);

static Common_parameter_attributes parse_common_parameter_attributes(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes retval;
	const auto &parameter_attributes = xml_reader.attributes();

	retval.bit_size = parameter_attributes.value("bits").toInt();
	assert(retval.bit_size != 0); //this fails if bit_size doesn't exist or could not be parsed or has an invalid value

	retval.parameter_name = parameter_attributes.value("name").toString().toStdString();

	retval.parameter_ctype = parameter_attributes.value("ctype").toString().toStdString();

	retval.parameter_position = parameter_attributes.value("position").toInt();
	if (retval.parameter_position == 0) {
		retval.parameter_position = parameter_attributes.value("memberpos").toInt();
	}

	return retval;
}

static RPCRuntimeParameterDescription parse_integer_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeIntegerParameter integer_parameter;

	const auto &parameter_attributes = xml_reader.attributes();
	assert(parameter_attributes.value("type") == "integer");

	xml_reader.readNextStartElement();
	assert(xml_reader.name() == "integer");
	auto signed_string = xml_reader.attributes().value("signed");
	if (signed_string == "True" || signed_string == "true") {
		integer_parameter.is_signed = true;
	} else if (signed_string == "False" || signed_string == "false") {
		integer_parameter.is_signed = false;
	} else {
        throw std::runtime_error("RPC: Integer parameter has no propper signed attribute");
	}
	xml_reader.skipCurrentElement(); //integer

	xml_reader.skipCurrentElement(); //parameter
    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(integer_parameter)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_enum_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeEnumerationParameter enumeration;
	enumeration.enum_name = common_attributes.parameter_ctype;

	while (xml_reader.readNextStartElement()) {
		assert(xml_reader.name() == "enum");
		const auto &enum_attributes = xml_reader.attributes();
		RPCRuntimeEnumerationParameter::Enum_value ev;
		ev.value = enum_attributes.value("value").toString().toStdString();
		ev.name = enum_attributes.value("name").toString().toStdString();

		enumeration.values.push_back(std::move(ev));

		xml_reader.skipCurrentElement(); //enum
	}

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(enumeration)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_character_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeCharacterParameter character;

	xml_reader.skipCurrentElement();

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(character)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_struct_parameter(QXmlStreamReader &xml_reader);

static RPCRuntimeParameterDescription parse_array_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);


	const auto &parameter_attributes = xml_reader.attributes();
	assert(parameter_attributes.value("type") == "array");

	int bit_size = parameter_attributes.value("bits").toInt();
	(void)bit_size;

	xml_reader.readNextStartElement();

	const auto &array_attributes = xml_reader.attributes();
	assert(xml_reader.name() == "array");

	int number_of_elements = array_attributes.value("elements").toInt();
	assert(number_of_elements);

    auto type = parse_parameter(xml_reader);
	if (type.get_type() == RPCRuntimeParameterDescription::Type::structure) {
		type.fix_array_bit_byte_bug();
	}
	RPCRuntimeArrayParameter array{std::move(type), number_of_elements};
	//array.type.bit_size = bit_size:
	xml_reader.skipCurrentElement();

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(array)};

    //retval.set_field_id(field_id);
    return retval;
}

static RPCRuntimeParameterDescription parse_struct_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeStructureParameter structure;


	while (xml_reader.readNextStartElement()) {
		assert(xml_reader.name() == "parameter");
        structure.members.push_back(parse_parameter(xml_reader));
	}

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(structure)};

    //retval.set_field_id(field_id);
    return retval;<commit_msg>fixes struct size calculation bug where RPC-generator's xml file provided wrong information<commit_after>#include "rpcruntime_protocol_description.h"

#include <QDebug>
#include <QXmlStreamReader>
#include <cassert>
#include <fstream>
#include <sstream>
#include <string>
#include <numeric>

struct Common_parameter_attributes {
	int bit_size;
    bool bit_size_is_possibly_devided_by_eight_due_to_bug_in_older_xml_generator_generating_structs;
	std::string parameter_name;
	std::string parameter_ctype;
	int parameter_position;
};

static RPCRuntimeParameterDescription parse_parameter(QXmlStreamReader &xml_reader);

static Common_parameter_attributes parse_common_parameter_attributes(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes retval;
	const auto &parameter_attributes = xml_reader.attributes();

    if (parameter_attributes.hasAttribute("bits")) {
		retval.bit_size = parameter_attributes.value("bits").toInt();
        retval.bit_size_is_possibly_devided_by_eight_due_to_bug_in_older_xml_generator_generating_structs = true;
    } else {
        retval.bit_size = parameter_attributes.value("bytes").toInt() * 8;
        retval.bit_size_is_possibly_devided_by_eight_due_to_bug_in_older_xml_generator_generating_structs = false;
    }

	assert(retval.bit_size != 0); //this fails if bit_size doesn't exist or could not be parsed or has an invalid value

	retval.parameter_name = parameter_attributes.value("name").toString().toStdString();

	retval.parameter_ctype = parameter_attributes.value("ctype").toString().toStdString();

	retval.parameter_position = parameter_attributes.value("position").toInt();
	if (retval.parameter_position == 0) {
		retval.parameter_position = parameter_attributes.value("memberpos").toInt();
	}

	return retval;
}

static RPCRuntimeParameterDescription parse_integer_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeIntegerParameter integer_parameter;

	const auto &parameter_attributes = xml_reader.attributes();
	assert(parameter_attributes.value("type") == "integer");

	xml_reader.readNextStartElement();
	assert(xml_reader.name() == "integer");
	auto signed_string = xml_reader.attributes().value("signed");
	if (signed_string == "True" || signed_string == "true") {
		integer_parameter.is_signed = true;
	} else if (signed_string == "False" || signed_string == "false") {
		integer_parameter.is_signed = false;
	} else {
        throw std::runtime_error("RPC: Integer parameter has no propper signed attribute");
	}
	xml_reader.skipCurrentElement(); //integer

	xml_reader.skipCurrentElement(); //parameter
    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(integer_parameter)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_enum_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeEnumerationParameter enumeration;
	enumeration.enum_name = common_attributes.parameter_ctype;

	while (xml_reader.readNextStartElement()) {
		assert(xml_reader.name() == "enum");
		const auto &enum_attributes = xml_reader.attributes();
		RPCRuntimeEnumerationParameter::Enum_value ev;
		ev.value = enum_attributes.value("value").toString().toStdString();
		ev.name = enum_attributes.value("name").toString().toStdString();

		enumeration.values.push_back(std::move(ev));

		xml_reader.skipCurrentElement(); //enum
	}

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(enumeration)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_character_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeCharacterParameter character;

	xml_reader.skipCurrentElement();

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(character)};
    //retval.set_field_id(parent_field_id+"."+retval.get_parameter_name());
    return retval;
}

static RPCRuntimeParameterDescription parse_struct_parameter(QXmlStreamReader &xml_reader);

static RPCRuntimeParameterDescription parse_array_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);


	const auto &parameter_attributes = xml_reader.attributes();
	assert(parameter_attributes.value("type") == "array");

	int bit_size = parameter_attributes.value("bits").toInt();
	(void)bit_size;

	xml_reader.readNextStartElement();

	const auto &array_attributes = xml_reader.attributes();
	assert(xml_reader.name() == "array");

	int number_of_elements = array_attributes.value("elements").toInt();
	assert(number_of_elements);

    auto type = parse_parameter(xml_reader);
	RPCRuntimeArrayParameter array{std::move(type), number_of_elements};
	//array.type.bit_size = bit_size:
	xml_reader.skipCurrentElement();

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(array)};

    //retval.set_field_id(field_id);
    return retval;
}

static RPCRuntimeParameterDescription parse_struct_parameter(QXmlStreamReader &xml_reader) {
	Common_parameter_attributes common_attributes = parse_common_parameter_attributes(xml_reader);
	RPCRuntimeStructureParameter structure;

	while (xml_reader.readNextStartElement()) {
		assert(xml_reader.name() == "parameter");
        structure.members.push_back(parse_parameter(xml_reader));
	}

    RPCRuntimeParameterDescription retval{common_attributes.bit_size, std::move(common_attributes.parameter_name), std::move(common_attributes.parameter_ctype),
                common_attributes.parameter_position, std::move(structure)};

    //retval.set_field_id(field_id);
    if (common_attributes.bit_size_is_possibly_devided_by_eight_due_to_bug_in_older_xml_generator_generating_structs) {
        retval.fix_array_bit_byte_bug();
    }
    return retval;
{'fraction_non_alphanumeric': 0.10499219968798752, 'fraction_numerical': 0.000390015600624025, 'mean_word_length': 7.347005208333333, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 73}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5387940', 'n_tokens_mistral': 3711, 'n_tokens_neox': 3619, 'n_words': 551}