aboutsummaryrefslogtreecommitdiff
path: root/emcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'emcc.c')
-rw-r--r--emcc.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/emcc.c b/emcc.c
index 9a6c742..ff715a4 100644
--- a/emcc.c
+++ b/emcc.c
@@ -787,12 +787,53 @@ struct savefile_write_ctx {
size_t pos;
};
-static void savefile_write(void *vctx, const void *buf, int len)
+static void savefile_write(void *vctx, const void *vbuf, int len)
{
+ static const unsigned char length[256] = {
+ /*
+ * Assign a length of 1 to any printable ASCII character that
+ * can be written literally in URI-encoding, i.e.
+ *
+ * A-Z a-z 0-9 - _ . ! ~ * ' ( )
+ *
+ * Assign length 3 (for % and two hex digits) to all other
+ * byte values.
+ */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1,
+ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ };
+ static const char hexdigits[] = "0123456789ABCDEF";
+
struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)vctx;
- if (ctx->buffer)
- memcpy(ctx->buffer + ctx->pos, buf, len);
- ctx->pos += len;
+ const unsigned char *buf = (const unsigned char *)vbuf;
+ for (int i = 0; i < len; i++) {
+ unsigned char c = buf[i];
+ int clen = length[c];
+ if (ctx->buffer) {
+ if (clen == 1) {
+ ctx->buffer[ctx->pos] = c;
+ } else {
+ ctx->buffer[ctx->pos] = '%';
+ ctx->buffer[ctx->pos+1] = hexdigits[c >> 4];
+ ctx->buffer[ctx->pos+2] = hexdigits[c & 0xF];
+ }
+ }
+ ctx->pos += clen;
+ }
}
char *get_save_file(void)