]>
diplodocus.org Git - nmh/blob - sbr/base64.c
2 * base64.c -- routines for converting to base64
4 * This code is Copyright (c) 2012, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
12 static char nib2b64
[0x40+1] =
13 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16 writeBase64aux (FILE *in
, FILE *out
, int crlf
)
19 unsigned char inbuf
[3];
23 while ((cc
= fread (inbuf
, sizeof(*inbuf
), sizeof(inbuf
), in
)) > 0) {
28 if (cc
< sizeof(inbuf
)) {
30 if (cc
< sizeof(inbuf
) - 1)
35 * Convert a LF to a CRLF if desired. That means we need to push
36 * data back into the input stream.
42 for (i
= 0; i
< cc
; i
++) {
43 if (inbuf
[i
] == '\n' && !skipnl
) {
46 * If it's the last character in the buffer, we can just
47 * substitute a \r and push a \n back. Otherwise shuffle
48 * everything down and push the last character back.
52 * If we're at the end of the input, there might be
53 * more room in inbuf; if so, add it there. Otherwise
54 * push it back to the input.
56 if (cc
< sizeof(inbuf
))
62 /* This only works as long as sizeof(inbuf) == 3 */
63 ungetc(inbuf
[cc
- 1], in
);
64 if (cc
== 3 && i
== 0)
74 bits
= (inbuf
[0] & 0xff) << 16;
75 bits
|= (inbuf
[1] & 0xff) << 8;
76 bits
|= inbuf
[2] & 0xff;
78 for (bp
= outbuf
+ sizeof(outbuf
); bp
> outbuf
; bits
>>= 6)
79 *--bp
= nib2b64
[bits
& 0x3f];
80 if (cc
< sizeof(inbuf
)) {
82 if (cc
< sizeof inbuf
- 1)
86 if (fwrite (outbuf
, sizeof(*outbuf
), sizeof(outbuf
), out
) <
88 advise ("writeBase64aux", "fwrite");
91 if (cc
< sizeof(inbuf
)) {
108 /* Caller is responsible for ensuring that the out array is long
109 enough. Given length is that of in, out should be have at
111 4 * [length/3] + length/57 + 2
112 But double the length will certainly be sufficient. */
114 writeBase64 (unsigned char *in
, size_t length
, unsigned char *out
)
116 unsigned int n
= BPERLIN
;
122 for (cc
= 0, bp
= in
; length
> 0 && cc
< 3; ++cc
, ++bp
, --length
)
128 bits
= (in
[0] & 0xff) << 16;
130 bits
|= (in
[1] & 0xff) << 8;
132 bits
|= in
[2] & 0xff;
137 for (bp
= out
+ 4; bp
> out
; bits
>>= 6)
138 *--bp
= nib2b64
[bits
& 0x3f];
164 * Essentially a duplicate of writeBase64, but without line wrapping or
165 * newline termination (note: string IS NUL terminated)
169 writeBase64raw (unsigned char *in
, size_t length
, unsigned char *out
)
175 for (cc
= 0, bp
= in
; length
> 0 && cc
< 3; ++cc
, ++bp
, --length
)
181 bits
= (in
[0] & 0xff) << 16;
183 bits
|= (in
[1] & 0xff) << 8;
185 bits
|= in
[2] & 0xff;
190 for (bp
= out
+ 4; bp
> out
; bits
>>= 6)
191 *--bp
= nib2b64
[bits
& 0x3f];