/* $Id: Base64.xs,v 3.2 2004/03/29 11:35:13 gisle Exp $
Copyright 1997-2004 Gisle Aas
modify it under the same terms as Perl itself.
The tables and some of the code that used to be here was borrowed from
metamail, which comes with this message:
Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
Permission to use, copy, modify, and distribute this material
for any purpose and without fee is hereby granted, provided
that the above copyright notice and this permission notice
appear in all copies, and that the name of Bellcore not be
used in advertising or publicity pertaining to this
material without the specific, prior written permission
of an authorized representative of Bellcore. BELLCORE
MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
*/
#ifdef __cplusplus
extern "C" {
#endif
#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif
#ifndef PATCHLEVEL
# include <patchlevel.h>
# include <could_not_find_Perl_patchlevel.h>
# endif
#endif
#endif
#ifdef G_WARN_ON
#else
#endif
static char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static unsigned char index_64[256] = {
};
#ifdef SvPVbyte
/* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
static char *
{
sv_utf8_downgrade(sv,0);
}
# endif
#else
#endif
#ifndef isXDIGIT
#endif
#ifndef NATIVE_TO_ASCII
#endif
SV*
encode_base64(sv,...)
PROTOTYPE: $;$
char *str; /* string to encode */
char *eol; /* the end-of-line sequence to use */
char *r; /* result string */
int chunk;
CODE:
#endif
/* set up EOL from the second argument if present, default to "\n" */
} else {
eol = "\n";
eollen = 1;
}
/* calculate the length of the result */
if (rlen) {
/* add space for EOL */
}
/* allocate a result buffer */
/* encode */
char *c = eol;
while (c < e)
*r++ = *c++;
chunk = 0;
}
if (len > 2) {
} else if (len == 2) {
*r++ = '=';
} else { /* len == 1 */
*r++ = '=';
*r++ = '=';
}
}
if (rlen) {
/* append eol to the result string */
char *c = eol;
while (c < e)
*r++ = *c++;
}
*r = '\0'; /* every SV in perl should be NUL-terminated */
SV*
PROTOTYPE: $
char *r;
unsigned char c[4];
CODE:
{
/* always enough, but might be too much */
}
int i = 0;
do {
c[i++] = uc;
if (i < 4) {
if (i && DOWARN)
warn("Premature end of base64 data");
if (i < 2) goto thats_it;
c[3] = EQ;
}
break;
}
} while (i < 4);
break;
}
/* printf("c0=%d,c1=%d,c2=%d,c3=%d\n", c[0],c[1],c[2],c[3]);*/
*r++ = (c[0] << 2) | ((c[1] & 0x30) >> 4);
if (c[2] == EQ)
break;
*r++ = ((c[1] & 0x0F) << 4) | ((c[2] & 0x3C) >> 2);
if (c[3] == EQ)
break;
*r++ = ((c[2] & 0x03) << 6) | c[3];
}
*r = '\0';
SV*
PROTOTYPE: $;$
char *eol;
char *beg;
char *end;
char *p;
char *p_beg;
CODE:
#endif
/* set up EOL from the second argument if present, default to "\n" */
} else {
eol = "\n";
eol_len = 1;
}
linelen = 0;
p = beg;
while (1) {
p_beg = p;
/* skip past as much plain text as possible */
while (p < end && qp_isplain(*p)) {
p++;
}
if (p == end || *p == '\n') {
/* whitespace at end of line must be encoded */
p--;
}
if (p_len) {
/* output plain text (with line breaks) */
if (eol_len) {
? MAX_LINE /* .......\n */
linelen = 0;
}
}
if (p_len) {
}
}
if (p == end) {
break;
}
else if (*p == '\n' && eol_len) {
p++;
linelen = 0;
}
else {
/* output escaped char (with line breaks) */
linelen = 0;
}
p++;
linelen += 3;
}
/* optimize reallocs a bit */
}
}
SV*
PROTOTYPE: $
char *r;
char *whitespace = 0;
CODE:
if (!whitespace)
whitespace = str;
str++;
}
str++;
}
else if (*str == '\n') {
whitespace = 0;
*r++ = *str++;
}
else {
if (whitespace) {
while (whitespace < str) {
*r++ = *whitespace++;
}
whitespace = 0;
}
if (*str == '=') {
char buf[3];
str++;
}
else {
/* look for soft line break */
char *p = str + 1;
p++;
if (p < end && *p == '\n')
str = p + 1;
str = p + 2;
else
*r++ = *str++; /* give up */
}
}
else {
*r++ = *str++;
}
}
}
if (whitespace) {
while (whitespace < str) {
*r++ = *whitespace++;
}
}
*r = '\0';