2
2
use io:: Reader ;
3
3
4
4
pub trait ToBase64 {
5
- fn to_base64 ( ) -> ~str ;
5
+ pure fn to_base64 ( ) -> ~str ;
6
6
}
7
7
8
8
impl & [ u8 ] : ToBase64 {
9
- fn to_base64( ) -> ~str {
9
+ pure fn to_base64( ) -> ~str {
10
10
let chars = str:: chars (
11
11
~"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +/"
12
12
) ;
13
13
14
- let len = self . len ( ) ;
15
14
let mut s = ~"";
16
- str:: reserve ( & mut s, ( ( len + 3 u) / 4 u) * 3 u) ;
17
-
18
- let mut i = 0 u;
19
-
20
- while i < len - ( len % 3 u) {
21
- let n = ( self [ i] as uint ) << 16 u |
22
- ( self [ i + 1 u] as uint ) << 8 u |
23
- ( self [ i + 2 u] as uint ) ;
24
-
25
- // This 24-bit number gets separated into four 6-bit numbers.
26
- str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
27
- str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
28
- str:: push_char ( & mut s, chars[ ( n >> 6 u) & 63 u] ) ;
29
- str:: push_char ( & mut s, chars[ n & 63 u] ) ;
30
-
31
- i += 3 u;
32
- }
33
-
34
- // Heh, would be cool if we knew this was exhaustive
35
- // (the dream of bounded integer types)
36
- match len % 3 {
37
- 0 => ( ) ,
38
- 1 => {
39
- let n = ( self [ i] as uint ) << 16 u;
40
- str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
41
- str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
42
- str:: push_char ( & mut s, '=' ) ;
43
- str:: push_char ( & mut s, '=' ) ;
44
- }
45
- 2 => {
46
- let n = ( self [ i] as uint ) << 16 u | ( self [ i + 1 u] as uint ) << 8 u;
47
- str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
48
- str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
49
- str:: push_char ( & mut s, chars[ ( n >> 6 u) & 63 u] ) ;
50
- str:: push_char ( & mut s, '=' ) ;
51
- }
52
- _ => fail ~"Algebra is broken, please alert the math police"
15
+ unsafe {
16
+ let len = self . len ( ) ;
17
+ str:: reserve ( & mut s, ( ( len + 3 u) / 4 u) * 3 u) ;
18
+
19
+ let mut i = 0 u;
20
+
21
+ while i < len - ( len % 3 u) {
22
+ let n = ( self [ i] as uint ) << 16 u |
23
+ ( self [ i + 1 u] as uint ) << 8 u |
24
+ ( self [ i + 2 u] as uint ) ;
25
+
26
+ // This 24-bit number gets separated into four 6-bit numbers.
27
+ str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
28
+ str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
29
+ str:: push_char ( & mut s, chars[ ( n >> 6 u) & 63 u] ) ;
30
+ str:: push_char ( & mut s, chars[ n & 63 u] ) ;
31
+
32
+ i += 3 u;
33
+ }
34
+
35
+ // Heh, would be cool if we knew this was exhaustive
36
+ // (the dream of bounded integer types)
37
+ match len % 3 {
38
+ 0 => ( ) ,
39
+ 1 => {
40
+ let n = ( self [ i] as uint ) << 16 u;
41
+ str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
42
+ str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
43
+ str:: push_char ( & mut s, '=' ) ;
44
+ str:: push_char ( & mut s, '=' ) ;
45
+ }
46
+ 2 => {
47
+ let n = ( self [ i] as uint ) << 16 u | ( self [ i + 1 u] as uint ) << 8 u;
48
+ str:: push_char ( & mut s, chars[ ( n >> 18 u) & 63 u] ) ;
49
+ str:: push_char ( & mut s, chars[ ( n >> 12 u) & 63 u] ) ;
50
+ str:: push_char ( & mut s, chars[ ( n >> 6 u) & 63 u] ) ;
51
+ str:: push_char ( & mut s, '=' ) ;
52
+ }
53
+ _ => fail ~"Algebra is broken, please alert the math police"
54
+ }
53
55
}
54
-
55
56
s
56
57
}
57
58
}
58
59
59
60
impl & str : ToBase64 {
60
- fn to_base64( ) -> ~str {
61
+ pure fn to_base64( ) -> ~str {
61
62
str:: to_bytes( self ) . to_base64( )
62
63
}
63
64
}
64
65
65
66
pub trait FromBase64 {
66
- fn from_base64( ) -> ~[ u8] ;
67
+ pure fn from_base64( ) -> ~[ u8] ;
67
68
}
68
69
69
70
impl ~[ u8] : FromBase64 {
70
- fn from_base64( ) -> ~[ u8] {
71
+ pure fn from_base64( ) -> ~[ u8] {
71
72
if self . len( ) % 4 u != 0 u { fail ~"invalid base64 length"; }
72
73
73
74
let len = self . len( ) ;
@@ -80,55 +81,56 @@ impl ~[u8]: FromBase64 {
80
81
81
82
let mut r = vec:: with_capacity( ( len / 4 u) * 3 u - padding) ;
82
83
83
- let mut i = 0 u;
84
- while i < len {
85
- let mut n = 0 u;
86
-
87
- for iter:: repeat( 4 u) {
88
- let ch = self [ i] as char ;
89
- n <<= 6 u;
90
-
91
- if ch >= 'A' && ch <= 'Z' {
92
- n |= ( ch as uint ) - 0x41 u;
93
- } else if ch >= 'a' && ch <= 'z' {
94
- n |= ( ch as uint ) - 0x47 u;
95
- } else if ch >= '0' && ch <= '9' {
96
- n |= ( ch as uint ) + 0x04 u;
97
- } else if ch == '+' {
98
- n |= 0x3E u;
99
- } else if ch == '/' {
100
- n |= 0x3F u;
101
- } else if ch == '=' {
102
- match len - i {
103
- 1 u => {
104
- r. push ( ( ( n >> 16 u) & 0xFF u) as u8 ) ;
105
- r. push ( ( ( n >> 8 u ) & 0xFF u) as u8 ) ;
106
- return copy r;
107
- }
108
- 2 u => {
109
- r. push ( ( ( n >> 10 u) & 0xFF u) as u8 ) ;
110
- return copy r;
111
- }
112
- _ => fail ~"invalid base64 padding"
84
+ unsafe {
85
+ let mut i = 0 u;
86
+ while i < len {
87
+ let mut n = 0 u;
88
+
89
+ for iter:: repeat( 4 u) {
90
+ let ch = self [ i] as char ;
91
+ n <<= 6 u;
92
+
93
+ if ch >= 'A' && ch <= 'Z' {
94
+ n |= ( ch as uint ) - 0x41 u;
95
+ } else if ch >= 'a' && ch <= 'z' {
96
+ n |= ( ch as uint ) - 0x47 u;
97
+ } else if ch >= '0' && ch <= '9' {
98
+ n |= ( ch as uint ) + 0x04 u;
99
+ } else if ch == '+' {
100
+ n |= 0x3E u;
101
+ } else if ch == '/' {
102
+ n |= 0x3F u;
103
+ } else if ch == '=' {
104
+ match len - i {
105
+ 1 u => {
106
+ r. push ( ( ( n >> 16 u) & 0xFF u) as u8 ) ;
107
+ r. push ( ( ( n >> 8 u ) & 0xFF u) as u8 ) ;
108
+ return copy r;
109
+ }
110
+ 2 u => {
111
+ r. push ( ( ( n >> 10 u) & 0xFF u) as u8 ) ;
112
+ return copy r;
113
+ }
114
+ _ => fail ~"invalid base64 padding"
115
+ }
116
+ } else {
117
+ fail ~"invalid base64 character";
113
118
}
114
- } else {
115
- fail ~"invalid base64 character";
116
- }
117
-
118
- i += 1 u;
119
- } ;
120
-
121
- r. push ( ( ( n >> 16 u) & 0xFF u) as u8 ) ;
122
- r. push ( ( ( n >> 8 u ) & 0xFF u) as u8 ) ;
123
- r. push ( ( ( n ) & 0xFF u) as u8 ) ;
119
+
120
+ i += 1 u;
121
+ } ;
122
+
123
+ r. push ( ( ( n >> 16 u) & 0xFF u) as u8 ) ;
124
+ r. push ( ( ( n >> 8 u ) & 0xFF u) as u8 ) ;
125
+ r. push ( ( ( n ) & 0xFF u) as u8 ) ;
126
+ }
124
127
}
125
-
126
128
r
127
129
}
128
130
}
129
131
130
132
impl ~str : FromBase64 {
131
- fn from_base64( ) -> ~[ u8 ] {
133
+ pure fn from_base64( ) -> ~[ u8 ] {
132
134
str :: to_bytes( self ) . from_base64( )
133
135
}
134
136
}
0 commit comments