X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/6ba5b855ebc737cc46cabfbe799b0c7706f437f4..7711f3fc00259e55f630cfe6104eff3083dc9d77:/sbr/base64.c diff --git a/sbr/base64.c b/sbr/base64.c index 5ff9f53c..3a578c21 100644 --- a/sbr/base64.c +++ b/sbr/base64.c @@ -13,10 +13,11 @@ static char nib2b64[0x40+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int -writeBase64aux (FILE *in, FILE *out) +writeBase64aux (FILE *in, FILE *out, int crlf) { unsigned int cc, n; - char inbuf[3]; + unsigned char inbuf[3]; + int skipnl = 0; n = BPERLIN; while ((cc = fread (inbuf, sizeof(*inbuf), sizeof(inbuf), in)) > 0) { @@ -29,6 +30,47 @@ writeBase64aux (FILE *in, FILE *out) if (cc < sizeof(inbuf) - 1) inbuf[1] = 0; } + + /* + * Convert a LF to a CRLF if desired. That means we need to push + * data back into the input stream. + */ + + if (crlf) { + unsigned int i; + + for (i = 0; i < cc; i++) { + if (inbuf[i] == '\n' && !skipnl) { + inbuf[i] = '\r'; + /* + * If it's the last character in the buffer, we can just + * substitute a \r and push a \n back. Otherwise shuffle + * everything down and push the last character back. + */ + if (i == cc - 1) { + /* + * If we're at the end of the input, there might be + * more room in inbuf; if so, add it there. Otherwise + * push it back to the input. + */ + if (cc < sizeof(inbuf)) + inbuf[cc++] = '\n'; + else + ungetc('\n', in); + skipnl = 1; + } else { + /* This only works as long as sizeof(inbuf) == 3 */ + ungetc(inbuf[cc - 1], in); + if (cc == 3 && i == 0) + inbuf[2] = inbuf[1]; + inbuf[++i] = '\n'; + } + } else { + skipnl = 0; + } + } + } + bits = (inbuf[0] & 0xff) << 16; bits |= (inbuf[1] & 0xff) << 8; bits |= inbuf[2] & 0xff; @@ -41,7 +83,10 @@ writeBase64aux (FILE *in, FILE *out) outbuf[2] = '='; } - fwrite (outbuf, sizeof(*outbuf), sizeof(outbuf), out); + if (fwrite (outbuf, sizeof(*outbuf), sizeof(outbuf), out) < + sizeof outbuf) { + advise ("writeBase64aux", "fwrite"); + } if (cc < sizeof(inbuf)) { putc ('\n', out);