711 lines
23 KiB
C
711 lines
23 KiB
C
/****** data.c
|
|
This file contains the functions for loading Data, be they Tiles or otherwise, from text data into TileData/TileSetData/Data structures. Additionally are defined functions for populating TileData into *Tile structures (as would be used from map generation or spawning operations). Finally, and more tertiary, this file also defines functions for loading files into memory.
|
|
******/
|
|
#include <stdio.h> // for file reading
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <limits.h> // for ULONG_MAX
|
|
#include <ctype.h> // for isdigit
|
|
#include "data.h"
|
|
/**** loadDataFromMemory
|
|
Loads given data from memory into a Data struct, also populating TileSetData and TileData structs.
|
|
|
|
****/
|
|
struct Data *loadDataFromMemory(char *memory, int size) {
|
|
struct Data *data = malloc(sizeof(struct Data));
|
|
data->size = SET_SIZE;
|
|
data->id = malloc(sizeof(int)*SET_SIZE);
|
|
data->set = malloc(sizeof(struct TileSetData*)*SET_SIZE);
|
|
memset(data->set, 0, sizeof(struct TileSetData*)*SET_SIZE);
|
|
int offset = 0;
|
|
int depth = 0; // used to manage position!
|
|
data->set_count = 0;
|
|
while (offset <= size-1) { // err, size-1? FIXME
|
|
if (memory[offset] == '{') {
|
|
depth++;
|
|
offset++; // skip that bracket
|
|
if (depth == 1) {
|
|
// now we get our tileset's id
|
|
char temp_string[31];
|
|
int temp_offset = offset-1;
|
|
int temp_offset_2 = 0;
|
|
while (memory[temp_offset] != '\n' && temp_offset > 0) {
|
|
temp_offset--;
|
|
}
|
|
while (memory[temp_offset] != '{') {
|
|
temp_string[temp_offset_2++] = memory[temp_offset++];
|
|
}
|
|
temp_string[temp_offset_2] = '\0';
|
|
|
|
int tileset_id = atoi(temp_string);
|
|
// resize Data if tileset's id is greater than our size
|
|
if (tileset_id > data->size) {
|
|
data->size += tileset_id-data->size;
|
|
//void *ret;
|
|
data->id = realloc(data->id, sizeof(int)*data->size);
|
|
data->set = realloc(data->set, sizeof(struct TileSetData*)*data->size);
|
|
}
|
|
data->set[tileset_id] = loadTileSetData(tileset_id, memory, &offset, &depth);
|
|
data->set_count++;
|
|
}
|
|
} else if (memory[offset] == '}') {
|
|
depth--;
|
|
}
|
|
offset++;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
int saveDataToFile(struct Data* data, const char *filename) {
|
|
FILE *output = fopen(filename, "w");
|
|
if (output == NULL) {
|
|
return -1;
|
|
}
|
|
int chars = 0;
|
|
int count = 0;
|
|
while (count < data->size) {
|
|
int count_2 = 0;
|
|
if (data->set[count]) {
|
|
chars += fprintf(output, "%d {\n", count);
|
|
while (count_2 < data->set[count]->size) {
|
|
if (data->set[count]->tile[count_2]) {
|
|
chars += fprintf(output, "%d {\n", count_2);
|
|
struct Table *table = data->set[count]->tile[count_2]->table;
|
|
int i = 0;
|
|
while (i < table->size) {
|
|
struct TablePair *table_pair = table->pair[i];
|
|
while (table_pair != NULL) {
|
|
if (table_pair->type == T_STRING) {
|
|
chars += fprintf(output, "%s %s\n", table_pair->key, table_pair->value);
|
|
} else if (table_pair->type == T_INT) {
|
|
chars += fprintf(output, "%s %d\n", table_pair->key, *(int*)table_pair->value);
|
|
} else if (table_pair->type == T_FLOAT) {
|
|
chars += fprintf(output, "%s %f\n", table_pair->key, *(float*)table_pair->value);
|
|
} else if (table_pair->type == T_PROTO_INVENTORY) {
|
|
chars += fprintf(output, "%s {\n", table_pair->key);
|
|
struct InventoryData* inv = table_pair->value;
|
|
while (inv != NULL) {
|
|
chars += fprintf(output, "%s, %d-%d, %f\n", inv->name, inv->count.min, inv->count.max, inv->chance);
|
|
inv = inv->next;
|
|
}
|
|
chars += fprintf(output, "}\n");
|
|
}
|
|
table_pair = table_pair->next;
|
|
}
|
|
i++;
|
|
}
|
|
chars += fprintf(output, "}\n");
|
|
}
|
|
count_2++;
|
|
}
|
|
chars += fprintf(output, "}\n");
|
|
}
|
|
count++;
|
|
}
|
|
fclose(output);
|
|
return chars;
|
|
}
|
|
|
|
struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, int *depth) {
|
|
struct TileSetData *set_data = malloc(sizeof(struct TileSetData));
|
|
set_data->tid = tileset_id;
|
|
set_data->tile_count = 0;
|
|
set_data->size = SET_SIZE; // default of 32
|
|
set_data->keys = newTable(set_data->size);
|
|
set_data->tile = malloc(sizeof(struct TileData*)*SET_SIZE);
|
|
// just so we're not working with undeclared vars
|
|
int i = 0;
|
|
while (i < SET_SIZE) {
|
|
set_data->tile[i++] = NULL;
|
|
}
|
|
/* populate Tiles! */
|
|
while (*depth != 0) {
|
|
if (memory[*offset] == '{') {
|
|
*offset = *offset + 1; //skip the bracket
|
|
*depth = *depth + 1;
|
|
if (*depth == 2) {
|
|
// now we get our tileset's id
|
|
char temp_string[31];
|
|
int temp_offset = *offset-1;
|
|
int temp_offset_2 = 0;
|
|
while (memory[temp_offset] != '\n' && temp_offset > 0) {
|
|
temp_offset--;
|
|
}
|
|
while (memory[temp_offset] != '{') {
|
|
temp_string[temp_offset_2++] = memory[temp_offset++];
|
|
}
|
|
temp_string[temp_offset_2] = '\0';
|
|
|
|
int tile_id = atoi(temp_string);
|
|
// resize Data if tileset's id is greater than our size
|
|
if (tile_id > set_data->size) {
|
|
set_data->size += tile_id-set_data->size;
|
|
//void *ret;
|
|
set_data->tile = realloc(set_data->tile, sizeof(struct TileData*)*set_data->size);
|
|
}
|
|
// if tile entry already exists, free old one and load in new one
|
|
if (set_data->tile[tile_id] != NULL) {
|
|
// FIXME: must free data for overwrite
|
|
freeTileData(set_data->tile[tile_id]);
|
|
} else {
|
|
set_data->tile_count++;
|
|
}
|
|
set_data->tile[tile_id] = loadTileData(tile_id, memory, offset, depth);
|
|
set_data->tile[tile_id]->tid = tileset_id; // store the tileset id in tile as well
|
|
// now let's
|
|
//printf("--> key->id: (%s)%d=>%d\n", getTablePairValue(set_data->tile[tile_id]->table, "name"), getTableIndex(set_data->keys, getTablePairValue(set_data->tile[tile_id]->table, "name")), tile_id);
|
|
addTablePair(set_data->keys, getTablePairValue(set_data->tile[tile_id]->table, "name"), &tile_id, sizeof(int), T_INT);
|
|
//printf("<-- key->id: (%s)%d=>%d\n", getTablePairValue(set_data->tile[tile_id]->table, "name"), getTableIndex(set_data->keys, getTablePairValue(set_data->tile[tile_id]->table, "name")), *(int*)getTablePairValue(set_data->keys, getTablePairValue(set_data->tile[tile_id]->table, "name")));
|
|
}
|
|
|
|
} else if (memory[*offset] == '}') {
|
|
*depth = *depth - 1;
|
|
}
|
|
*offset = *offset + 1;
|
|
}
|
|
return set_data;
|
|
}
|
|
|
|
/**** loadTileData
|
|
This function is the third step in the linear processing of a data file - it takes an offset and begins processing at that memory until the depth is less than or equal to 1. What it actually does is convert all lines into key=>value pairs (using a Table and TablePairs), with the key delimited from the value by the first occurance of a space character after a non-space character has occurred. ex: " name my name" = name=>"my name"
|
|
From that point forward, properties can be retrieved from the TileData's Table by using the various getTable* functions.
|
|
|
|
****/
|
|
struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
|
|
struct TileData *tile_data = newTileData(8);
|
|
tile_data->id = id;
|
|
|
|
char var_name[32]; // max 32 chars for var name
|
|
char var_value[256]; // max 256 chars for value
|
|
|
|
int i = 0;
|
|
|
|
short mode = 0;
|
|
short value_mode = 0;
|
|
while(*depth > 1) {
|
|
switch (memory[*offset]) {
|
|
case '{':
|
|
*depth = *depth + 1;
|
|
if (*depth == 3) {
|
|
*offset = *offset + 2; // skip that bracket and newline
|
|
// let's get the name for the inventory
|
|
char temp_string[31];
|
|
int temp_offset = *offset-2;
|
|
int temp_offset_2 = 0;
|
|
while (memory[temp_offset] != '\n' && temp_offset > 0) {
|
|
temp_offset--;
|
|
}
|
|
temp_offset++;
|
|
while (memory[temp_offset] != ' ') {
|
|
temp_string[temp_offset_2++] = memory[temp_offset++];
|
|
}
|
|
temp_string[temp_offset_2] = '\0';
|
|
struct InventoryData *inv = loadInventoryData(memory, offset, depth);
|
|
addTablePairPointer(tile_data->table, temp_string, inv, T_PROTO_INVENTORY);
|
|
mode = 0;
|
|
}
|
|
break;
|
|
case '}':
|
|
*depth = *depth - 1;
|
|
break;
|
|
case ' ':
|
|
if (mode == 1) {
|
|
var_name[i] = '\0';
|
|
i = 0;
|
|
mode = 2;
|
|
} else if (mode == 2) {
|
|
var_value[i++] = memory[*offset];
|
|
}
|
|
break;
|
|
case '\n':
|
|
var_value[i] = '\0';
|
|
if (mode == 2) {
|
|
if (*depth == 2) {
|
|
if (value_mode == T_CHAR) {
|
|
addTablePair(tile_data->table, var_name, var_value, strlen(var_value)+1, T_STRING);
|
|
printf("%s(%d)=>%s(string)\n", var_name, getTableIndex(tile_data->table, var_name), (char*)getTablePair(tile_data->table, var_name)->value);
|
|
} else if (value_mode == T_FLOAT) {
|
|
float val = atof(var_value);
|
|
addTablePair(tile_data->table, var_name, &val, sizeof(float*), T_FLOAT);
|
|
printf("%s(%d)=>%f(float)\n", var_name, getTableIndex(tile_data->table, var_name), *(float*)getTablePair(tile_data->table, var_name)->value);
|
|
} else {
|
|
int val = atoi(var_value);
|
|
addTablePair(tile_data->table, var_name, &val, sizeof(int*), T_INT);
|
|
printf("%s(%d)=>%d(int)\n", var_name, getTableIndex(tile_data->table, var_name), *(int*)getTablePair(tile_data->table, var_name)->value);
|
|
}
|
|
}
|
|
}
|
|
i = 0;
|
|
mode = 0;
|
|
value_mode = 0;
|
|
break;
|
|
default:
|
|
if (mode == 1) {
|
|
var_name[i++] = memory[*offset];
|
|
} else if (mode == 2) {
|
|
var_value[i++] = memory[*offset];
|
|
if (isdigit(memory[*offset]) == 0) {
|
|
// not exactly fail safe
|
|
if (memory[*offset] == '.' && value_mode != T_CHAR) {
|
|
value_mode = T_FLOAT;
|
|
} else {
|
|
value_mode = T_CHAR;
|
|
}
|
|
}
|
|
} else if (mode == 0) {
|
|
mode = 1;
|
|
var_name[i++] = memory[*offset];
|
|
}
|
|
break;
|
|
}
|
|
if (*depth <= 1)
|
|
break;
|
|
*offset = *offset + 1;
|
|
}
|
|
return tile_data;
|
|
}
|
|
|
|
struct TileData *newTileData(int size) {
|
|
struct TileData *tile_data = malloc(sizeof(struct TileData));
|
|
tile_data->id = 0;
|
|
tile_data->count = 0;
|
|
tile_data->size = size;
|
|
tile_data->table = newTable(size);
|
|
return tile_data;
|
|
}
|
|
|
|
struct InventoryData *newInventoryData() {
|
|
struct InventoryData *inventory_data = malloc(sizeof(struct InventoryData));
|
|
inventory_data->tid = 0;
|
|
inventory_data->id = 0;
|
|
inventory_data->count.min = 1;
|
|
inventory_data->count.max = 1;
|
|
inventory_data->chance = 100.0f;
|
|
inventory_data->name = malloc(6);
|
|
memcpy(inventory_data->name, "undef", 6);
|
|
inventory_data->next = NULL;
|
|
return inventory_data;
|
|
}
|
|
|
|
void setInventoryDataName(struct InventoryData *inventory, const char *name) {
|
|
int length = strlen(name)+1;
|
|
inventory->name = realloc(inventory->name, length);
|
|
memcpy(inventory->name, name, length);
|
|
}
|
|
|
|
void freeInventoryData(struct InventoryData *inventory_data) {
|
|
struct InventoryData *current_data = inventory_data;
|
|
while (current_data != NULL) {
|
|
struct InventoryData *next_data = current_data->next;
|
|
free(current_data->name);
|
|
free(current_data);
|
|
current_data = next_data;
|
|
}
|
|
}
|
|
|
|
struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth) {
|
|
struct InventoryData *inventory_data = newInventoryData();
|
|
struct InventoryData *first_data = inventory_data;
|
|
struct InventoryData *last_data = NULL;
|
|
// mode, 0 = name, 1 = count, 2 = chance
|
|
char temp_string[64];
|
|
int temp_i = 0;
|
|
int mode = 0;
|
|
while (*depth > 2) {
|
|
switch(memory[*offset]) {
|
|
case '{':
|
|
*depth = *depth +1;
|
|
break;
|
|
case '}':
|
|
*depth = *depth - 1;
|
|
break;
|
|
case ' ':
|
|
if (mode == 0)
|
|
temp_string[temp_i++] = memory[*offset];
|
|
break;
|
|
case '\n':
|
|
temp_string[temp_i] = '\0';
|
|
if (mode == 0) {
|
|
inventory_data->name = realloc(inventory_data->name, temp_i+1);
|
|
memcpy(inventory_data->name, temp_string, temp_i+1);
|
|
} else if (mode == 1) {
|
|
char chance_buffer[64];
|
|
int ch_buffer_i = 0;
|
|
int temp_offset = 0;
|
|
int c_mode = 0;
|
|
while (temp_offset != temp_i) {
|
|
switch(temp_string[temp_offset]) {
|
|
case '-':
|
|
chance_buffer[ch_buffer_i] = '\0';
|
|
inventory_data->count.min = atoi(chance_buffer);
|
|
c_mode = 1;
|
|
ch_buffer_i = 0;
|
|
break;
|
|
default:
|
|
chance_buffer[ch_buffer_i++] = temp_string[temp_offset];
|
|
break;
|
|
}
|
|
temp_offset++;
|
|
}
|
|
chance_buffer[ch_buffer_i] = '\0';
|
|
if (c_mode == 0)
|
|
inventory_data->count.min = atoi(chance_buffer);
|
|
inventory_data->count.max = atoi(chance_buffer);
|
|
} else if (mode == 2) {
|
|
inventory_data->chance = atof(temp_string);
|
|
}
|
|
temp_i = 0;
|
|
mode = 0;
|
|
if (last_data != NULL)
|
|
last_data->next = inventory_data;
|
|
last_data = inventory_data;
|
|
inventory_data = newInventoryData();
|
|
break;
|
|
case ',':
|
|
temp_string[temp_i] = '\0';
|
|
if (mode == 0) {
|
|
inventory_data->name = realloc(inventory_data->name, temp_i+1);
|
|
memcpy(inventory_data->name, temp_string, temp_i+1);
|
|
} else if (mode == 1) {
|
|
char chance_buffer[64];
|
|
int ch_buffer_i = 0;
|
|
int temp_offset = 0;
|
|
int c_mode = 0;
|
|
while (temp_offset != temp_i) {
|
|
switch(temp_string[temp_offset]) {
|
|
case '-':
|
|
chance_buffer[ch_buffer_i] = '\0';
|
|
inventory_data->count.min = atoi(chance_buffer);
|
|
c_mode = 1;
|
|
ch_buffer_i = 0;
|
|
break;
|
|
default:
|
|
chance_buffer[ch_buffer_i++] = temp_string[temp_offset];
|
|
break;
|
|
}
|
|
temp_offset++;
|
|
}
|
|
chance_buffer[ch_buffer_i] = '\0';
|
|
if (c_mode == 0)
|
|
inventory_data->count.min = atoi(chance_buffer);
|
|
inventory_data->count.max = atoi(chance_buffer);
|
|
} else if (mode == 2) {
|
|
inventory_data->chance = atof(temp_string);
|
|
}
|
|
temp_i = 0;
|
|
mode++;
|
|
break;
|
|
default:
|
|
temp_string[temp_i++] = memory[*offset];
|
|
break;
|
|
}
|
|
*offset = *offset + 1;
|
|
}
|
|
return first_data;
|
|
}
|
|
|
|
struct TileSetData *getTileSetData(struct Data *data, int tileset_id) {
|
|
if (tileset_id > data->size) {
|
|
return NULL;
|
|
}
|
|
if (data->set[tileset_id] != NULL) {
|
|
return data->set[tileset_id];
|
|
}
|
|
return NULL;
|
|
}
|
|
/*struct TileData *getTileDataByKey(struct TileSetData *set, char *key) {
|
|
int *tid = getTablePairValue(data->set[data_set]->keys, key);
|
|
if (tid != NULL) {
|
|
return data->set[data_set]->tile[*tid];
|
|
}
|
|
return NULL;
|
|
}*/
|
|
|
|
void freeTileData(struct TileData *tile_data) {
|
|
freeTable(tile_data->table);
|
|
free(tile_data);
|
|
}
|
|
|
|
struct Table *newTable(int size) {
|
|
struct Table *table = malloc(sizeof(struct Table));
|
|
table->size = size;
|
|
table->pair = malloc(sizeof(struct TablePair*)*size);
|
|
int i = 0;
|
|
while (i != size) {
|
|
table->pair[i++] = NULL;
|
|
}
|
|
//memset(table->pair, sizeof(struct TablePair*)*size, NULL);
|
|
return table;
|
|
}
|
|
|
|
void freeTable(struct Table *table) {
|
|
int i = 0;
|
|
while (i < table->size) {
|
|
if (table->pair[i] != NULL) {
|
|
freeTablePair(table->pair[i]);
|
|
}
|
|
i++;
|
|
}
|
|
free(table->pair);
|
|
free(table);
|
|
}
|
|
|
|
int getTableIndex(struct Table *table, const char *key) {
|
|
if (key == NULL)
|
|
return -1;
|
|
int i = 0;
|
|
int index = 0;
|
|
int key_length = strlen(key);
|
|
while (index < INT_MAX && i < key_length) {
|
|
index += key[i++];
|
|
}
|
|
return index % table->size;
|
|
}
|
|
|
|
struct TileData *getTileDataByKey(struct Data *data, char *key) {
|
|
int data_set = 0;
|
|
while (data_set < data->size) {
|
|
if (data->set[data_set] != NULL) {
|
|
int *tid = getTablePairValue(data->set[data_set]->keys, key);
|
|
if (tid != NULL) {
|
|
return data->set[data_set]->tile[*tid];
|
|
}
|
|
}
|
|
data_set++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
struct TileData *getTileDataById(struct Data *data, int tileset_id, int tile_id) {
|
|
if (tile_id >= data->size) {
|
|
return NULL;
|
|
}
|
|
if (data->set[tileset_id] != NULL) {
|
|
if (data->set[tileset_id]->tile[tile_id] != NULL) {
|
|
return data->set[tileset_id]->tile[tile_id];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
struct TablePair *getTablePair(struct Table *table, const char *key) {
|
|
if (table == NULL)
|
|
return NULL;
|
|
struct TablePair *pair = table->pair[getTableIndex(table, key)];
|
|
while (pair != NULL) {
|
|
if (strcmp(key, pair->key) == 0) {
|
|
return pair;
|
|
}
|
|
pair = pair->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*int deleteTablePair(struct Table *table, char *key) {
|
|
int index = getTableIndex(table, key);
|
|
struct TablePair *pair = table->pair[index];
|
|
if (strcmp(key, pair->key) == 0) {
|
|
table->pair[index] = pair->next;
|
|
freeTablePair(pair);
|
|
return 0;
|
|
}
|
|
struct TablePair *previous = NULL;
|
|
pair = pair->next;
|
|
// not yet found, let's go down the chain
|
|
while (pair != NULL) {
|
|
if (strcmp(key, pair->key) == 0) {
|
|
// found it, now let's free and repair the Table
|
|
previous->next = pair->next;
|
|
freeTablePair(pair);
|
|
return 0;
|
|
}
|
|
previous = pair;
|
|
pair = pair->next;
|
|
}
|
|
return -1; // if we reach here, that means it didn't exist
|
|
}*/
|
|
|
|
/**** getTablePairValue
|
|
Attempts to return the TablePair value of given key. If the TablePair's type is of T_INT, T_FLOAT, or other such values, the
|
|
****/
|
|
void *getTablePairValue(struct Table *table, const char *key) {
|
|
struct TablePair *pair = getTablePair(table, key);
|
|
if (pair != NULL) {
|
|
return pair->value;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int addTablePair(struct Table *table, const char *key, void *value, int value_size, int type) {
|
|
if (key == NULL || value == NULL)
|
|
return -10;
|
|
int index = getTableIndex(table, key);
|
|
if (table->pair[index] == NULL) {
|
|
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
|
|
if (table_pair == NULL)
|
|
return -1;
|
|
table_pair->next = NULL;
|
|
setTablePair(table_pair, key, value, value_size, type);
|
|
table->pair[index] = table_pair;
|
|
table->count++;
|
|
} else {
|
|
struct TablePair *current_pair = table->pair[index];
|
|
while (1) {
|
|
if (strcmp(key, current_pair->key) == 0) {
|
|
current_pair->value = value;
|
|
break;
|
|
} else {
|
|
if (current_pair->next == NULL) {
|
|
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
|
|
if (table_pair == NULL)
|
|
return -2;
|
|
table_pair->next = NULL;
|
|
setTablePair(table_pair, key, value, value_size, type);
|
|
current_pair->next = table_pair;
|
|
table->count++;
|
|
break;
|
|
} else {
|
|
current_pair = current_pair->next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int deleteTablePair(struct Table *table, char *key) {
|
|
if (key == NULL)
|
|
return -10;
|
|
int index = getTableIndex(table, key);
|
|
if (table->pair[index] == NULL) {
|
|
// does not exist
|
|
return -1;
|
|
} else {
|
|
struct TablePair *current_pair = table->pair[index];
|
|
struct TablePair *last_pair = NULL;
|
|
while (1) {
|
|
if (strcmp(key, current_pair->key) == 0) {
|
|
// we have a match, so let's repair the chain if needed
|
|
if (current_pair->next != NULL) {
|
|
last_pair->next = current_pair->next;
|
|
}
|
|
freeTablePair(current_pair);
|
|
table->count--;
|
|
break;
|
|
} else {
|
|
if (current_pair->next == NULL) {
|
|
// does not exist
|
|
return -1;
|
|
} else {
|
|
last_pair = current_pair;
|
|
current_pair = current_pair->next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int addTablePairPointer(struct Table *table, const char *key, void *value, int type) {
|
|
if (key == NULL || value == NULL)
|
|
return -10;
|
|
int index = getTableIndex(table, key);
|
|
if (table->pair[index] == NULL) {
|
|
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
|
|
if (table_pair == NULL)
|
|
return -1;
|
|
setTablePairPointer(table_pair, key, value, type);
|
|
table->pair[index] = table_pair;
|
|
table->count++;
|
|
} else {
|
|
struct TablePair *current_pair = table->pair[index];
|
|
while (1) {
|
|
if (strcmp(key, current_pair->key) == 0) {
|
|
current_pair->value = value;
|
|
break;
|
|
} else {
|
|
if (current_pair->next == NULL) {
|
|
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
|
|
if (table_pair == NULL)
|
|
return -2;
|
|
setTablePairPointer(table_pair, key, value, type);
|
|
current_pair->next = table_pair;
|
|
table->count++;
|
|
break;
|
|
} else {
|
|
current_pair = current_pair->next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void setTablePair(struct TablePair *table_pair, const char *key, void *value, int value_size, int type) {
|
|
int key_size = strlen(key)+1;
|
|
table_pair->key = malloc(key_size);
|
|
memcpy(table_pair->key, key, key_size);
|
|
|
|
table_pair->value = malloc(value_size);
|
|
memcpy(table_pair->value, value, value_size);
|
|
|
|
table_pair->type = type;
|
|
table_pair->next = NULL;
|
|
}
|
|
|
|
void setTablePairPointer(struct TablePair *table_pair, const char *key, void *value, int type) {
|
|
int key_size = strlen(key)+1;
|
|
table_pair->key = malloc(key_size);
|
|
memcpy(table_pair->key, key, key_size);
|
|
|
|
table_pair->value = value;
|
|
|
|
table_pair->type = type;
|
|
table_pair->next = NULL;
|
|
}
|
|
|
|
|
|
void freeTablePair(struct TablePair *table_pair) {
|
|
struct TablePair *pair = table_pair;
|
|
while (pair != NULL) {
|
|
struct TablePair *sub_pair = pair->next;
|
|
free(pair->key);
|
|
switch (pair->type) {
|
|
case T_PROTO_INVENTORY:
|
|
freeInventoryData(pair->value);
|
|
break;
|
|
default:
|
|
free(pair->value);
|
|
break;
|
|
}
|
|
free(pair);
|
|
pair = sub_pair;
|
|
}
|
|
}
|
|
|
|
/**** fileToMemory
|
|
This function takes a pointer to an uninitialized char array, along with a char array for a file name. It then attempts to read the provided file into the passed buffer, returning the size on completion.
|
|
****/
|
|
int fileToMemory(char **buffer, const char *file_name) {
|
|
int i, n, pos = 0;
|
|
char t_buf[16];
|
|
|
|
FILE *file = fopen(file_name, "r");
|
|
if (file == NULL) {
|
|
return -1;
|
|
}
|
|
fseek(file, 0, SEEK_END);
|
|
int size = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
char *new_buffer = malloc(size);
|
|
while ((n = fread(t_buf, 1, 16, file))) {
|
|
for (i = 0; i < n; i++) {
|
|
new_buffer[pos++] = t_buf[i];
|
|
}
|
|
}
|
|
fclose(file);
|
|
*buffer = new_buffer;
|
|
return size;
|
|
}
|