refactor: extract read_/write_ship functions.

add test: bad names are cleaned up (failing).
This commit is contained in:
Enno Rehling 2016-11-11 22:25:56 +01:00
parent 110e87916d
commit 5032d44af4
3 changed files with 108 additions and 52 deletions

View File

@ -1673,9 +1673,68 @@ struct building *read_building(gamedata *data) {
return b; return b;
} }
int read_game(gamedata *data) { void write_ship(gamedata *data, const ship *sh)
{
storage *store = data->store;
write_ship_reference(sh, store);
WRITE_STR(store, (const char *)sh->name);
WRITE_STR(store, sh->display ? (const char *)sh->display : "");
WRITE_TOK(store, sh->type->_name);
WRITE_INT(store, sh->size);
WRITE_INT(store, sh->damage);
WRITE_INT(store, sh->flags & SFL_SAVEMASK);
assert((sh->type->flags & SFL_NOCOAST) == 0 || sh->coast == NODIRECTION);
WRITE_INT(store, sh->coast);
write_attribs(store, sh->attribs, sh);
}
ship *read_ship(struct gamedata *data)
{
char name[DISPLAYSIZE]; char name[DISPLAYSIZE];
int n, p, nread; ship *sh;
int n;
storage *store = data->store;
sh = (ship *)calloc(1, sizeof(ship));
READ_INT(store, &sh->no);
shash(sh);
READ_STR(store, name, sizeof(name));
sh->name = _strdup(name);
if (lomem) {
READ_STR(store, NULL, 0);
}
else {
READ_STR(store, name, sizeof(name));
sh->display = _strdup(name);
}
READ_STR(store, name, sizeof(name));
sh->type = st_find(name);
if (sh->type == NULL) {
/* old datafiles */
sh->type = st_find((const char *)LOC(default_locale, name));
}
assert(sh->type || !"ship_type not registered!");
READ_INT(store, &sh->size);
READ_INT(store, &sh->damage);
if (data->version >= FOSS_VERSION) {
READ_INT(store, &sh->flags);
}
/* Attribute rekursiv einlesen */
READ_INT(store, &n);
sh->coast = (direction_t)n;
if (sh->type->flags & SFL_NOCOAST) {
sh->coast = NODIRECTION;
}
read_attribs(data, &sh->attribs, sh);
return sh;
}
int read_game(gamedata *data) {
int p, nread;
faction *f, **fp; faction *f, **fp;
region *r; region *r;
building **bp; building **bp;
@ -1755,10 +1814,10 @@ int read_game(gamedata *data) {
while (--p >= 0) { while (--p >= 0) {
building *b = *bp = read_building(data); building *b = *bp = read_building(data);
b->region = r;
if (b->type == bt_lighthouse) { if (b->type == bt_lighthouse) {
r->flags |= RF_LIGHTHOUSE; r->flags |= RF_LIGHTHOUSE;
} }
b->region = r;
bp = &b->next; bp = &b->next;
} }
/* Schiffe */ /* Schiffe */
@ -1767,43 +1826,9 @@ int read_game(gamedata *data) {
shp = &r->ships; shp = &r->ships;
while (--p >= 0) { while (--p >= 0) {
ship *sh = (ship *)calloc(1, sizeof(ship)); ship *sh = *shp = read_ship(data);
sh->region = r; sh->region = r;
READ_INT(store, &sh->no);
*shp = sh;
shp = &sh->next; shp = &sh->next;
shash(sh);
READ_STR(store, name, sizeof(name));
sh->name = _strdup(name);
if (lomem) {
READ_STR(store, NULL, 0);
}
else {
READ_STR(store, name, sizeof(name));
sh->display = _strdup(name);
}
READ_STR(store, name, sizeof(name));
sh->type = st_find(name);
if (sh->type == NULL) {
/* old datafiles */
sh->type = st_find((const char *)LOC(default_locale, name));
}
assert(sh->type || !"ship_type not registered!");
READ_INT(store, &sh->size);
READ_INT(store, &sh->damage);
if (data->version >= FOSS_VERSION) {
READ_INT(store, &sh->flags);
}
/* Attribute rekursiv einlesen */
READ_INT(store, &n);
sh->coast = (direction_t)n;
if (sh->type->flags & SFL_NOCOAST) {
sh->coast = NODIRECTION;
}
read_attribs(data, &sh->attribs, sh);
} }
*shp = 0; *shp = 0;
@ -2006,6 +2031,7 @@ int write_game(gamedata *data) {
WRITE_INT(store, listlen(r->buildings)); WRITE_INT(store, listlen(r->buildings));
WRITE_SECTION(store); WRITE_SECTION(store);
for (b = r->buildings; b; b = b->next) { for (b = r->buildings; b; b = b->next) {
assert(b->region == r);
write_building(data, b); write_building(data, b);
} }
@ -2013,23 +2039,13 @@ int write_game(gamedata *data) {
WRITE_SECTION(store); WRITE_SECTION(store);
for (sh = r->ships; sh; sh = sh->next) { for (sh = r->ships; sh; sh = sh->next) {
assert(sh->region == r); assert(sh->region == r);
write_ship_reference(sh, store); write_ship(data, sh);
WRITE_STR(store, (const char *)sh->name);
WRITE_STR(store, sh->display ? (const char *)sh->display : "");
WRITE_TOK(store, sh->type->_name);
WRITE_INT(store, sh->size);
WRITE_INT(store, sh->damage);
WRITE_INT(store, sh->flags & SFL_SAVEMASK);
assert((sh->type->flags & SFL_NOCOAST) == 0 || sh->coast == NODIRECTION);
WRITE_INT(store, sh->coast);
WRITE_SECTION(store);
write_attribs(store, sh->attribs, sh);
WRITE_SECTION(store);
} }
WRITE_INT(store, listlen(r->units)); WRITE_INT(store, listlen(r->units));
WRITE_SECTION(store); WRITE_SECTION(store);
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
assert(u->region == r);
write_unit(data, u); write_unit(data, u);
} }
} }

View File

@ -30,6 +30,8 @@ extern "C" {
struct spell; struct spell;
struct spellbook; struct spellbook;
struct unit; struct unit;
struct building;
struct ship;
struct gamedata; struct gamedata;
#define MAX_INPUT_SIZE DISPLAYSIZE*2 #define MAX_INPUT_SIZE DISPLAYSIZE*2
@ -61,6 +63,9 @@ extern "C" {
void write_building(struct gamedata *data, const struct building *b); void write_building(struct gamedata *data, const struct building *b);
struct building *read_building(struct gamedata *data); struct building *read_building(struct gamedata *data);
void write_ship(struct gamedata *data, const struct ship *sh);
struct ship *read_ship(struct gamedata *data);
int a_readint(struct attrib *a, void *owner, struct gamedata *); int a_readint(struct attrib *a, void *owner, struct gamedata *);
void a_writeint(const struct attrib *a, const void *owner, void a_writeint(const struct attrib *a, const void *owner,
struct storage *store); struct storage *store);

View File

@ -7,6 +7,7 @@
#include "save.h" #include "save.h"
#include "version.h" #include "version.h"
#include "building.h" #include "building.h"
#include "ship.h"
#include "unit.h" #include "unit.h"
#include "group.h" #include "group.h"
#include "ally.h" #include "ally.h"
@ -85,8 +86,8 @@ static void test_readwrite_building(CuTest * tc)
{ {
gamedata data; gamedata data;
storage store; storage store;
struct building *b; building *b;
struct region *r; region *r;
test_setup(); test_setup();
r = test_create_region(0, 0, 0); r = test_create_region(0, 0, 0);
@ -114,6 +115,39 @@ static void test_readwrite_building(CuTest * tc)
test_cleanup(); test_cleanup();
} }
static void test_readwrite_ship(CuTest * tc)
{
gamedata data;
storage store;
ship *sh;
region *r;
test_setup();
r = test_create_region(0, 0, 0);
sh = test_create_ship(r, 0);
free(sh->name);
sh->name = _strdup(" Hodor ");
CuAssertStrEquals(tc, " Hodor ", sh->name);
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
write_ship(&data, sh);
data.strm.api->rewind(data.strm.handle);
free_gamedata();
r = test_create_region(0, 0, 0);
gamedata_init(&data, &store, RELEASE_VERSION);
sh = read_ship(&data);
CuAssertPtrNotNull(tc, sh);
CuAssertStrEquals(tc, "Hodor", sh->name);
CuAssertPtrEquals(tc, 0, sh->region);
sh->region = r;
r->ships = sh;
mstream_done(&data.strm);
gamedata_done(&data);
test_cleanup();
}
static void test_readwrite_attrib(CuTest *tc) { static void test_readwrite_attrib(CuTest *tc) {
gamedata data; gamedata data;
storage store; storage store;
@ -364,6 +398,7 @@ CuSuite *get_save_suite(void)
SUITE_ADD_TEST(suite, test_readwrite_data); SUITE_ADD_TEST(suite, test_readwrite_data);
SUITE_ADD_TEST(suite, test_readwrite_unit); SUITE_ADD_TEST(suite, test_readwrite_unit);
SUITE_ADD_TEST(suite, test_readwrite_building); SUITE_ADD_TEST(suite, test_readwrite_building);
SUITE_ADD_TEST(suite, test_readwrite_ship);
SUITE_ADD_TEST(suite, test_readwrite_dead_faction_createunit); SUITE_ADD_TEST(suite, test_readwrite_dead_faction_createunit);
SUITE_ADD_TEST(suite, test_readwrite_dead_faction_changefaction); SUITE_ADD_TEST(suite, test_readwrite_dead_faction_changefaction);
SUITE_ADD_TEST(suite, test_readwrite_dead_faction_regionowner); SUITE_ADD_TEST(suite, test_readwrite_dead_faction_regionowner);