source: main/trunk/greenstone2/build-src/packages/w3mir/MIME-Base64-2.11/Base64.xs@ 26670

Last change on this file since 26670 was 718, checked in by davidb, 25 years ago

added m3mir package

  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1/* $Id: Base64.xs 718 1999-10-19 02:36:47Z davidb $
2
3Copyright 1997-1998 Gisle Aas
4
5This library is free software; you can redistribute it and/or
6modify it under the same terms as Perl itself.
7
8
9The tables and some of the code that used to be here was borrowed from
10metamail, which comes with this message:
11
12 Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
13
14 Permission to use, copy, modify, and distribute this material
15 for any purpose and without fee is hereby granted, provided
16 that the above copyright notice and this permission notice
17 appear in all copies, and that the name of Bellcore not be
18 used in advertising or publicity pertaining to this
19 material without the specific, prior written permission
20 of an authorized representative of Bellcore. BELLCORE
21 MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
22 OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
23 WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
24
25*/
26
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31#include "EXTERN.h"
32#include "perl.h"
33#include "XSUB.h"
34#ifdef __cplusplus
35}
36#endif
37
38#include "patchlevel.h"
39#if PATCHLEVEL <= 4 && !defined(PL_dowarn)
40 #define PL_dowarn dowarn
41#endif
42
43#define MAX_LINE 76 /* size of encoded lines */
44
45static char basis_64[] =
46 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
47
48#define XX 255 /* illegal base64 char */
49#define EQ 254 /* padding */
50#define INVALID XX
51
52static unsigned char index_64[256] = {
53 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
54 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
55 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
56 52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,EQ,XX,XX,
57 XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
58 15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
59 XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
60 41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
61
62 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
63 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
64 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
65 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
66 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
67 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
68 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
69 XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
70};
71
72
73
74MODULE = MIME::Base64 PACKAGE = MIME::Base64
75
76SV*
77encode_base64(sv,...)
78 SV* sv
79 PROTOTYPE: $;$
80
81 PREINIT:
82 char *str; /* string to encode */
83 SSize_t len; /* length of the string */
84 char *eol; /* the end-of-line sequence to use */
85 STRLEN eollen; /* length of the EOL sequence */
86 char *r; /* result string */
87 STRLEN rlen; /* length of result string */
88 unsigned char c1, c2, c3;
89 int chunk;
90
91 CODE:
92 str = SvPV(sv, rlen); /* SvPV(sv, len) gives warning for signed len */
93 len = (SSize_t)rlen;
94
95 /* set up EOL from the second argument if present, default to "\n" */
96 if (items > 1 && SvOK(ST(1))) {
97 eol = SvPV(ST(1), eollen);
98 } else {
99 eol = "\n";
100 eollen = 1;
101 }
102
103 /* calculate the length of the result */
104 rlen = (len+2) / 3 * 4; /* encoded bytes */
105 if (rlen) {
106 /* add space for EOL */
107 rlen += ((rlen-1) / MAX_LINE + 1) * eollen;
108 }
109
110 /* allocate a result buffer */
111 RETVAL = newSV(rlen ? rlen : 1);
112 SvPOK_on(RETVAL);
113 SvCUR_set(RETVAL, rlen);
114 r = SvPVX(RETVAL);
115
116 /* encode */
117 for (chunk=0; len > 0; len -= 3, chunk++) {
118 if (chunk == (MAX_LINE/4)) {
119 char *c = eol;
120 char *e = eol + eollen;
121 while (c < e)
122 *r++ = *c++;
123 chunk = 0;
124 }
125 c1 = *str++;
126 c2 = *str++;
127 *r++ = basis_64[c1>>2];
128 *r++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
129 if (len > 2) {
130 c3 = *str++;
131 *r++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
132 *r++ = basis_64[c3 & 0x3F];
133 } else if (len == 2) {
134 *r++ = basis_64[(c2 & 0xF) << 2];
135 *r++ = '=';
136 } else { /* len == 1 */
137 *r++ = '=';
138 *r++ = '=';
139 }
140 }
141 if (rlen) {
142 /* append eol to the result string */
143 char *c = eol;
144 char *e = eol + eollen;
145 while (c < e)
146 *r++ = *c++;
147 }
148 *r = '\0'; /* every SV in perl should be NUL-terminated */
149
150 OUTPUT:
151 RETVAL
152
153SV*
154decode_base64(sv)
155 SV* sv
156 PROTOTYPE: $
157
158 PREINIT:
159 STRLEN len;
160 register unsigned char *str = (unsigned char*)SvPV(sv, len);
161 unsigned char const* end = str + len;
162 char *r;
163 unsigned char c[4];
164
165 CODE:
166 {
167 /* always enough, but might be too much */
168 STRLEN rlen = len * 3 / 4;
169 RETVAL = newSV(rlen ? rlen : 1);
170 }
171 SvPOK_on(RETVAL);
172 r = SvPVX(RETVAL);
173
174 while (str < end) {
175 int i = 0;
176 do {
177 unsigned char uc = index_64[*str++];
178 if (uc != INVALID)
179 c[i++] = uc;
180
181 if (str == end) {
182 if (i < 4) {
183 if (i && PL_dowarn)
184 warn("Premature end of base64 data");
185 if (i < 2) goto thats_it;
186 if (i == 2) c[2] = EQ;
187 c[3] = EQ;
188 }
189 break;
190 }
191 } while (i < 4);
192
193 if (c[0] == EQ || c[1] == EQ) {
194 if (PL_dowarn) warn("Premature padding of base64 data");
195 break;
196 }
197 /* printf("c0=%d,c1=%d,c2=%d,c3=%d\n", c[0],c[1],c[2],c[3]);/**/
198
199 *r++ = (c[0] << 2) | ((c[1] & 0x30) >> 4);
200
201 if (c[2] == EQ)
202 break;
203 *r++ = ((c[1] & 0x0F) << 4) | ((c[2] & 0x3C) >> 2);
204
205 if (c[3] == EQ)
206 break;
207 *r++ = ((c[2] & 0x03) << 6) | c[3];
208 }
209
210 thats_it:
211 SvCUR_set(RETVAL, r - SvPVX(RETVAL));
212 *r = '\0';
213
214 OUTPUT:
215 RETVAL
Note: See TracBrowser for help on using the repository browser.