String formatting mess to encode the JSON metadata

This commit is contained in:
Eric Fischer
2014-09-25 16:07:03 -07:00
parent 86f4f2dd05
commit ce485148fe
+48 -26
View File
@@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@@ -12,6 +13,7 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <stdarg.h>
#include "jsonpull.h" #include "jsonpull.h"
#include "tile.h" #include "tile.h"
@@ -370,17 +372,41 @@ void check(struct index *ix, long long n, char *metabase, unsigned *file_bbox, s
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
void quote(FILE *fp, char *s) { void quote(char **buf, char *s) {
char tmp[strlen(s) * 8 + 1];
char *out = tmp;
for (; *s != '\0'; s++) { for (; *s != '\0'; s++) {
if (*s == '\\' || *s == '\"') { if (*s == '\\' || *s == '\"') {
fputc('\\', fp); *out++ = '\\';
fputc(*s, fp); *out++ = *s;
} else if (*s < ' ') { } else if (*s < ' ') {
fprintf(fp, "\\u%04x", *s); sprintf(out, "\\u%04x", *s);
out = out + strlen(out);
} else { } else {
fputc(*s, fp); *out++ = *s;
} }
} }
*out = '\0';
*buf = realloc(*buf, strlen(*buf) + strlen(tmp) + 1);
strcat(*buf, tmp);
}
void aprintf(char **buf, const char *format, ...) {
va_list ap;
char *tmp;
va_start(ap, format);
if (vasprintf(&tmp, format, ap) < 0) {
fprintf(stderr, "memory allocation failure\n");
exit(EXIT_FAILURE);
}
va_end(ap);
*buf = realloc(*buf, strlen(*buf) + strlen(tmp) + 1);
strcat(*buf, tmp);
free(tmp);
} }
void read_json(FILE *f, char *fname, char *layername, int maxzoom, int minzoom, char *outdir, sqlite3 *outdb) { void read_json(FILE *f, char *fname, char *layername, int maxzoom, int minzoom, char *outdir, sqlite3 *outdb) {
@@ -604,13 +630,7 @@ next_feature:
close(indexfd); close(indexfd);
close(metafd); close(metafd);
char s[strlen(outdir) + strlen("/metadata.json") + 1]; {
sprintf(s, "%s/metadata.json", outdir);
FILE *fp = fopen(s, "w");
if (fp == NULL) {
fprintf(stderr, "metadata.json: %s\n", strerror(errno));
} else {
char *sql, *err; char *sql, *err;
sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('name', %Q);", fname); sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('name', %Q);", fname);
@@ -687,33 +707,35 @@ next_feature:
} }
sqlite3_free(sql); sqlite3_free(sql);
fprintf(fp, "\"json\": \"{"); char *buf = strdup("{");
fprintf(fp, "\\\"vector_layers\\\": [ { \\\"id\\\": \\\""); aprintf(&buf, "\"vector_layers\": [ { \"id\": \"");
quote(fp, layername); quote(&buf, layername);
fprintf(fp, "\\\", \\\"description\\\": \\\"\\\", \\\"minzoom\\\": %d, \\\"maxzoom\\\": %d, \\\"fields\\\": {", minzoom, maxzoom); aprintf(&buf, "\", \"description\": \"\", \"minzoom\": %d, \"maxzoom\": %d, \"fields\": {", minzoom, maxzoom);
struct pool_val *pv; struct pool_val *pv;
for (pv = file_keys.head; pv != NULL; pv = pv->next) { for (pv = file_keys.head; pv != NULL; pv = pv->next) {
fprintf(fp, "\\\""); aprintf(&buf, "\"");
quote(fp, pv->s); quote(&buf, pv->s);
if (pv->type == VT_NUMBER) { if (pv->type == VT_NUMBER) {
fprintf(fp, "\\\": \\\"Number\\\""); aprintf(&buf, "\": \"Number\"");
} else { } else {
fprintf(fp, "\\\": \\\"String\\\""); aprintf(&buf, "\": \"String\"");
} }
if (pv->next != NULL) { if (pv->next != NULL) {
fprintf(fp, ", "); aprintf(&buf, ", ");
} }
} }
fprintf(fp, "} } ]"); aprintf(&buf, "} } ] }");
fprintf(fp, "}\",\n");
fprintf(fp, "}\n"); sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('json', %Q);", buf);
if (sqlite3_exec(outdb, sql, NULL, NULL, &err) != SQLITE_OK) {
fclose(fp); fprintf(stderr, "set metadata: %s\n", err);
exit(EXIT_FAILURE);
}
sqlite3_free(sql);
} }
} }