diff --git a/scripts/tests/storage.lua b/scripts/tests/storage.lua index 0aa0b45f7..c262652db 100644 --- a/scripts/tests/storage.lua +++ b/scripts/tests/storage.lua @@ -26,8 +26,8 @@ function test_store_unit() assert_not_nil(store) u = store:read_unit() assert_not_nil(u) - assert_equal(r, u.region) assert_equal(f, u.faction) + assert_equal(nil, u.region) store:close() os.remove(filename) assert_not_nil(u) diff --git a/src/bind_storage.c b/src/bind_storage.c index ba96791af..ca83f199a 100644 --- a/src/bind_storage.c +++ b/src/bind_storage.c @@ -33,40 +33,12 @@ static int tolua_storage_create(lua_State * L) { const char *filename = tolua_tostring(L, 1, 0); const char *type = tolua_tostring(L, 2, "rb"); - FILE * F; - int err = 0; - size_t sz; + gamedata *data; - F = fopen(filename, type); - if (F) { - gamedata *data = (gamedata *)calloc(1, sizeof(gamedata)); - storage *store = (storage *)calloc(1, sizeof(storage)); - data->store = store; - if (strchr(type, 'r')) { - sz = fread(&data->version, sizeof(int), 1, F); - if (sz != sizeof(int)) { - err = ferror(F); - } - else { - err = fseek(F, sizeof(int), SEEK_CUR); - } - } - else if (strchr(type, 'w')) { - int n = STREAM_VERSION; - data->version = RELEASE_VERSION; - fwrite(&data->version, sizeof(int), 1, F); - fwrite(&n, sizeof(int), 1, F); - } - if (err) { - fclose(F); - free(data); - free(store); - } else { - fstream_init(&data->strm, F); - binstore_init(store, &data->strm); - tolua_pushusertype(L, (void *)data, TOLUA_CAST "storage"); - return 1; - } + data = gamedata_open(filename, type); + if (data) { + tolua_pushusertype(L, (void *)data, TOLUA_CAST "storage"); + return 1; } return 0; } @@ -134,8 +106,7 @@ static int tolua_storage_tostring(lua_State * L) static int tolua_storage_close(lua_State * L) { gamedata *data = (gamedata *)tolua_tousertype(L, 1, 0); - binstore_done(data->store); - fstream_done(&data->strm); + gamedata_close(data); return 0; } diff --git a/src/kernel/save.c b/src/kernel/save.c index 3111c09e5..cb942c83f 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1887,6 +1887,50 @@ int writegame(const char *filename) return 0; } +void gamedata_close(gamedata *data) { + binstore_done(data->store); + fstream_done(&data->strm); +} + +gamedata *gamedata_open(const char *filename, const char *mode) { + FILE *F = fopen(filename, mode); + + if (F) { + gamedata *data = (gamedata *)calloc(1, sizeof(gamedata)); + storage *store = (storage *)calloc(1, sizeof(storage)); + int err = 0; + size_t sz; + + data->store = store; + if (strchr(mode, 'r')) { + sz = fread(&data->version, 1, sizeof(int), F); + if (sz != sizeof(int)) { + err = ferror(F); + } + else { + err = fseek(F, sizeof(int), SEEK_CUR); + } + } + else if (strchr(mode, 'w')) { + int n = STREAM_VERSION; + data->version = RELEASE_VERSION; + fwrite(&data->version, sizeof(int), 1, F); + fwrite(&n, sizeof(int), 1, F); + } + if (err) { + fclose(F); + free(data); + free(store); + } + else { + fstream_init(&data->strm, F); + binstore_init(store, &data->strm); + return data; + } + } + return 0; +} + int a_readint(attrib * a, void *owner, struct storage *store) { /* assert(sizeof(int)==sizeof(a->data)); */ diff --git a/src/kernel/save.h b/src/kernel/save.h index 11b53d620..ca364fc9c 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -42,44 +42,46 @@ extern "C" { /* Nach MAX_INPUT_SIZE brechen wir das Einlesen der Zeile ab und nehmen an, * dass hier ein Fehler (fehlende ") vorliegt */ + extern int data_version; + extern int enc_gamedata; + int readorders(const char *filename); int creategame(void); int readgame(const char *filename, bool backup); int writegame(const char *filename); - /* Versionsänderungen: */ - extern int data_version; - extern int enc_gamedata; + int current_turn(void); - extern int current_turn(void); + void read_items(struct storage *store, struct item **it); + void write_items(struct storage *store, struct item *it); - extern void read_items(struct storage *store, struct item **it); - extern void write_items(struct storage *store, struct item *it); + void read_spellbook(struct spellbook **bookp, struct storage *store, int(*get_level)(const struct spell * sp, void *), void * cbdata); + void write_spellbook(const struct spellbook *book, struct storage *store); - extern void read_spellbook(struct spellbook **bookp, struct storage *store, int(*get_level)(const struct spell * sp, void *), void * cbdata); - extern void write_spellbook(const struct spellbook *book, struct storage *store); + void write_unit(struct gamedata *data, const struct unit *u); + struct unit *read_unit(struct gamedata *data); - extern void write_unit(struct gamedata *data, const struct unit *u); - extern struct unit *read_unit(struct gamedata *data); + int a_readint(struct attrib *a, void *owner, struct storage *store); + void a_writeint(const struct attrib *a, const void *owner, + struct storage *store); + int a_readshorts(struct attrib *a, void *owner, struct storage *store); + void a_writeshorts(const struct attrib *a, const void *owner, + struct storage *store); + int a_readchars(struct attrib *a, void *owner, struct storage *store); + void a_writechars(const struct attrib *a, const void *owner, + struct storage *store); + int a_readvoid(struct attrib *a, void *owner, struct storage *store); + void a_writevoid(const struct attrib *a, const void *owner, + struct storage *store); + int a_readstring(struct attrib *a, void *owner, struct storage *store); + void a_writestring(const struct attrib *a, const void *owner, + struct storage *store); + void a_finalizestring(struct attrib *a); - extern int a_readint(struct attrib *a, void *owner, struct storage *store); - extern void a_writeint(const struct attrib *a, const void *owner, - struct storage *store); - extern int a_readshorts(struct attrib *a, void *owner, struct storage *store); - extern void a_writeshorts(const struct attrib *a, const void *owner, - struct storage *store); - extern int a_readchars(struct attrib *a, void *owner, struct storage *store); - extern void a_writechars(const struct attrib *a, const void *owner, - struct storage *store); - extern int a_readvoid(struct attrib *a, void *owner, struct storage *store); - extern void a_writevoid(const struct attrib *a, const void *owner, - struct storage *store); - extern int a_readstring(struct attrib *a, void *owner, struct storage *store); - extern void a_writestring(const struct attrib *a, const void *owner, - struct storage *store); - extern void a_finalizestring(struct attrib *a); + void create_backup(char *file); - extern void create_backup(char *file); + struct gamedata *gamedata_open(const char *filename, const char *mode); + void gamedata_close(struct gamedata *data); #ifdef __cplusplus } diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index 26f48a07f..fd8ff48ea 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -2,6 +2,8 @@ #include #include "save.h" +#include "unit.h" +#include "faction.h" #include "version.h" #include #include @@ -21,9 +23,45 @@ static void test_readwrite_data(CuTest * tc) test_cleanup(); } +static void test_readwrite_unit(CuTest * tc) +{ + const char *filename = "test.dat"; + char path[MAX_PATH]; + gamedata *data; + struct unit *u; + struct region *r; + struct faction *f; + int fno; + + test_cleanup(); + r = test_create_region(0, 0, 0); + f = test_create_faction(0); + fno = f->no; + u = test_create_unit(f, r); + sprintf(path, "%s/%s", datapath(), filename); + + data = gamedata_open(path, "wb"); + write_unit(data, u); + gamedata_close(data); + + free_gamedata(); + f = test_create_faction(0); + renumber_faction(f, fno); + data = gamedata_open(path, "rb"); + u = read_unit(data); + gamedata_close(data); + + CuAssertPtrNotNull(tc, u); + CuAssertPtrEquals(tc, f, u->faction); + CuAssertPtrEquals(tc, 0, u->region); + CuAssertIntEquals(tc, 0, remove(path)); + test_cleanup(); +} + CuSuite *get_save_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_readwrite_data); + SUITE_ADD_TEST(suite, test_readwrite_unit); return suite; } diff --git a/storage b/storage index 86b967441..1d92cb36d 160000 --- a/storage +++ b/storage @@ -1 +1 @@ -Subproject commit 86b96744157eb08c55998df4c12fa2e073005b49 +Subproject commit 1d92cb36df41c183c378aad17cbbfc0eddbb5c84