@@ -44,69 +44,69 @@ public Base64Encoder()
44
44
InitialiseDecodingTable ( ) ;
45
45
}
46
46
47
- /**
48
- * encode the input data producing a base 64 output stream.
49
- *
50
- * @return the number of bytes produced.
51
- */
52
- public int Encode (
53
- byte [ ] data ,
54
- int off ,
55
- int length ,
56
- Stream outStream )
47
+ public int Encode ( byte [ ] inBuf , int inOff , int inLen , byte [ ] outBuf , int outOff )
57
48
{
58
- int modulus = length % 3 ;
59
- int dataLength = ( length - modulus ) ;
60
- int a1 , a2 , a3 ;
49
+ int inPos = inOff ;
50
+ int inEnd = inOff + inLen - 2 ;
51
+ int outPos = outOff ;
61
52
62
- for ( int i = off ; i < off + dataLength ; i += 3 )
53
+ while ( inPos < inEnd )
63
54
{
64
- a1 = data [ i ] & 0xff ;
65
- a2 = data [ i + 1 ] & 0xff ;
66
- a3 = data [ i + 2 ] & 0xff ;
67
-
68
- outStream . WriteByte ( encodingTable [ ( int ) ( ( uint ) a1 >> 2 ) & 0x3f ] ) ;
69
- outStream . WriteByte ( encodingTable [ ( ( a1 << 4 ) | ( int ) ( ( uint ) a2 >> 4 ) ) & 0x3f ] ) ;
70
- outStream . WriteByte ( encodingTable [ ( ( a2 << 2 ) | ( int ) ( ( uint ) a3 >> 6 ) ) & 0x3f ] ) ;
71
- outStream . WriteByte ( encodingTable [ a3 & 0x3f ] ) ;
55
+ uint a1 = inBuf [ inPos ++ ] ;
56
+ uint a2 = inBuf [ inPos ++ ] ;
57
+ uint a3 = inBuf [ inPos ++ ] ;
58
+
59
+ outBuf [ outPos ++ ] = encodingTable [ ( a1 >> 2 ) & 0x3F ] ;
60
+ outBuf [ outPos ++ ] = encodingTable [ ( ( a1 << 4 ) | ( a2 >> 4 ) ) & 0x3F ] ;
61
+ outBuf [ outPos ++ ] = encodingTable [ ( ( a2 << 2 ) | ( a3 >> 6 ) ) & 0x3F ] ;
62
+ outBuf [ outPos ++ ] = encodingTable [ a3 & 0x3F ] ;
72
63
}
73
64
74
- /*
75
- * process the tail end.
76
- */
77
- int b1 , b2 , b3 ;
78
- int d1 , d2 ;
65
+ switch ( inLen - ( inPos - inOff ) )
66
+ {
67
+ case 1 :
68
+ {
69
+ uint a1 = inBuf [ inPos ++ ] ;
79
70
80
- switch ( modulus )
71
+ outBuf [ outPos ++ ] = encodingTable [ ( a1 >> 2 ) & 0x3F ] ;
72
+ outBuf [ outPos ++ ] = encodingTable [ ( a1 << 4 ) & 0x3F ] ;
73
+ outBuf [ outPos ++ ] = padding ;
74
+ outBuf [ outPos ++ ] = padding ;
75
+ break ;
76
+ }
77
+ case 2 :
81
78
{
82
- case 0 : /* nothing left to do */
83
- break ;
84
- case 1 :
85
- d1 = data [ off + dataLength ] & 0xff ;
86
- b1 = ( d1 >> 2 ) & 0x3f ;
87
- b2 = ( d1 << 4 ) & 0x3f ;
88
-
89
- outStream . WriteByte ( encodingTable [ b1 ] ) ;
90
- outStream . WriteByte ( encodingTable [ b2 ] ) ;
91
- outStream . WriteByte ( padding ) ;
92
- outStream . WriteByte ( padding ) ;
93
- break ;
94
- case 2 :
95
- d1 = data [ off + dataLength ] & 0xff ;
96
- d2 = data [ off + dataLength + 1 ] & 0xff ;
97
-
98
- b1 = ( d1 >> 2 ) & 0x3f ;
99
- b2 = ( ( d1 << 4 ) | ( d2 >> 4 ) ) & 0x3f ;
100
- b3 = ( d2 << 2 ) & 0x3f ;
101
-
102
- outStream . WriteByte ( encodingTable [ b1 ] ) ;
103
- outStream . WriteByte ( encodingTable [ b2 ] ) ;
104
- outStream . WriteByte ( encodingTable [ b3 ] ) ;
105
- outStream . WriteByte ( padding ) ;
106
- break ;
79
+ uint a1 = inBuf [ inPos ++ ] ;
80
+ uint a2 = inBuf [ inPos ++ ] ;
81
+
82
+ outBuf [ outPos ++ ] = encodingTable [ ( a1 >> 2 ) & 0x3F ] ;
83
+ outBuf [ outPos ++ ] = encodingTable [ ( ( a1 << 4 ) | ( a2 >> 4 ) ) & 0x3F ] ;
84
+ outBuf [ outPos ++ ] = encodingTable [ ( a2 << 2 ) & 0x3F ] ;
85
+ outBuf [ outPos ++ ] = padding ;
86
+ break ;
107
87
}
88
+ }
89
+
90
+ return outPos - outOff ;
91
+ }
108
92
109
- return ( dataLength / 3 ) * 4 + ( ( modulus == 0 ) ? 0 : 4 ) ;
93
+ /**
94
+ * encode the input data producing a base 64 output stream.
95
+ *
96
+ * @return the number of bytes produced.
97
+ */
98
+ public int Encode ( byte [ ] buf , int off , int len , Stream outStream )
99
+ {
100
+ byte [ ] tmp = new byte [ 72 ] ;
101
+ while ( len > 0 )
102
+ {
103
+ int inLen = System . Math . Min ( 54 , len ) ;
104
+ int outLen = Encode ( buf , off , inLen , tmp , 0 ) ;
105
+ outStream . Write ( tmp , 0 , outLen ) ;
106
+ off += inLen ;
107
+ len -= inLen ;
108
+ }
109
+ return ( ( len + 2 ) / 3 ) * 4 ;
110
110
}
111
111
112
112
private bool ignore (
@@ -128,8 +128,9 @@ public int Decode(
128
128
Stream outStream )
129
129
{
130
130
byte b1 , b2 , b3 , b4 ;
131
+ byte [ ] outBuffer = new byte [ 54 ] ; // S/MIME standard
132
+ int bufOff = 0 ;
131
133
int outLen = 0 ;
132
-
133
134
int end = off + length ;
134
135
135
136
while ( end > off )
@@ -166,16 +167,32 @@ public int Decode(
166
167
if ( ( b1 | b2 | b3 | b4 ) >= 0x80 )
167
168
throw new IOException ( "invalid characters encountered in base64 data" ) ;
168
169
169
- outStream . WriteByte ( ( byte ) ( ( b1 << 2 ) | ( b2 >> 4 ) ) ) ;
170
- outStream . WriteByte ( ( byte ) ( ( b2 << 4 ) | ( b3 >> 2 ) ) ) ;
171
- outStream . WriteByte ( ( byte ) ( ( b3 << 6 ) | b4 ) ) ;
170
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b1 << 2 ) | ( b2 >> 4 ) ) ;
171
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b2 << 4 ) | ( b3 >> 2 ) ) ;
172
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b3 << 6 ) | b4 ) ;
173
+
174
+ if ( bufOff == outBuffer . Length )
175
+ {
176
+ outStream . Write ( outBuffer , 0 , bufOff ) ;
177
+ bufOff = 0 ;
178
+ }
172
179
173
180
outLen += 3 ;
174
181
175
182
i = nextI ( data , i , finish ) ;
176
183
}
177
184
178
- outLen += decodeLastBlock ( outStream , ( char ) data [ end - 4 ] , ( char ) data [ end - 3 ] , ( char ) data [ end - 2 ] , ( char ) data [ end - 1 ] ) ;
185
+ if ( bufOff > 0 )
186
+ {
187
+ outStream . Write ( outBuffer , 0 , bufOff ) ;
188
+ }
189
+
190
+ int e0 = nextI ( data , i , end ) ;
191
+ int e1 = nextI ( data , e0 + 1 , end ) ;
192
+ int e2 = nextI ( data , e1 + 1 , end ) ;
193
+ int e3 = nextI ( data , e2 + 1 , end ) ;
194
+
195
+ outLen += decodeLastBlock ( outStream , ( char ) data [ e0 ] , ( char ) data [ e1 ] , ( char ) data [ e2 ] , ( char ) data [ e3 ] ) ;
179
196
180
197
return outLen ;
181
198
}
@@ -208,8 +225,9 @@ public int DecodeString(
208
225
// return bytes.Length;
209
226
210
227
byte b1 , b2 , b3 , b4 ;
228
+ byte [ ] outBuffer = new byte [ 54 ] ; // S/MIME standard
229
+ int bufOff = 0 ;
211
230
int length = 0 ;
212
-
213
231
int end = data . Length ;
214
232
215
233
while ( end > 0 )
@@ -246,16 +264,32 @@ public int DecodeString(
246
264
if ( ( b1 | b2 | b3 | b4 ) >= 0x80 )
247
265
throw new IOException ( "invalid characters encountered in base64 data" ) ;
248
266
249
- outStream . WriteByte ( ( byte ) ( ( b1 << 2 ) | ( b2 >> 4 ) ) ) ;
250
- outStream . WriteByte ( ( byte ) ( ( b2 << 4 ) | ( b3 >> 2 ) ) ) ;
251
- outStream . WriteByte ( ( byte ) ( ( b3 << 6 ) | b4 ) ) ;
267
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b1 << 2 ) | ( b2 >> 4 ) ) ;
268
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b2 << 4 ) | ( b3 >> 2 ) ) ;
269
+ outBuffer [ bufOff ++ ] = ( byte ) ( ( b3 << 6 ) | b4 ) ;
252
270
253
271
length += 3 ;
254
272
273
+ if ( bufOff == outBuffer . Length )
274
+ {
275
+ outStream . Write ( outBuffer , 0 , bufOff ) ;
276
+ bufOff = 0 ;
277
+ }
278
+
255
279
i = nextI ( data , i , finish ) ;
256
280
}
257
281
258
- length += decodeLastBlock ( outStream , data [ end - 4 ] , data [ end - 3 ] , data [ end - 2 ] , data [ end - 1 ] ) ;
282
+ if ( bufOff > 0 )
283
+ {
284
+ outStream . Write ( outBuffer , 0 , bufOff ) ;
285
+ }
286
+
287
+ int e0 = nextI ( data , i , end ) ;
288
+ int e1 = nextI ( data , e0 + 1 , end ) ;
289
+ int e2 = nextI ( data , e1 + 1 , end ) ;
290
+ int e3 = nextI ( data , e2 + 1 , end ) ;
291
+
292
+ length += decodeLastBlock ( outStream , data [ e0 ] , data [ e1 ] , data [ e2 ] , data [ e3 ] ) ;
259
293
260
294
return length ;
261
295
}
0 commit comments