aboutsummaryrefslogtreecommitdiff
path: root/analyzer/parser
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-07-23 17:35:04 +0200
committerMosder <xmosder12@gmail.com>2026-07-23 17:35:04 +0200
commit8317c3b33b9b1c70e5ae4c87c7efe33d9b9ce09a (patch)
tree8a6b5e20196a253c75b44762de223f1ea2b4a067 /analyzer/parser
parent33fcaa8140784ab32cfc8c14a6fc7fdb71435265 (diff)
feat: added helper functions for dealing with memory management and refactored the codebase to use them
Diffstat (limited to 'analyzer/parser')
-rw-r--r--analyzer/parser/fight_results/fight_results.c109
-rw-r--r--analyzer/parser/fight_results/fight_results.h6
-rw-r--r--analyzer/parser/parser.c16
-rw-r--r--analyzer/parser/structs.c4
4 files changed, 56 insertions, 79 deletions
diff --git a/analyzer/parser/fight_results/fight_results.c b/analyzer/parser/fight_results/fight_results.c
index e7c7123..efc4b36 100644
--- a/analyzer/parser/fight_results/fight_results.c
+++ b/analyzer/parser/fight_results/fight_results.c
@@ -30,6 +30,8 @@ void cleanup_fight_results(void *data) {
for (size_t i = 0; i < fight_results->num_enemy; i++) {
free(fight_results->enemy_results[i].name);
}
+ free(fight_results->friendly_results);
+ free(fight_results->enemy_results);
}
byte_t *find_fight_results(TCPStream *stream, int offset, int *length) {
@@ -41,12 +43,6 @@ byte_t *find_fight_results(TCPStream *stream, int offset, int *length) {
return start;
}
-Item *expand_items(Item *items, size_t *items_capacity, size_t to_fit) {
- while (*items_capacity < to_fit)
- *items_capacity <<= 1;
- return realloc(items, *items_capacity * sizeof(Item));
-}
-
void get_stars(char *buffer, int incr_above_b1) {
char star_types[] = {'B', 'S', 'G'};
sprintf(buffer, " (%c%d)", star_types[incr_above_b1 / 3], incr_above_b1 % 3 + 1);
@@ -67,10 +63,11 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str)
if (gears_separator)
gears_str = gears_separator + strlen(SEPARATOR_GEAR);
- Item item;
-
+ // get gear info for rank, name and stars / syng level
GearInfo gear_info = {0};
fill_struct(&gear_info, gear_info_fields, ARR_LEN(gear_info_fields), gear.info, strlen(gear.info), SEPARATOR_GEAR_INFO_FIELD);
+
+ // create the buffer of information about gear
char buffer[SINGLE_ITEM_BUFFER_LEN];
char roman[5];
to_roman(roman, gear_info.rank);
@@ -91,9 +88,9 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str)
break;
}
}
- item.data = strdup(buffer);
- cleanup_struct(&gear_info, gear_info_fields, ARR_LEN(gear_info_fields));
+ // add gear with specific type
+ Item item = {.data = strdup(buffer)};
switch (gear.type) {
case TYPE_SYNG_NORMAL:
// atoi should be fine, since syng_tier starts from 1 for syngs
@@ -109,26 +106,22 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str)
item.type = EPIC;
break;
}
+ results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item);
- // expand if needed
- if (results->num_items >= *items_capacity)
- results->items = expand_items(results->items, items_capacity, results->num_items + 1);
- results->items[results->num_items++] = item;
+ cleanup_struct(&gear_info, gear_info_fields, ARR_LEN(gear_info_fields));
// add orb to items if it exists
if (strlen(gear.orb)) {
- Item item;
- char buffer[SINGLE_ITEM_BUFFER_LEN];
Orb orb = {0};
fill_struct(&orb, orb_fields, ARR_LEN(orb_fields), gear.orb, strlen(gear.orb), SEPARATOR_ORB_FIELD);
+
+ char buffer[SINGLE_ITEM_BUFFER_LEN];
sprintf(buffer, "%sorb %s", get_artifact_size_from_id(orb.size), get_orb_name_from_id(orb.id));
- item.data = strdup(buffer);
+
+ Item item = {.data = strdup(buffer), .type = ORB};
+ results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item);
+
cleanup_struct(&orb, orb_fields, ARR_LEN(orb_fields));
- item.type = ORB;
- // expand if needed
- if (results->num_items >= *items_capacity)
- results->items = expand_items(results->items, items_capacity, results->num_items + 1);
- results->items[results->num_items++] = item;
}
cleanup_struct(&gear, gear_fields, ARR_LEN(gear_fields));
@@ -150,16 +143,10 @@ void add_drifs(FriendlyResults *results, size_t *items_capacity, char *drifs_str
if (drifs_separator)
drifs_str = drifs_separator + strlen(SEPARATOR_DRIF);
- Item item;
- item.data = strdup(drif.name);
- item.type = DRIF;
+ Item item = {.data = strdup(drif.name), .type = DRIF};
+ results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item);
cleanup_struct(&drif, drif_fields, ARR_LEN(drif_fields));
-
- // expand if needed
- if (results->num_items >= *items_capacity)
- results->items = expand_items(results->items, items_capacity, results->num_items + 1);
- results->items[results->num_items++] = item;
} while (drifs_separator);
}
@@ -180,37 +167,31 @@ void add_items(FriendlyResults *results, size_t *items_capacity, char *items_str
if (items_separator)
items_str = items_separator + strlen(SEPARATOR_ITEMS);
- Item item;
- item.data = strdup(buffer);
- item.type = NORMAL;
-
- // expand if needed
- if (results->num_items >= *items_capacity)
- results->items = expand_items(results->items, items_capacity, results->num_items + 1);
- results->items[results->num_items++] = item;
+ Item item = {.data = strdup(buffer), .type = NORMAL};
+ results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item);
} while (items_separator);
}
// parse EntityResults to FriendlyResults
FriendlyResults parse_to_friendly(EntityResults entity_results) {
- FriendlyResults results;
-
- results.name = strdup(entity_results.name);
- results.exp = entity_results.exp;
- results.gold = entity_results.gold;
- results.level = entity_results.level;
- results.psycho = entity_results.psycho;
- results.splinters = entity_results.splinters;
+ FriendlyResults results = {
+ .name = strdup(entity_results.name),
+ .exp = entity_results.exp,
+ .gold = entity_results.gold,
+ .level = entity_results.level,
+ .psycho = entity_results.psycho,
+ .splinters = entity_results.splinters,
+ .num_items = 0,
+ .saturation = 0
+ };
// create items array and add to it gear, drifs and items
- results.num_items = 0;
- results.items = malloc(INIT_ITEMS_CAPACITY * sizeof(Item));
+ results.items = safe_malloc(INIT_ITEMS_CAPACITY * sizeof(Item));
size_t items_cap = INIT_ITEMS_CAPACITY;
add_gear(&results, &items_cap, entity_results.gear);
add_drifs(&results, &items_cap, entity_results.drifs);
add_items(&results, &items_cap, entity_results.items);
- results.saturation = 0;
if (strlen(entity_results.saturation) > 0) {
int saturation_id;
sscanf(entity_results.saturation, "%d,%d", &saturation_id, &results.saturation);
@@ -222,25 +203,26 @@ FriendlyResults parse_to_friendly(EntityResults entity_results) {
// parse EntityResults to EnemyResults
EnemyResults parse_to_enemy(EntityResults entity_results) {
- EnemyResults results;
-
- results.name = strdup(entity_results.name);
- results.level = entity_results.level;
-
+ EnemyResults results = {.name = strdup(entity_results.name), .level = entity_results.level};
return results;
}
ParsedData parse_fight_results(byte_t *data, size_t length) {
- ParsedData parsed_data;
- parsed_data.data_type = TYPE_FIGHT_RESULTS;
+ ParsedData parsed_data = {.data_type = TYPE_FIGHT_RESULTS, .data_cleanup = cleanup_fight_results};
// ignore start and end indicators
data += strlen(FIGHT_RESULTS_START);
length -= strlen(FIGHT_RESULTS_START) + strlen(FIGHT_RESULTS_END);
- FightResults *results = malloc(sizeof(FightResults));
+ FightResults *results = safe_malloc(sizeof(FightResults));
+
+ results->friendly_results = safe_malloc(INIT_ENTITIES_PER_SIDE * sizeof(FriendlyResults));
results->num_friendly = 0;
+ size_t friendly_cap = INIT_ENTITIES_PER_SIDE;
+
+ results->enemy_results = safe_malloc(INIT_ENTITIES_PER_SIDE * sizeof(EnemyResults));
results->num_enemy = 0;
+ size_t enemy_cap = INIT_ENTITIES_PER_SIDE;
byte_t *entity_separator;
do {
@@ -252,12 +234,16 @@ ParsedData parse_fight_results(byte_t *data, size_t length) {
// depending on team - parse it into friendly or enemy results
switch (entity_results.team) {
- case TEAM_FRIEND:
- results->friendly_results[results->num_friendly++] = parse_to_friendly(entity_results);
+ case TEAM_FRIEND: {
+ FriendlyResults res = parse_to_friendly(entity_results);
+ results->friendly_results = array_append(results->friendly_results, sizeof(FriendlyResults), &results->num_friendly, &friendly_cap, &res);
break;
- case TEAM_ENEMY:
- results->enemy_results[results->num_enemy++] = parse_to_enemy(entity_results);
+ }
+ case TEAM_ENEMY: {
+ EnemyResults res = parse_to_enemy(entity_results);
+ results->enemy_results = array_append(results->enemy_results, sizeof(EnemyResults), &results->num_enemy, &enemy_cap, &res);
break;
+ }
}
cleanup_struct(&entity_results, entity_fields, ARR_LEN(entity_fields));
@@ -270,6 +256,5 @@ ParsedData parse_fight_results(byte_t *data, size_t length) {
} while (entity_separator);
parsed_data.data = results;
- parsed_data.data_cleanup = cleanup_fight_results;
return parsed_data;
}
diff --git a/analyzer/parser/fight_results/fight_results.h b/analyzer/parser/fight_results/fight_results.h
index 04add96..ec90394 100644
--- a/analyzer/parser/fight_results/fight_results.h
+++ b/analyzer/parser/fight_results/fight_results.h
@@ -44,14 +44,14 @@ typedef struct {
int level;
} EnemyResults;
-#define MAX_ENTITIES_PER_SIDE 8
+#define INIT_ENTITIES_PER_SIDE 6
// entire fight resutls
typedef struct {
size_t num_friendly;
- FriendlyResults friendly_results[MAX_ENTITIES_PER_SIDE];
+ FriendlyResults *friendly_results;
size_t num_enemy;
- EnemyResults enemy_results[MAX_ENTITIES_PER_SIDE];
+ EnemyResults *enemy_results;
} FightResults;
extern find_function_t find_fight_results;
diff --git a/analyzer/parser/parser.c b/analyzer/parser/parser.c
index 87ab4c0..d00cd97 100644
--- a/analyzer/parser/parser.c
+++ b/analyzer/parser/parser.c
@@ -5,13 +5,6 @@
#include "parser/find_parse_functions.h"
#include "utils/memory.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;
@@ -30,7 +23,7 @@ byte_t *find_earliest_data(TCPStream *stream, int stream_offset, int *earliest_l
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));
+ ParsedData *parsed_data = safe_malloc(parsed_data_capacity * sizeof(ParsedData));
*n_parsed_data = 0;
int stream_offset = 0;
@@ -50,11 +43,8 @@ ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed
// 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);
+ ParsedData new_parsed = earliest_parse_fun(earliest_data, earliest_length);
+ parsed_data = array_append(parsed_data, sizeof(ParsedData), n_parsed_data, &parsed_data_capacity, &new_parsed);
stream_offset = earliest_data - stream->data + earliest_length;
}
} while (earliest_data);
diff --git a/analyzer/parser/structs.c b/analyzer/parser/structs.c
index c59fa82..dedf0d1 100644
--- a/analyzer/parser/structs.c
+++ b/analyzer/parser/structs.c
@@ -4,12 +4,14 @@
#include <stdlib.h>
#include <string.h>
+#include "utils/memory.h"
+
void fill_struct(void *obj, const StructField *fields, size_t n_fields, const char *data, size_t data_len, const char *sep) {
for (size_t i = 0; i < n_fields; i++) {
char *next_sep = memmem(data, data_len, sep, strlen(sep));
size_t len = next_sep ? next_sep - data : data_len;
- char *str = malloc(len + 1);
+ char *str = safe_malloc(len + 1);
memcpy(str, data, len);
str[len] = '\0';