From 32bb25cc2666809759371436a6450574b00c0e6d Mon Sep 17 00:00:00 2001 From: Mosder Date: Mon, 13 Jul 2026 15:32:27 +0200 Subject: feat: added generic functionallity for getting the parsed data from stream --- analyzer/parser/parser.c | 79 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 13 deletions(-) (limited to 'analyzer/parser/parser.c') diff --git a/analyzer/parser/parser.c b/analyzer/parser/parser.c index 7fb155f..246635c 100644 --- a/analyzer/parser/parser.c +++ b/analyzer/parser/parser.c @@ -2,19 +2,72 @@ #include -ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed_data) { - // TODO: Need to do parsing of the entire thing (loop) and return all of the parsed data - int length; - byte_t *start = find_fight_results(stream, &length); - if (start == NULL) { - *parsed_len = stream->len; - } - else if (length == -1) { - *parsed_len = 0; +#include "find_parse_functions.h" + +// expand parsed data exponentially to fit el_count elements +ParsedData *expand_parsed_data(ParsedData *parsed_data, size_t *capacity, size_t el_count) { + while (*capacity < el_count) + *capacity <<= 1; + return realloc(parsed_data, *capacity * sizeof(ParsedData)); +} + +// find earliest data to parse in stream +byte_t *find_earliest_data(TCPStream *stream, int stream_offset, int *earliest_length, parse_function_t **earliest_parse_fun) { + byte_t *earliest_data = NULL; + for (size_t i = 0; i < RESULT_TYPE_COUNT; i++) { + int length; + byte_t *data = all_find_parse_functions[i].find_fn(stream, stream_offset, &length); + // if it's the first found or earlier than earliest - save it + if (data && (!earliest_data || data < earliest_data)) { + earliest_data = data; + *earliest_length = length; + *earliest_parse_fun = all_find_parse_functions[i].parse_fn; + } } - else { - parse_fight_results(start, length); - *parsed_len = start - stream->data + length; + return earliest_data; +} + +ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed_data) { + size_t parsed_data_capacity = INIT_PARSED_DATA_CAPACITY; + ParsedData *parsed_data = malloc(parsed_data_capacity * sizeof(ParsedData)); + *n_parsed_data = 0; + + int stream_offset = 0; + byte_t *earliest_data; + do { + // find earliest data to parse + int earliest_length; + parse_function_t *earliest_parse_fun; + earliest_data = find_earliest_data(stream, stream_offset, &earliest_length, &earliest_parse_fun); + + // if start of data to parse was found, but not the end, then finish here + // set parsed_len, so that the beginning of that data is at the beginning of the stream + if (earliest_data && earliest_length == -1) { + *parsed_len = earliest_data - stream->data; + return parsed_data; + } + + // if data to parse was found, parse it and update the offset + if (earliest_data) { + // if no capacity in parsed data array - expand it + if (*n_parsed_data >= parsed_data_capacity) + parsed_data = expand_parsed_data(parsed_data, &parsed_data_capacity, *n_parsed_data + 1); + + parsed_data[(*n_parsed_data)++] = earliest_parse_fun(earliest_data, earliest_length); + stream_offset = earliest_data - stream->data + earliest_length; + } + } while (earliest_data); + + // if all was parsed - set parsed_len to stream_len and return the data + *parsed_len = stream->len; + return parsed_data; +} + +void free_parsed_data(ParsedData *parsed_data, size_t n_parsed_data) { + for (size_t i = 0; i < n_parsed_data; i++) { + if (parsed_data[i].data_cleanup) + parsed_data[i].data_cleanup(parsed_data[i].data); + free(parsed_data[i].data); } - return NULL; + free(parsed_data); } -- cgit v1.2.3