annotate lphobos/std/base64.d @ 883:b52d5de7783f

GC defines and linkage changes.
author Christian Kamm <kamm incasoftware de>
date Thu, 08 Jan 2009 18:20:02 +0100
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