Plumb 3D geometry and per-node attributes through serialization

This commit is contained in:
Eric Fischer 2018-08-23 12:15:33 -07:00
parent ee3f35363b
commit dcc467627d
4 changed files with 67 additions and 3 deletions

View File

@ -37,10 +37,12 @@ drawvec decode_geometry(FILE *meta, std::atomic<long long> *geompos, int z, unsi
while (1) {
draw d;
if (!deserialize_byte_io(meta, &d.op, geompos)) {
signed char op;
if (!deserialize_byte_io(meta, &op, geompos)) {
fprintf(stderr, "Internal error: Unexpected end of file in geometry\n");
exit(EXIT_FAILURE);
}
d.op = op & VT_CLOSEPATH;
if (d.op == VT_END) {
break;
}
@ -77,6 +79,13 @@ drawvec decode_geometry(FILE *meta, std::atomic<long long> *geompos, int z, unsi
d.x = wwx;
d.y = wwy;
if (op & VT_NODE_3D) {
deserialize_double_io(meta, &d.elevation, geompos);
}
if (op & VT_NODE_ATTRIB) {
deserialize_string_io(meta, d.attributes, geompos);
}
}
out.push_back(d);

View File

@ -15,6 +15,9 @@
#define VT_LINETO 2
#define VT_CLOSEPATH 7
#define VT_NODE_3D 8
#define VT_NODE_ATTRIB 16
// The bitfield is to make sizeof(draw) be 16 instead of 24
// at the cost, apparently, of a 0.7% increase in running time
// for packing and unpacking.

View File

@ -30,6 +30,11 @@ size_t fwrite_check(const void *ptr, size_t size, size_t nitems, FILE *stream, c
return w;
}
void serialize_double(FILE *out, double n, std::atomic<long long> *fpos, const char *fname) {
fwrite_check(&n, sizeof(double), 1, out, fname);
*fpos += sizeof(double);
}
void serialize_int(FILE *out, int n, std::atomic<long long> *fpos, const char *fname) {
serialize_long_long(out, n, fpos, fname);
}
@ -72,6 +77,12 @@ void serialize_uint(FILE *out, unsigned n, std::atomic<long long> *fpos, const c
*fpos += sizeof(unsigned);
}
void serialize_string(FILE *out, std::string const &s, std::atomic<long long> *fpos, const char *fname) {
serialize_ulong_long(out, s.size(), fpos, fname);
fwrite_check(s.c_str(), sizeof(char), s.size(), out, fname);
*fpos += s.size();
}
void deserialize_int(char **f, int *n) {
long long ll;
deserialize_long_long(f, &ll);
@ -112,6 +123,27 @@ void deserialize_byte(char **f, signed char *n) {
*f += sizeof(signed char);
}
int deserialize_double_io(FILE *f, double *n, std::atomic<long long> *geompos) {
if (fread(n, sizeof(double), 1, f) == 1) {
*geompos += sizeof(double);
return 1;
}
return 0;
}
int deserialize_string_io(FILE *f, std::string &s, std::atomic<long long> *geompos) {
unsigned long long len;
if (deserialize_ulong_long_io(f, &len, geompos)) {
char tmp[len];
if (fread(tmp, sizeof(char), len, f) == len) {
*geompos += len;
s = std::string(tmp, len);
return 1;
}
}
return 0;
}
int deserialize_long_long_io(FILE *f, long long *n, std::atomic<long long> *geompos) {
unsigned long long zigzag = 0;
int ret = deserialize_ulong_long_io(f, &zigzag, geompos);
@ -171,9 +203,25 @@ int deserialize_byte_io(FILE *f, signed char *n, std::atomic<long long> *geompos
static void write_geometry(drawvec const &dv, std::atomic<long long> *fpos, FILE *out, const char *fname, long long wx, long long wy) {
for (size_t i = 0; i < dv.size(); i++) {
if (dv[i].op == VT_MOVETO || dv[i].op == VT_LINETO) {
serialize_byte(out, dv[i].op, fpos, fname);
int op = dv[i].op;
if (!isnan(dv[i].elevation)) {
op |= VT_NODE_3D;
}
if (dv[i].attributes.size() != 0) {
op |= VT_NODE_ATTRIB;
}
serialize_byte(out, op, fpos, fname);
serialize_long_long(out, dv[i].x - wx, fpos, fname);
serialize_long_long(out, dv[i].y - wy, fpos, fname);
if (op & VT_NODE_3D) {
serialize_double(out, dv[i].elevation, fpos, fname);
}
if (op & VT_NODE_ATTRIB) {
serialize_string(out, dv[i].attributes, fpos, fname);
}
wx = dv[i].x;
wy = dv[i].y;
} else {

View File

@ -16,21 +16,25 @@ size_t fwrite_check(const void *ptr, size_t size, size_t nitems, FILE *stream, c
void serialize_int(FILE *out, int n, std::atomic<long long> *fpos, const char *fname);
void serialize_long_long(FILE *out, long long n, std::atomic<long long> *fpos, const char *fname);
void serialize_ulong_long(FILE *out, unsigned long long n, std::atomic<long long> *fpos, const char *fname);
void serialize_double(FILE *out, double n, std::atomic<long long> *fpos, const char *fname);
void serialize_byte(FILE *out, signed char n, std::atomic<long long> *fpos, const char *fname);
void serialize_uint(FILE *out, unsigned n, std::atomic<long long> *fpos, const char *fname);
void serialize_string(FILE *out, const char *s, std::atomic<long long> *fpos, const char *fname);
void serialize_string(FILE *out, std::string const &s, std::atomic<long long> *fpos, const char *fname);
void deserialize_int(char **f, int *n);
void deserialize_long_long(char **f, long long *n);
void deserialize_ulong_long(char **f, unsigned long long *n);
void deserialize_double(char **f, double *n);
void deserialize_uint(char **f, unsigned *n);
void deserialize_byte(char **f, signed char *n);
int deserialize_int_io(FILE *f, int *n, std::atomic<long long> *geompos);
int deserialize_long_long_io(FILE *f, long long *n, std::atomic<long long> *geompos);
int deserialize_ulong_long_io(FILE *f, unsigned long long *n, std::atomic<long long> *geompos);
int deserialize_double_io(FILE *f, double *n, std::atomic<long long> *geompos);
int deserialize_uint_io(FILE *f, unsigned *n, std::atomic<long long> *geompos);
int deserialize_byte_io(FILE *f, signed char *n, std::atomic<long long> *geompos);
int deserialize_string_io(FILE *f, std::string &s, std::atomic<long long> *geompos);
struct serial_val {
int type = 0;