+2001-06-16 [sergey]
+
+ * src/base64.c, src/base64.h (Base64Decoder, base64_decoder_new,
+ base64_decoder_free, base64_decoder_decode): new object and
+ functions for decoding base64 streams.
+ * src/procmime.c (procmime_decode_content): modified to use the
+ new base64 decoder.
+
2001-06-15 [paul]
0.4.99claws10
*
* Modified by Hiroyuki Yamamoto <hiro-y@kcn.ne.jp>
*/
+
+#include "defs.h"
+
#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+#include "base64.h"
static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
return len;
}
+struct _Base64Decoder
+{
+ int buf_len;
+ unsigned char buf[4];
+};
+
+Base64Decoder *
+base64_decoder_new (void)
+{
+ Base64Decoder *decoder;
+
+ decoder = g_new0 (Base64Decoder, 1);
+ return decoder;
+}
+
+void
+base64_decoder_free (Base64Decoder *decoder)
+{
+ g_free (decoder);
+}
+
+int
+base64_decoder_decode (Base64Decoder *decoder,
+ const char *in,
+ char *out)
+{
+ int len = 0;
+ int buf_len;
+ unsigned char buf[4];
+
+ g_return_val_if_fail (decoder != NULL, -1);
+ g_return_val_if_fail (in != NULL, -1);
+ g_return_val_if_fail (out != NULL, -1);
+
+ buf_len = decoder->buf_len;
+ memcpy (buf, decoder->buf, sizeof(buf));
+ while (1) {
+ while (buf_len < 4) {
+ int c = *(unsigned char *)in++;
+ if (c == '\0') break;
+ if (c == '\r' || c == '\n') continue;
+ if (c != '=' && DECODE64(c) == BAD)
+ return -1;
+ buf[buf_len++] = c;
+ }
+ if (buf_len < 4 || buf[0] == '=' || buf[1] == '=') {
+ decoder->buf_len = buf_len;
+ memcpy (decoder->buf, buf, sizeof(buf));
+ return len;
+ }
+ *out++ = ((DECODE64(buf[0]) << 2)
+ | ((DECODE64(buf[1]) >> 4) & 0x03));
+ ++len;
+ if (buf[2] != '=') {
+ *out++ = (((DECODE64(buf[1]) << 4) & 0xf0)
+ | (DECODE64(buf[2]) >> 2));
+ ++len;
+ if (buf[3] != '=') {
+ *out++ = (((DECODE64(buf[2]) << 6) & 0xc0)
+ | DECODE64(buf[3]));
+ ++len;
+ }
+ }
+ buf_len = 0;
+ if (buf[2] == '=' || buf[3] == '=') {
+ decoder->buf_len = 0;
+ return len;
+ }
+ }
+}
+
/* base64.c ends here */
#ifndef __BASE64_H__
#define __BASE64_H__
+typedef struct _Base64Decoder Base64Decoder;
+
+Base64Decoder * base64_decoder_new (void);
+void base64_decoder_free (Base64Decoder *decoder);
+int base64_decoder_decode (Base64Decoder *decoder,
+ const char *in,
+ char *out);
+
void to64frombits(unsigned char *, const unsigned char *, int);
int from64tobits(char *, const char *);
} else if (mimeinfo->encoding_type == ENC_BASE64) {
gchar outbuf[BUFFSIZE];
gint len;
+ Base64Decoder *decoder;
+ decoder = base64_decoder_new();
while (fgets(buf, sizeof(buf), infp) != NULL &&
(!boundary ||
!IS_BOUNDARY(buf, boundary, boundary_len))) {
- len = from64tobits(outbuf, buf);
+ len = base64_decoder_decode(decoder, buf, outbuf);
if (len < 0) {
g_warning("Bad BASE64 content\n");
break;
}
fwrite(outbuf, sizeof(gchar), len, outfp);
}
+ base64_decoder_free(decoder);
} else if (mimeinfo->encoding_type == ENC_X_UUENCODE) {
gchar outbuf[BUFFSIZE];
gint len;