X-Git-Url: https://git.distorted.org.uk/~mdw/misc/blobdiff_plain/22fb157c9459f0d07eb46d09370c27d3e57a437c..refs/tags/1.2.1:/gorp.c?ds=sidebyside diff --git a/gorp.c b/gorp.c index 398e852..d5ce481 100644 --- a/gorp.c +++ b/gorp.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -23,102 +24,91 @@ struct format { #define CHUNK 1024 -static void format_base64(size_t n, unsigned line) +static void do_format(size_t n, unsigned line, void *ctx, + void (*encode)(void *, char *, size_t, dstr *), + void (*fix)(char *, size_t)) { - unsigned char buf[CHUNK]; + char buf[CHUNK]; dstr d = DSTR_INIT; - base64_ctx b; - - base64_init(&b); - if (line) { - b.indent = "\n"; - b.maxline = line; - } else { - b.indent = ""; - b.maxline = 0; - } while (n) { size_t nn = CHUNK; if (nn > n) nn = n; rand_get(RAND_GLOBAL, buf, nn); - base64_encode(&b, buf, nn, &d); + encode(ctx, buf, nn, &d); + if (fix) fix(d.buf, d.len); DWRITE(&d, stdout); DRESET(&d); n -= nn; } - base64_encode(&b, 0, 0, &d); + encode(ctx, 0, 0, &d); if (!line) { while (d.len && d.buf[d.len - 1] == '=') d.len--; } + if (fix) fix(d.buf, d.len); DPUTC(&d, '\n'); DWRITE(&d, stdout); } -static void file_fix(char *p, size_t n) +static void do_base64(void *ctx, char *p, size_t sz, dstr *d) + { base64_encode(ctx, p, sz, d); } +static void do_format_base64(size_t n, unsigned line, + void (*fix)(char *, size_t)) +{ + base64_ctx b; + + base64_init(&b); + if (line) { b.indent = "\n"; b.maxline = line; } + else { b.indent = ""; b.maxline = 0; } + do_format(n, line, &b, do_base64, fix); +} +static void format_base64(size_t n, unsigned line) + { do_format_base64(n, line, 0); } + +static void do_base32(void *ctx, char *p, size_t sz, dstr *d) + { base32_encode(ctx, p, sz, d); } +static void format_base32(size_t n, unsigned line) +{ + base32_ctx b; + + base32_init(&b); + if (line) { b.indent = "\n"; b.maxline = line; } + else { b.indent = ""; b.maxline = 0; } + do_format(n, line, &b, do_base32, 0); +} + +static void fix_file64(char *p, size_t n) { while (n) { if (*p == '/') *p = '%'; p++; n--; } } - static void format_file64(size_t n, unsigned line) -{ - unsigned char buf[CHUNK]; - dstr d = DSTR_INIT; - base64_ctx b; - - base64_init(&b); - b.indent = ""; - b.maxline = 0; + { do_format_base64(n, line, fix_file64); } +static void fix_safe64(char *p, size_t n) +{ while (n) { - size_t nn = CHUNK; - if (nn > n) nn = n; - rand_get(RAND_GLOBAL, buf, nn); - base64_encode(&b, buf, nn, &d); - file_fix(d.buf, d.len); - DWRITE(&d, stdout); - DRESET(&d); - n -= nn; + if (*p == '+') *p = '-'; + else if (*p == '/') *p = '_'; + p++; n--; } - base64_encode(&b, 0, 0, &d); - file_fix(d.buf, d.len); - while (d.len && d.buf[d.len - 1] == '=') - d.len--; - DPUTC(&d, '\n'); - DWRITE(&d, stdout); } +static void format_safe64(size_t n, unsigned line) + { do_format_base64(n, line, fix_safe64); } +static void do_hex(void *ctx, char *p, size_t sz, dstr *d) + { hex_encode(ctx, p, sz, d); } static void format_hex(size_t n, unsigned line) { - unsigned char buf[CHUNK]; - dstr d = DSTR_INIT; - hex_ctx h; + hex_ctx b; - hex_init(&h); - if (line) { - h.indent = "\n"; - h.maxline = line; - } else { - h.indent = ""; - h.maxline = 0; - } - - while (n) { - size_t nn = CHUNK; - if (nn > n) nn = n; - rand_get(RAND_GLOBAL, buf, nn); - hex_encode(&h, buf, nn, &d); - DWRITE(&d, stdout); - DRESET(&d); - n -= nn; - } - hex_encode(&h, 0, 0, &d); - DPUTC(&d, '\n'); - DWRITE(&d, stdout); + hex_init(&b); + if (line) { b.indent = "\n"; b.maxline = line; } + else { b.indent = ""; b.maxline = 0; } + do_format(n, line, &b, do_hex, 0); } static void format_raw(size_t n, unsigned line) @@ -137,6 +127,8 @@ static void format_raw(size_t n, unsigned line) static const struct format fmt[] = { { "base64", format_base64 }, { "file64", format_file64 }, + { "safe64", format_safe64 }, + { "base32", format_base32 }, { "hex", format_hex }, { "raw", format_raw }, { 0, 0 } @@ -178,7 +170,8 @@ Options:\n\ \n\ -y, --bytes Output length is bytes, not bits.\n\ -l, --line=LENGTH For textual output, limit line length to LENGTH.\n\ --f, --format=FORMAT Select output format: base64, file64, hex, raw.\n\ +-f, --format=FORMAT Select output format:\n\ + base64, file64, safe64, base32, hex, raw.\n\ ", stdout); }