10
10
11
11
//! Base64 binary-to-text encoding
12
12
13
+ /// Available encoding character sets
14
+ pub enum CharacterSet {
15
+ /// The standard character set (uses '+' and '/')
16
+ Standard ,
17
+ /// The URL safe character set (uses '-' and '_')
18
+ UrlSafe
19
+ }
20
+
13
21
/// Contains configuration parameters for to_base64
14
22
pub struct Config {
15
- /// True to use the url-safe encoding format ('-' and '_'), false to use
16
- /// the standard encoding format ('+' and '/')
17
- pub url_safe : bool ,
23
+ /// Character set to use
24
+ char_set : CharacterSet ,
18
25
/// True to pad output with '=' characters
19
- pub pad : bool ,
26
+ pad : bool ,
20
27
/// Some(len) to wrap lines at len, None to disable line wrapping
21
- pub line_length : Option < uint >
28
+ line_length : Option < uint >
22
29
}
23
30
24
31
/// Configuration for RFC 4648 standard base64 encoding
25
32
pub static standard: Config =
26
- Config { url_safe : false , pad : true , line_length : None } ;
33
+ Config { char_set : Standard , pad : true , line_length : None } ;
27
34
28
35
/// Configuration for RFC 4648 base64url encoding
29
36
pub static url_safe: Config =
30
- Config { url_safe : true , pad : false , line_length : None } ;
37
+ Config { char_set : UrlSafe , pad : false , line_length : None } ;
31
38
32
39
/// Configuration for RFC 2045 MIME base64 encoding
33
40
pub static mime: Config =
34
- Config { url_safe : false , pad : true , line_length : Some ( 76 ) } ;
41
+ Config { char_set : Standard , pad : true , line_length : Some ( 76 ) } ;
35
42
36
43
static STANDARD_CHARS : [ char , ..64 ] = [
37
44
'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' ,
@@ -63,7 +70,8 @@ impl<'self> ToBase64 for &'self [u8] {
63
70
* # Example
64
71
*
65
72
* ~~~ {.rust}
66
- * use std::base64::{ToBase64, standard};
73
+ * extern mod extra;
74
+ * use extra::base64::{ToBase64, standard};
67
75
*
68
76
* fn main () {
69
77
* let str = [52,32].to_base64(standard);
@@ -72,9 +80,9 @@ impl<'self> ToBase64 for &'self [u8] {
72
80
* ~~~
73
81
*/
74
82
fn to_base64 ( & self , config : Config ) -> ~str {
75
- let chars = match config. url_safe {
76
- true => URLSAFE_CHARS ,
77
- false => STANDARD_CHARS
83
+ let chars = match config. char_set {
84
+ Standard => STANDARD_CHARS ,
85
+ UrlSafe => URLSAFE_CHARS
78
86
} ;
79
87
80
88
let mut s = ~"";
@@ -151,7 +159,8 @@ impl<'self> ToBase64 for &'self str {
151
159
* # Example
152
160
*
153
161
* ~~~ {.rust}
154
- * use std::base64::{ToBase64, standard};
162
+ * extern mod extra;
163
+ * use extra::base64::{ToBase64, standard};
155
164
*
156
165
* fn main () {
157
166
* let str = "Hello, World".to_base64(standard);
@@ -169,7 +178,7 @@ impl<'self> ToBase64 for &'self str {
169
178
pub trait FromBase64 {
170
179
/// Converts the value of `self`, interpreted as base64 encoded data, into
171
180
/// an owned vector of bytes, returning the vector.
172
- fn from_base64 ( & self ) -> ~[ u8 ] ;
181
+ fn from_base64 ( & self ) -> Result < ~[ u8 ] , ~ str > ;
173
182
}
174
183
175
184
impl < ' self > FromBase64 for & ' self [ u8 ] {
@@ -180,7 +189,8 @@ impl<'self> FromBase64 for &'self [u8] {
180
189
* # Example
181
190
*
182
191
* ~~~ {.rust}
183
- * use std::base64::{ToBase64, FromBase64, standard};
192
+ * extern mod extra;
193
+ * use extra::base64::{ToBase64, FromBase64, standard};
184
194
*
185
195
* fn main () {
186
196
* let str = [52,32].to_base64(standard);
@@ -190,7 +200,7 @@ impl<'self> FromBase64 for &'self [u8] {
190
200
* }
191
201
* ~~~
192
202
*/
193
- fn from_base64 ( & self ) -> ~[ u8 ] {
203
+ fn from_base64 ( & self ) -> Result < ~[ u8 ] , ~ str > {
194
204
let mut r = ~[ ] ;
195
205
let mut buf: u32 = 0 ;
196
206
let mut modulus = 0 ;
@@ -208,7 +218,7 @@ impl<'self> FromBase64 for &'self [u8] {
208
218
'/' |'_' => buf |= 0x3F ,
209
219
'\r' |'\n' => loop ,
210
220
'=' => break ,
211
- _ => fail ! ( "Invalid Base64 character" )
221
+ _ => return Err ( ~ "Invalid Base64 character")
212
222
}
213
223
214
224
buf <<= 6 ;
@@ -222,7 +232,7 @@ impl<'self> FromBase64 for &'self [u8] {
222
232
}
223
233
224
234
if !it. all ( |& byte| { byte as char == '=' } ) {
225
- fail ! ( "Invalid Base64 character" ) ;
235
+ return Err ( ~ "Invalid Base64 character") ;
226
236
}
227
237
228
238
match modulus {
@@ -234,10 +244,10 @@ impl<'self> FromBase64 for &'self [u8] {
234
244
r. push ( ( buf >> 8 ) as u8 ) ;
235
245
}
236
246
0 => ( ) ,
237
- _ => fail ! ( "Invalid Base64 length" )
247
+ _ => return Err ( ~ "Invalid Base64 length")
238
248
}
239
249
240
- r
250
+ Ok ( r )
241
251
}
242
252
}
243
253
@@ -255,7 +265,8 @@ impl<'self> FromBase64 for &'self str {
255
265
* This converts a string literal to base64 and back.
256
266
*
257
267
* ~~~ {.rust}
258
- * use std::base64::{ToBase64, FromBase64, standard};
268
+ * extern mod extra;
269
+ * use extra::base64::{ToBase64, FromBase64, standard};
259
270
* use std::str;
260
271
*
261
272
* fn main () {
@@ -268,7 +279,7 @@ impl<'self> FromBase64 for &'self str {
268
279
* }
269
280
* ~~~
270
281
*/
271
- fn from_base64 ( & self ) -> ~[ u8 ] {
282
+ fn from_base64 ( & self ) -> Result < ~[ u8 ] , ~ str > {
272
283
self . as_bytes ( ) . from_base64 ( )
273
284
}
274
285
}
@@ -306,36 +317,48 @@ fn test_to_base64_url_safe() {
306
317
307
318
#[test]
308
319
fn test_from_base64_basic() {
309
- assert_eq!(" ".from_base64(), " ".as_bytes().to_owned());
310
- assert_eq!(" Zg ==".from_base64(), " f".as_bytes().to_owned());
311
- assert_eq!(" Zm8 =".from_base64(), " fo".as_bytes().to_owned());
312
- assert_eq!(" Zm9v ".from_base64(), " foo".as_bytes().to_owned());
313
- assert_eq!(" Zm9vYg ==".from_base64(), " foob".as_bytes().to_owned());
314
- assert_eq!(" Zm9vYmE =".from_base64(), " fooba".as_bytes().to_owned());
315
- assert_eq!(" Zm9vYmFy ".from_base64(), " foobar".as_bytes().to_owned());
320
+ assert_eq!(" ".from_base64().get() , " ".as_bytes().to_owned());
321
+ assert_eq!(" Zg ==".from_base64().get() , " f".as_bytes().to_owned());
322
+ assert_eq!(" Zm8 =".from_base64().get() , " fo".as_bytes().to_owned());
323
+ assert_eq!(" Zm9v ".from_base64().get() , " foo".as_bytes().to_owned());
324
+ assert_eq!(" Zm9vYg ==".from_base64().get() , " foob".as_bytes().to_owned());
325
+ assert_eq!(" Zm9vYmE =".from_base64().get() , " fooba".as_bytes().to_owned());
326
+ assert_eq!(" Zm9vYmFy ".from_base64().get() , " foobar".as_bytes().to_owned());
316
327
}
317
328
318
329
#[test]
319
330
fn test_from_base64_newlines() {
320
- assert_eq!(" Zm9v \r \n YmFy ".from_base64(), " foobar".as_bytes().to_owned());
331
+ assert_eq!(" Zm9v \r \n YmFy ".from_base64().get(),
332
+ " foobar".as_bytes().to_owned());
321
333
}
322
334
323
335
#[test]
324
336
fn test_from_base64_urlsafe() {
325
- assert_eq!(" -_8".from_base64(), " +/8 =" . from_base64( ) ) ;
337
+ assert_eq!(" -_8".from_base64().get(), " +/8 =".from_base64().get());
338
+ }
339
+
340
+ #[test]
341
+ fn test_from_base64_invalid_char() {
342
+ assert!(" Zm $=".from_base64().is_err())
343
+ assert!(" Zg ==$".from_base64().is_err());
344
+ }
345
+
346
+ #[test]
347
+ fn test_from_base64_invalid_padding() {
348
+ assert!(" Z ===" . from_base64( ) . is_err( ) ) ;
326
349
}
327
350
328
351
#[ test]
329
352
fn test_base64_random( ) {
330
- use std:: rand:: random;
353
+ use std:: rand:: { task_rng , random, RngUtil } ;
331
354
use std:: vec;
332
355
333
356
for 1000 . times {
334
357
let v: ~[ u8] = do vec:: build |push| {
335
- for 100 . times {
358
+ for task_rng ( ) . gen_uint_range ( 1 , 100 ) . times {
336
359
push( random( ) ) ;
337
360
}
338
361
} ;
339
- assert_eq ! ( v. to_base64( standard) . from_base64( ) , v) ;
362
+ assert_eq ! ( v. to_base64( standard) . from_base64( ) . get ( ) , v) ;
340
363
}
341
364
}
0 commit comments