annotate lphobos/std/base64.d @ 650:aa6a0b7968f7

Added test case for bug #100 Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 05 Oct 2008 17:28:15 +0200
parents a7dfa0ed966c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
130
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
1 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
2 * Encodes/decodes MIME base64 data.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
3 *
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
4 * Macros:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
5 * WIKI=Phobos/StdBase64
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
6 * References:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
7 * <a href="http://en.wikipedia.org/wiki/Base64">Wikipedia Base64</a>$(BR)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
8 * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>$(BR)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
9 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
10
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
11
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
12 /* base64.d
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
13 * Modified from C. Miller's version, his copyright is below.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
14 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
15
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
16 /*
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
17 Copyright (C) 2004 Christopher E. Miller
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
18
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
19 This software is provided 'as-is', without any express or implied
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
20 warranty. In no event will the authors be held liable for any damages
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
21 arising from the use of this software.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
22
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
23 Permission is granted to anyone to use this software for any purpose,
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
24 including commercial applications, and to alter it and redistribute it
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
25 freely, subject to the following restrictions:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
26
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
27 1. The origin of this software must not be misrepresented; you must not
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
28 claim that you wrote the original software. If you use this software
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
29 in a product, an acknowledgment in the product documentation would be
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
30 appreciated but is not required.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
31 2. Altered source versions must be plainly marked as such, and must not be
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
32 misrepresented as being the original software.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
33 3. This notice may not be removed or altered from any source distribution.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
34 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
35
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
36 module std.base64;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
37
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
38 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
39 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
40
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
41 class Base64Exception: Exception
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
42 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
43 this(char[] msg)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
44 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
45 super(msg);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
46 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
47 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
48
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
49
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
50 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
51 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
52
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
53 class Base64CharException: Base64Exception
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
54 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
55 this(char[] msg)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
56 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
57 super(msg);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
58 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
59 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
60
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
61
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
62 const char[] array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
63
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
64
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
65 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
66 * Returns the number of bytes needed to encode a string of length slen.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
67 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
68
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
69 uint encodeLength(uint slen)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
70 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
71 uint result;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
72 result = slen / 3;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
73 if(slen % 3)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
74 result++;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
75 return result * 4;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
76 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
77
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
78 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
79 * Encodes str[] and places the result in buf[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
80 * Params:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
81 * str = string to encode
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
82 * buf = destination buffer, must be large enough for the result.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
83 * Returns:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
84 * slice into buf[] representing encoded result
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
85 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
86
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
87 char[] encode(char[] str, char[] buf)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
88 in
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
89 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
90 assert(buf.length >= encodeLength(str.length));
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
91 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
92 body
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
93 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
94 if(!str.length)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
95 return buf[0 .. 0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
96
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
97 uint stri;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
98 uint strmax = str.length / 3;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
99 uint strleft = str.length % 3;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
100 uint x;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
101 char* sp, bp;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
102
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
103 bp = &buf[0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
104 sp = &str[0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
105 for(stri = 0; stri != strmax; stri++)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
106 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
107 x = (sp[0] << 16) | (sp[1] << 8) | (sp[2]);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
108 sp+= 3;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
109 *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
110 *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
111 *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
112 *bp++ = array[(x & 0b00000000_00000000_00111111)];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
113 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
114
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
115 switch(strleft)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
116 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
117 case 2:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
118 x = (sp[0] << 16) | (sp[1] << 8);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
119 sp += 2;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
120 *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
121 *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
122 *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
123 *bp++ = '=';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
124 break;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
125
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
126 case 1:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
127 x = *sp++ << 16;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
128 *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
129 *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
130 *bp++ = '=';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
131 *bp++ = '=';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
132 break;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
133
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
134 case 0:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
135 break;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
136
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
137 default:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
138 assert(0);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
139 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
140
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
141 return buf[0 .. (bp - &buf[0])];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
142 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
143
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
144
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
145 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
146 * Encodes str[] and returns the result.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
147 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
148
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
149 char[] encode(char[] str)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
150 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
151 return encode(str, new char[encodeLength(str.length)]);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
152 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
153
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
154
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
155 unittest
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
156 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
157 assert(encode("f") == "Zg==");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
158 assert(encode("fo") == "Zm8=");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
159 assert(encode("foo") == "Zm9v");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
160 assert(encode("foos") == "Zm9vcw==");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
161 assert(encode("all your base64 are belong to foo") == "YWxsIHlvdXIgYmFzZTY0IGFyZSBiZWxvbmcgdG8gZm9v");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
162 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
163
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
164
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
165 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
166 * Returns the number of bytes needed to decode an encoded string of this
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
167 * length.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
168 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
169 uint decodeLength(uint elen)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
170 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
171 return elen / 4 * 3;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
172 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
173
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
174
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
175 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
176 * Decodes str[] and places the result in buf[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
177 * Params:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
178 * str = string to encode
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
179 * buf = destination buffer, must be large enough for the result.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
180 * Returns:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
181 * slice into buf[] representing encoded result
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
182 * Errors:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
183 * Throws Base64Exception on invalid base64 encoding in estr[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
184 * Throws Base64CharException on invalid base64 character in estr[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
185 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
186 char[] decode(char[] estr, char[] buf)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
187 in
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
188 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
189 assert(buf.length + 2 >= decodeLength(estr.length)); //account for '=' padding
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
190 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
191 body
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
192 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
193 void badc(char ch)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
194 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
195 throw new Base64CharException("Invalid base64 character '" ~ (&ch)[0 .. 1] ~ "'");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
196 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
197
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
198
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
199 uint arrayIndex(char ch)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
200 out(result)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
201 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
202 assert(ch == array[result]);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
203 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
204 body
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
205 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
206 if(ch >= 'A' && ch <= 'Z')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
207 return ch - 'A';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
208 if(ch >= 'a' && ch <= 'z')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
209 return 'Z' - 'A' + 1 + ch - 'a';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
210 if(ch >= '0' && ch <= '9')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
211 return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + ch - '0';
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
212 if(ch == '+')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
213 return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
214 if(ch == '/')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
215 return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1 + 1;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
216 badc(ch);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
217 assert(0);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
218 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
219
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
220
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
221 if(!estr.length)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
222 return buf[0 .. 0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
223
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
224 if(estr.length % 4)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
225 throw new Base64Exception("Invalid encoded base64 string");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
226
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
227 uint estri;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
228 uint estrmax = estr.length / 4;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
229 uint x;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
230 char* sp, bp;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
231 char ch;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
232
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
233 sp = &estr[0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
234 bp = &buf[0];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
235 for(estri = 0; estri != estrmax; estri++)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
236 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
237 x = arrayIndex(sp[0]) << 18 | arrayIndex(sp[1]) << 12;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
238 sp += 2;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
239
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
240 ch = *sp++;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
241 if(ch == '=')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
242 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
243 if(*sp++ != '=')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
244 badc('=');
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
245 *bp++ = cast(char) (x >> 16);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
246 break;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
247 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
248 x |= arrayIndex(ch) << 6;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
249
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
250 ch = *sp++;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
251 if(ch == '=')
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
252 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
253 *bp++ = cast(char) (x >> 16);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
254 *bp++ = cast(char) ((x >> 8) & 0xFF);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
255 break;
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
256 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
257 x |= arrayIndex(ch);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
258
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
259 *bp++ = cast(char) (x >> 16);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
260 *bp++ = cast(char) ((x >> 8) & 0xFF);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
261 *bp++ = cast(char) (x & 0xFF);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
262 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
263
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
264 return buf[0 .. (bp - &buf[0])];
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
265 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
266
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
267 /**
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
268 * Decodes estr[] and returns the result.
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
269 * Errors:
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
270 * Throws Base64Exception on invalid base64 encoding in estr[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
271 * Throws Base64CharException on invalid base64 character in estr[].
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
272 */
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
273
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
274 char[] decode(char[] estr)
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
275 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
276 return decode(estr, new char[decodeLength(estr.length)]);
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
277 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
278
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
279
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
280 unittest
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
281 {
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
282 assert(decode(encode("f")) == "f");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
283 assert(decode(encode("fo")) == "fo");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
284 assert(decode(encode("foo")) == "foo");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
285 assert(decode(encode("foos")) == "foos");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
286 assert(decode(encode("all your base64 are belong to foo")) == "all your base64 are belong to foo");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
287
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
288 assert(decode(encode("testing some more")) == "testing some more");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
289 assert(decode(encode("asdf jkl;")) == "asdf jkl;");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
290 assert(decode(encode("base64 stuff")) == "base64 stuff");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
291 assert(decode(encode("\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!")) == "\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!");
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
292 }
a7dfa0ed966c [svn r134] Merged the DMD 1.024 frontend.
lindquist
parents:
diff changeset
293