From c05aad1b14772ffa82fa96554f60cf743a56e39a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 Apr 2008 09:52:03 +0000 Subject: [PATCH] - binary storage uses packed int - creport: disabled writing of r->uid - creport: fixed missing quotes --- src/common/gamecode/creport.c | 13 +++- src/common/kernel/binarystore.c | 118 ++++++++++++++++++++++++++++---- src/common/kernel/curse.c | 13 +--- src/common/kernel/save.c | 8 --- src/common/kernel/save.h | 2 - src/common/kernel/version.h | 3 +- src/scripts/run-tests.lua | 10 +-- 7 files changed, 127 insertions(+), 40 deletions(-) diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 2d136f1a0..0d0a2acf8 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -637,7 +637,16 @@ cr_output_ship(FILE * F, const ship * sh, const unit * u, int fcaptain, const fa print_curses(F, f, sh, TYP_SHIP); } -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ + +static void +fwriteorder(FILE * F, const struct order * ord, const struct locale * lang) +{ + char obuf[1024]; + fputc('"', F); + write_order(ord, lang, obuf, sizeof(obuf)); + if (obuf[0]) fputs(obuf, F); + fputc('"', F); +} /* prints all that belongs to a unit */ static void @@ -1319,7 +1328,7 @@ report_computer(const char * filename, report_context * ctx, const char * charse #endif else fprintf(F, "REGION %d %d %d\n", region_x(r, f), region_y(r, f), r->planep->id); } - fprintf(F, "\"%d\";id\n", r->uid); + /* fprintf(F, "\"%d\";id\n", r->uid); */ if (r->land) { const char * str = rname(r, f->locale); if (str && str[0]) { diff --git a/src/common/kernel/binarystore.c b/src/common/kernel/binarystore.c index 4342e650f..d79b5eab9 100644 --- a/src/common/kernel/binarystore.c +++ b/src/common/kernel/binarystore.c @@ -21,12 +21,94 @@ without prior permission by the authors of Eressea. #include #define file(store) (FILE *)((store)->userdata) + +#define STREAM_VERSION 1 + +INLINE_FUNCTION size_t +pack_int(int v, char * buffer) +{ + int sign = (v<0); + + if (sign) { + v = ~v + 1; + sign = 0x40; + } + if (v<0x40) { + buffer[0] = (char)(v | sign); + return 1; + } else if (v<0x2000) { + buffer[0] = (char)((v>> 6) | 0x80); + buffer[1] = (char)((v & 0x3F) | sign); + return 2; + } else if (v<0x100000) { + buffer[0] = (char)((v>>13) & 0x7f | 0x80); + buffer[1] = (char)((v>> 6) & 0x7f | 0x80); + buffer[2] = (char)((v & 0x3F) | sign); + return 3; + } else if (v<0x8000000) { + buffer[0] = (char)((v>>20) & 0x7f | 0x80); + buffer[1] = (char)((v>>13) & 0x7f | 0x80); + buffer[2] = (char)((v>> 6) & 0x7f | 0x80); + buffer[3] = (char)((v & 0x3F) | sign); + return 4; + } + buffer[0] = (char)((v>>27) & 0x7f | 0x80); + buffer[1] = (char)((v>>20) & 0x7f | 0x80); + buffer[2] = (char)((v>>13) & 0x7f | 0x80); + buffer[3] = (char)((v>> 6) & 0x7f | 0x80); + buffer[4] = (char)((v & 0x3F) | sign); + return 5; +} + +INLINE_FUNCTION int +unpack_int(const char * buffer) +{ + int i = 0, v = 0; + + while (buffer[i] & 0x80) { + v = (v << 7) | (buffer[i++] & 0x7f); + } + v = (v << 6) | (buffer[i] & 0x3f); + + if (buffer[i] & 0x40) { + v = ~v + 1; + } + return v; +} + static int bin_w_brk(struct storage * store) { return 0; } +static int +bin_w_int_pak(struct storage * store, int arg) +{ + char buffer[5]; + size_t size = pack_int(arg, buffer); + return (int)fwrite(buffer, sizeof(char), size, file(store)); +} + +static int +bin_r_int_pak(struct storage * store) +{ + int v = 0; + char ch; + + fread(&ch, sizeof(char), 1, file(store)); + while (ch & 0x80) { + v = (v << 7) | (ch & 0x7f); + fread(&ch, sizeof(char), 1, file(store)); + } + v = (v << 6) | (ch & 0x3f); + + if (ch & 0x40) { + v = ~v + 1; + } + return v; +} + static int bin_w_int(struct storage * store, int arg) { @@ -60,21 +142,21 @@ bin_w_str(struct storage * store, const char * tok) { int result; if (tok==NULL || tok[0]==0) { - static const int empty = 0; - result = (int)fwrite(&empty, sizeof(int), 1, file(store)); + result = store->w_int(store, 0); } else { int size = (int)strlen(tok); - result = (int)fwrite(&size, sizeof(int), 1, file(store)); + result = store->w_int(store, size); result += (int)fwrite(tok, size, 1, file(store)); } return result; } + static char * bin_r_str(struct storage * store) { int len; - fread(&len, sizeof(len), 1, file(store)); + len = store->r_int(store); if (len) { char * result = malloc(len+1); @@ -84,13 +166,14 @@ bin_r_str(struct storage * store) } return NULL; } + static void bin_r_str_buf(struct storage * store, char * result, size_t size) { int i; size_t rd, len; - fread(&i, sizeof(int), 1, file(store)); + i = store->r_int(store); assert(i>=0); if (i==0) { result[0] = 0; @@ -116,9 +199,18 @@ bin_open(struct storage * store, const char * filename, int mode) store->encoding=XML_CHAR_ENCODING_UTF8; /* always utf8 it is */ if (F) { if (mode==IO_READ) { - store->version = store->r_int(store); + int stream_version = 0; + store->version = bin_r_int(store); + if (store->version>=INTPAK_VERSION) { + stream_version = bin_r_int(store); + } + if (stream_version==0) { + store->r_int = bin_r_int; + store->w_int = bin_w_int; + } } else if (store->encoding==XML_CHAR_ENCODING_UTF8) { - store->w_int(store, RELEASE_VERSION); + bin_w_int(store, RELEASE_VERSION); + bin_w_int(store, STREAM_VERSION); } } return (F==NULL); @@ -131,12 +223,12 @@ bin_close(struct storage * store) } const storage binary_store = { - bin_w_brk, - bin_w_int, bin_r_int, - bin_w_flt, bin_r_flt, - bin_w_int, bin_r_int, - bin_w_str, bin_r_str, bin_r_str_buf, - bin_w_str, bin_r_str, bin_r_str_buf, + bin_w_brk, /* newline (ignore) */ + bin_w_int_pak, bin_r_int_pak, /* int storage */ + bin_w_flt, bin_r_flt, /* float storage */ + bin_w_int, bin_r_int, /* id storage */ + bin_w_str, bin_r_str, bin_r_str_buf, /* token storage */ + bin_w_str, bin_r_str, bin_r_str_buf, /* string storage */ bin_open, bin_close, 0, 0, NULL }; diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index 68970c927..7d823fb90 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -176,7 +176,7 @@ curse_read(attrib * a, struct storage * store) int vigour = store->r_int(store); c->vigour = vigour; } - if (store->versionversionr_int(store); if (mageid.i <= 0) { @@ -221,26 +221,19 @@ void curse_write(const attrib * a, struct storage * store) { unsigned int flags; - int mage_no; curse * c = (curse*)a->data.v; const curse_type * ct = c->type; + unit * mage = (c->magician && c->magician->number)?c->magician:NULL; /* copied from c_clearflag */ flags = (c->flags & ~CURSE_ISNEW) | (c->type->flags & CURSE_ISNEW); - if (c->magician && c->magician->number) { - mage_no = c->magician->no; - assert(mage_no>0); - } else { - mage_no = -1; - } - store->w_int(store, c->no); store->w_tok(store, ct->cname); store->w_int(store, flags); store->w_int(store, c->duration); store->w_flt(store, (float)c->vigour); - store->w_int(store, mage_no); + write_unit_reference(mage, store); store->w_int(store, c->effect.i); if (c->type->write) c->type->write(store, c); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index c202db593..b1428e66c 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -834,14 +834,6 @@ lastturn(void) return turn; } -void -fwriteorder(FILE * F, const struct order * ord, const struct locale * lang) -{ - char obuf[1024]; - write_order(ord, lang, obuf, sizeof(obuf)); - if (obuf[0]) fputs(obuf, F); -} - static void writeorder(struct storage * store, const struct order * ord, const struct locale * lang) { diff --git a/src/common/kernel/save.h b/src/common/kernel/save.h index 7662b6c42..ed1ea783a 100644 --- a/src/common/kernel/save.h +++ b/src/common/kernel/save.h @@ -59,8 +59,6 @@ extern void write_items(struct storage * store, struct item *it); extern const char * datapath(void); -extern void fwriteorder(FILE * F, const struct order * ord, const struct locale * lang); - extern int a_readint(struct attrib * a, struct storage * store); extern void a_writeint(const struct attrib * a, struct storage * store); extern int a_readshorts(struct attrib * a, struct storage * store); diff --git a/src/common/kernel/version.h b/src/common/kernel/version.h index a088c11ce..b783ef15e 100644 --- a/src/common/kernel/version.h +++ b/src/common/kernel/version.h @@ -54,6 +54,7 @@ #define UNICODE_VERSION 326 /* everything is stored as UTF8 */ #define UID_VERSION 327 /* regions have a unique id */ #define STORAGE_VERSION 328 /* with storage.h, some things are stored smarter (ids as base36, fractions as float) */ +#define INTPAK_VERSION 329 /* in binary, ints can get packed */ #define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */ -#define RELEASE_VERSION STORAGE_VERSION /* current datafile */ +#define RELEASE_VERSION INTPAK_VERSION /* current datafile */ diff --git a/src/scripts/run-tests.lua b/src/scripts/run-tests.lua index d0dc552f9..70629a5c2 100644 --- a/src/scripts/run-tests.lua +++ b/src/scripts/run-tests.lua @@ -12,12 +12,14 @@ end test_locales() local now = os.clock() ---read_game("566", "text") ---write_game("566.dat", "binary") read_game("566.dat", "binary") +--read_game("566", "text") local elapsed = os.clock() - now --- text: 51.203 --- binary: 20.859 print(elapsed) +-- text: 50.574 +-- bin0: 19.547 +-- bin1: 18.953 + +write_game("566.dat", "binary") io.stdin:read("*line")