getting into stash/item finding, but it ended up big. Removed the read/writeThing API in favor of the marshall/unmarshallThing API. It was slightly awkward in a couple spots where the format of writeThing and marshallThing differed slightly (strings, level_id, level_pos).
Doesn't affect savegames.
When it's is okay to break savegames (maybe just before releasing 0.4?) it would be nice to remove the few remaining redundancies listed above.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3828 c06c8d41-db1a-0410-9941-cceddc491573
WF2DSJGR6PKLGQSXEFF4ZW4EZZFGMHXPXWUYAKYBPFJH6KJKAANQC
ND6XK6Z4XFRB3L42TK3G34SZQYETLPNVOIKBA65SJMB4FYAGOWPAC
G2HJY7M5HS6E5GMPPB6CKNKIMATET3PWMUNY6XAHCB6ICS3WOUBQC
AO3KHGKGSX2ZR24KJVIOTUY7EHYHMMI5W4HN3CAG4YGQHBOHLGDQC
52J7CYVAW3QCUEWA5OKWPDGOP6JZR5NJSE3JDLZFBCR7B6LH5ASAC
DMLFJIPOE4ZXUFQ25VVEZCMURP2UPJBBWDGQS3DPQVUNVBBQ4GDQC
BK6MGPSEAEMU4URBAPKY3VTKK6JC6IZVN5CNOSN2UPTIOWQYEWLQC
77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC
7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
ESWIM76FGJL4QFLSHU6AC4D74PT7OPLQ7ZCJYWLZS5UCBAJDXYHAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
WX2VFNANQZ3IRHBXSLKJT3G3OAQREAZISXLOTG6JO7KXFBHQFOYAC
2G55UEHQ7554OPNSZVTUCZTWSHIFKGT56QEGSYFKCTX547I4AL3AC
5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC
T4IH76FA5TWHFOZUJFHLQXQJENJHWTUZZP4EGNA7D4GTZY7D4ZKAC
6HG6JFO47Y3BZLU7Y6G3R2CX6JFGN4X5PKK6S5IGUXUYQ5GVZYFQC
NJDPIHOREOTAZJXOMZA5QA4TBADDWLFZ25NVAIFDQ7BUBVUWCEEAC
G4JT6UMXZW2M4GLNPX7C5NLHZIEJ5KGVHKRAXX7PEZEFVQCGN4DAC
442VGKMARB6LTQUEBIB5P447EI34BRJL6JALZKXLWPDHWCM6KKCQC
TAHSTXR7ROOMDFUSBUU4ZAIEWQLAS5CIRCTARLD4Q2BGNLSL7E5QC
A5H6EHZ5L5Z3BW2MIEJSDZMGTUQIJT6HSQXJVFBN5ZR55SGNNQNQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
AVCMVFA3MKCXHO6H44UK5KJNIHTGQV7UA7GYXM26VI6TXXU5ZN6QC
2EF3QUVPUQAKBTZKLKQ5B73Z26TXX2H2G2MKIMXD7B7BSDCYE7SAC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
XPCGZBHHSL6MB3ORMUJI64BAERU6AZTIY6RK56BBW7SNB3IK24IAC
43ZTEB57FU7KE5EVMYWZONNVJBZCGF3JEAJZIY25LC4LGE65PG5QC
TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC
ZK5H5YBD3R7H3KKNKSJYE65TUEPPWIWUJLU567FKSZYQYIW6ZVFAC
QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
NCDWWDJQLAU5ORSAQGZKJJ5E22VTDGGPJMVVBWQFHQ2B3U3UFHDQC
JTTHP2BEYEPBQMSDM7IKANTMKRPY6ACGL2JN4D3OBZ7HFXKAYEGQC
RGHXFBNIULRVRYLBGG5JZDMYVM2E2JJ2Y5KQPMU6PUS3V26G6ZXQC
JDM27QE4HR52AYFSQE763BFF57ANOTF5MXKMO377PP5EXMN7SAOAC
WE3JT43OR4L6675GINGU4B3YDBMURJZHDDYY3VLHUJEBAKH2HYEAC
34C4U6EQWERY75GZJKUCM5KVGU2OUICETS5LGZF6RMKMZT4R5SQAC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
KXUQB3WNWC5IFL6VFWADEPQMMU3VV3NDI5FLA666PGOEWFYUHCLQC
3EEPRFC6SVG4NAQS5XDAUBDG33CRJ7UG3MJOHI6WNO6RKCIGTFXAC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
RLUXNEFLEICA7ERDVUOIJZJJSTPY2QLEXYN2KDEVWZSKVIV4CKPQC
ANBVGN4RZOMY5LI4QSHOV2477FN55H353ZYLSVCPTXC7AWWSQZBAC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC
IVVTHLTTLOP5TSULXJWUSSXHOKYWVU3OWKYVK45A7RIB6V34MYQAC
ZJLJGSB2XSBQU42OFQMXL3EG4CXAQGOYAU6YTV2SAWZEJIPFH2CAC
RM4LRL6W56XHFWFZIA6LQLR6TPAHVSSXBVCNYZJIZSBPKFWDAJJQC
RBAGQ2PB7V5YAM5KSHSZR2E3MLKDSRVM5XYGI2TIXP5QMVBOQHDQC
3PY3L3A4QRW3Z5Y7SHO4TMVOOP2VNCO27X2MX4DTOP2SADLBQUOAC
Z262AMUK447BTC7MVOPQQ3NZTQXQOE5JODNHXN3IU7WL4ABSW5YQC
7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC
DKRSOHZXL6EPSLKOKHF7GJXSZEJVY7CXGACSHWLM5B5FTRETWWCAC
writeShort(file, branch);
writeShort(file, depth);
writeShort(file, level_type);
marshallShort(outf, branch);
marshallShort(outf, depth);
marshallShort(outf, level_type);
branch = static_cast<branch_type>(readShort(file));
depth = readShort(file);
level_type = static_cast<level_area_type>(readShort(file));
branch = static_cast<branch_type>(unmarshallShort(inf));
depth = unmarshallShort(inf);
level_type = static_cast<level_area_type>(unmarshallShort(inf));
writeCoord(file, position);
writeShort(file, grid);
destination.save(file);
writeByte(file, guessed_pos? 1 : 0);
writeByte(file, type);
marshallCoord(outf, position);
marshallShort(outf, grid);
destination.save(outf);
marshallByte(outf, guessed_pos? 1 : 0);
marshallByte(outf, type);
readCoord(file, position);
grid = static_cast<dungeon_feature_type>(readShort(file));
destination.load(file);
guessed_pos = readByte(file) != 0;
type = static_cast<stair_type>(readByte(file));
unmarshallCoord(inf, position);
grid = static_cast<dungeon_feature_type>(unmarshallShort(inf));
destination.load(inf);
guessed_pos = unmarshallByte(inf) != 0;
type = static_cast<stair_type>(unmarshallByte(inf));
// string -- 4 byte length, non-terminated string data
void marshallString4(writer &th, const std::string &data)
{
marshallLong(th, data.length());
th.write(data.c_str(), data.length());
}
void unmarshallString4(reader &th, std::string& s)
{
const int len = unmarshallLong(th);
s.resize(len);
if (len) th.read(&s.at(0), len);
}
static void load_item(FILE *file, item_def &item)
{
reader inf(file);
unmarshallItem(inf, item);
}
// ----------------------------------------------------------------------
// Stash
// ----------------------------------------------------------------------
void Note::save( FILE* fp ) const {
writeLong( fp, type );
writeLong( fp, turn );
writeShort( fp, packed_place );
writeLong( fp, first );
writeLong( fp, second );
writeString( fp, name );
writeString( fp, desc );
void Note::save(writer& outf) const
{
marshallLong( outf, type );
marshallLong( outf, turn );
marshallShort( outf, packed_place );
marshallLong( outf, first );
marshallLong( outf, second );
marshallString4( outf, name );
marshallString4( outf, desc );
type = static_cast<NOTE_TYPES>(readLong( fp ));
turn = readLong( fp );
packed_place = readShort( fp );
first = readLong( fp );
second = readLong( fp );
name = readString( fp );
desc = readString( fp );
type = static_cast<NOTE_TYPES>(unmarshallLong( inf ));
turn = unmarshallLong( inf );
packed_place = unmarshallShort( inf );
first = unmarshallLong( inf );
second = unmarshallLong( inf );
unmarshallString4( inf, name );
unmarshallString4( inf, desc );
branch = static_cast<branch_type>( readShort(inf) );
shallowest = readShort(inf);
deepest = readShort(inf);
deny = readByte(inf);
branch = static_cast<branch_type>( unmarshallShort(inf) );
shallowest = unmarshallShort(inf);
deepest = unmarshallShort(inf);
deny = unmarshallByte(inf);
cache_offset = ftell(outf);
writeShort(outf, MAP_CACHE_VERSION); // Level indicator.
writeString(outf, name);
cache_offset = outf.tell();
marshallShort(outf, MAP_CACHE_VERSION); // Level indicator.
marshallString4(outf, name);
writeString(outf, name);
writeString(outf, place_loaded_from.filename);
writeLong(outf, place_loaded_from.lineno);
writeShort(outf, orient);
writeLong(outf, chance);
writeLong(outf, cache_offset);
writeString(outf, tags);
marshallString4(outf, name);
marshallString4(outf, place_loaded_from.filename);
marshallLong(outf, place_loaded_from.lineno);
marshallShort(outf, orient);
marshallLong(outf, chance);
marshallLong(outf, cache_offset);
marshallString4(outf, tags);
name = readString(inf);
place_loaded_from.filename = readString(inf);
place_loaded_from.lineno = readLong(inf);
orient = static_cast<map_section_type>( readShort(inf) );
chance = readLong(inf);
cache_offset = readLong(inf);
tags = readString(inf);
unmarshallString4(inf, name);
unmarshallString4(inf, place_loaded_from.filename);
place_loaded_from.lineno = unmarshallLong(inf);
orient = static_cast<map_section_type>( unmarshallShort(inf) );
chance = unmarshallLong(inf);
cache_offset = unmarshallLong(inf);
unmarshallString4(inf, tags);
// Default cap on strings marshalled.
#define STR_CAP 1000
void writeShort(FILE *file, short s);
short readShort(FILE *file);
void writeByte(FILE *file, unsigned char byte);
unsigned char readByte(FILE *file);
void writeString(FILE* file, const std::string &s, int cap = STR_CAP);
std::string readString(FILE *file, int cap = STR_CAP);
void writeLong(FILE* file, long num);
long readLong(FILE *file);
void writeCoord(FILE *file, const coord_def &pos);
void readCoord(FILE *file, coord_def &pos);
void writeShort(FILE *file, short s)
{
char data[2];
// High byte first - network order
data[0] = static_cast<char>((s >> 8) & 0xFF);
data[1] = static_cast<char>(s & 0xFF);
write2(file, data, sizeof(data));
}
short readShort(FILE *file)
{
unsigned char data[2];
read2(file, (char *) data, 2);
// High byte first
return (((short) data[0]) << 8) | (short) data[1];
}
void writeByte(FILE *file, unsigned char byte)
{
write2(file, (char *) &byte, sizeof byte);
}
unsigned char readByte(FILE *file)
{
unsigned char byte;
read2(file, (char *) &byte, sizeof byte);
return byte;
}
void writeString(FILE* file, const std::string &s, int cap)
{
int length = s.length();
if (length > cap)
length = cap;
writeLong(file, length);
if (length)
write2(file, s.c_str(), length);
}
std::string readString(FILE *file, int cap)
{
const int length = readLong(file);
if (length > 0)
{
if (length <= cap)
{
char *buf = new char[length];
read2(file, buf, length);
const std::string s(buf, length);
delete [] buf;
return (s);
}
end(1, false, "String too long: %d bytes\n", length);
}
return ("");
}
void writeLong(FILE* file, long num)
{
// High word first, network order
writeShort(file, (short) ((num >> 16) & 0xFFFFL));
writeShort(file, (short) (num & 0xFFFFL));
}
long readLong(FILE *file)
{
// We need the unsigned short cast even for the high word because we
// might be on a system where long is more than 4 bytes, and we don't want
// to sign extend the high short.
return ((long) (unsigned short) readShort(file)) << 16 |
(long) (unsigned short) readShort(file);
}
void writeCoord(FILE *file, const coord_def &pos)
{
writeShort(file, pos.x);
writeShort(file, pos.y);
}
void readCoord(FILE *file, coord_def &pos)
{
pos.x = readShort(file);
pos.y = readShort(file);
}