-/* $Id: Base64.xs,v 1.32 2003/01/05 07:49:07 gisle Exp $
+/* $Id: Base64.xs,v 1.41 2004/01/08 14:07:26 gisle Exp $
-Copyright 1997-2003 Gisle Aas
+Copyright 1997-2004 Gisle Aas
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
}
#endif
-#include "patchlevel.h"
+#ifndef PATCHLEVEL
+# include <patchlevel.h>
+# if !(defined(PERL_VERSION) || (SUBVERSION > 0 && defined(PATCHLEVEL)))
+# include <could_not_find_Perl_patchlevel.h>
+# endif
+#endif
+
#if PATCHLEVEL <= 4 && !defined(PL_dowarn)
#define PL_dowarn dowarn
#endif
+#ifdef G_WARN_ON
+ #define DOWARN (PL_dowarn & G_WARN_ON)
+#else
+ #define DOWARN PL_dowarn
+#endif
+
+
#define MAX_LINE 76 /* size of encoded lines */
static char basis_64[] =
chunk = 0;
}
c1 = *str++;
- c2 = *str++;
+ c2 = len > 1 ? *str++ : '\0';
*r++ = basis_64[c1>>2];
*r++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
if (len > 2) {
if (str == end) {
if (i < 4) {
- if (i && PL_dowarn)
+ if (i && DOWARN)
warn("Premature end of base64 data");
if (i < 2) goto thats_it;
if (i == 2) c[2] = EQ;
} while (i < 4);
if (c[0] == EQ || c[1] == EQ) {
- if (PL_dowarn) warn("Premature padding of base64 data");
+ if (DOWARN) warn("Premature padding of base64 data");
break;
}
/* printf("c0=%d,c1=%d,c2=%d,c3=%d\n", c[0],c[1],c[2],c[3]);*/
MODULE = MIME::Base64 PACKAGE = MIME::QuotedPrint
-#define qp_isplain(c) ((c) == '\t' || ((c) >= ' ' && (c) <= '~') && (c) != '=')
+#define qp_isplain(c) ((c) == '\t' || (((c) >= ' ' && (c) <= '~') && (c) != '='))
SV*
encode_qp(sv,...)
while (p < end && qp_isplain(*p)) {
p++;
}
- if (*p == '\n' || p == end) {
+ if (p == end || *p == '\n') {
/* whitespace at end of line must be encoded */
while (p > p_beg && (*(p - 1) == '\t' || *(p - 1) == ' '))
p--;
if (p_len) {
/* output plain text (with line breaks) */
if (eol_len) {
- STRLEN max_last_line = (*p == '\n' || p == end)
+ STRLEN max_last_line = (p == end || *p == '\n')
? MAX_LINE /* .......\n */
- : (*(p + 1) == '\n' || (p + 1) == end)
+ : ((p + 1) == end || *(p + 1) == '\n')
? MAX_LINE - 3 /* ....=XX\n */
: MAX_LINE - 4; /* ...=XX=\n */
while (p_len + linelen > max_last_line) {
}
}
- if (*p == '\n') {
+ if (p == end) {
+ break;
+ }
+ else if (*p == '\n' && eol_len) {
sv_catpvn(RETVAL, eol, eol_len);
p++;
linelen = 0;
}
- else if (p < end) {
+ else {
/* output escaped char (with line breaks) */
+ assert(p < end);
if (eol_len && linelen > MAX_LINE - 4) {
sv_catpvn(RETVAL, "=", 1);
sv_catpvn(RETVAL, eol, eol_len);
p++;
linelen += 3;
}
- else {
- assert(p == end);
- break;
- }
/* optimize reallocs a bit */
if (SvLEN(RETVAL) > 80 && SvLEN(RETVAL) - SvCUR(RETVAL) < 3) {
PREINIT:
STRLEN len;
- char *str = (unsigned char*)SvPVbyte(sv, len);
+ char *str = SvPVbyte(sv, len);
char const* end = str + len;
char *r;
char *whitespace = 0;
}
whitespace = 0;
}
- if (*str == '=' && (str + 2) < end && isxdigit(str[1]) && isxdigit(str[2])) {
- char buf[3];
- str++;
- buf[0] = *str++;
- buf[1] = *str++;
- buf[2] = '\0';
- *r++ = (char)strtol(buf, 0, 16);
- }
- else if (*str == '=' && (str + 1) < end && str[1] == '\n') {
- str += 2;
+ if (*str == '=') {
+ if ((str + 2) < end && isXDIGIT(str[1]) && isXDIGIT(str[2])) {
+ char buf[3];
+ str++;
+ buf[0] = *str++;
+ buf[1] = *str++;
+ buf[2] = '\0';
+ *r++ = (char)strtol(buf, 0, 16);
+ }
+ else {
+ /* look for soft line break */
+ char *p = str + 1;
+ while (p < end && (*p == ' ' || *p == '\t'))
+ p++;
+ if (p < end && *p == '\n')
+ str = p + 1;
+ else if ((p + 1) < end && *p == '\r' && *(p + 1) == '\n')
+ str = p + 2;
+ else
+ *r++ = *str++; /* give up */
+ }
}
- else if (*str == '=' && (str + 2) < end && str[1] == '\r' && str[2] == '\n') {
- str += 3;
+ else {
+ *r++ = *str++;
}
- else {
- *r++ = *str++;
- }
}
}
+ if (whitespace) {
+ while (whitespace < str) {
+ *r++ = *whitespace++;
+ }
+ }
*r = '\0';
SvCUR_set(RETVAL, r - SvPVX(RETVAL));