1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.io;
16  
17  import com.liferay.portal.kernel.util.CharPool;
18  
19  import java.io.IOException;
20  import java.io.OutputStream;
21  
22  /**
23   * <a href="Base64OutputStream.java.html"><b><i>View Source</i></b></a>
24   *
25   * @author Tina Tian
26   */
27  public class Base64OutputStream extends OutputStream {
28  
29      public Base64OutputStream(OutputStream outputStream) {
30          _outputStream = outputStream;
31          _unitBuffer = new byte[3];
32          _unitBufferIndex = 0;
33          _outputBuffer = new byte[4];
34      }
35  
36      public void close() throws IOException {
37          flush();
38  
39          _outputStream.close();
40      }
41  
42      public void flush() throws IOException {
43          if (_unitBufferIndex == 1) {
44              encodeUnit(_unitBuffer[0]);
45          }
46          else if (_unitBufferIndex == 2) {
47              encodeUnit(_unitBuffer[0], _unitBuffer[1]);
48          }
49  
50          _unitBufferIndex = 0;
51  
52          _outputStream.flush();
53      }
54  
55      public void write(byte[] bytes) throws IOException {
56          write(bytes, 0, bytes.length);
57      }
58  
59      public void write(byte[] bytes, int offset, int length) throws IOException {
60          if (length <= 0) {
61              return;
62          }
63  
64          while ((_unitBufferIndex != 0) && (length > 0)) {
65              write(bytes[offset++]);
66  
67              length--;
68          }
69  
70          if (length <= 0) {
71              return;
72          }
73  
74          int bytesLength = length - (length % 3);
75  
76          length -= bytesLength;
77  
78          while (bytesLength > 0) {
79              encodeUnit(bytes[offset], bytes[offset + 1], bytes[offset + 2]);
80  
81              bytesLength -=3 ;
82              offset += 3;
83          }
84  
85          while (length > 0) {
86              write(bytes[offset++]);
87  
88              length--;
89          }
90      }
91  
92      public void write(int byteValue) throws IOException {
93          _unitBuffer[_unitBufferIndex++] = (byte)byteValue;
94  
95          if (_unitBufferIndex == 3) {
96              encodeUnit(_unitBuffer[0], _unitBuffer[1], _unitBuffer[2]);
97  
98              _unitBufferIndex = 0;
99          }
100     }
101 
102     protected void encodeUnit(byte byteValue) throws IOException {
103         int intValue = byteValue & 0xff;
104 
105         intValue <<= 4;
106 
107         _outputBuffer[3] = (byte)CharPool.EQUAL;
108         _outputBuffer[2] = (byte)CharPool.EQUAL;
109         _outputBuffer[1] = (byte)getChar(intValue & 0x3f);
110 
111         intValue >>= 6;
112 
113         _outputBuffer[0] = (byte)getChar(intValue & 0x3f);
114 
115         _outputStream.write(_outputBuffer);
116     }
117 
118     protected void encodeUnit(byte byte1, byte byte2) throws IOException {
119         int intValue = byte1 & 0xff;
120 
121         intValue <<= 8;
122         intValue |= byte2 & 0xff;
123         intValue <<= 2;
124 
125         _outputBuffer[3] = (byte)CharPool.EQUAL;
126         _outputBuffer[2] = (byte)getChar(intValue & 0x3f);
127 
128         intValue >>= 6;
129 
130         _outputBuffer[1] = (byte)getChar(intValue & 0x3f);
131 
132         intValue >>= 6;
133 
134         _outputBuffer[0] = (byte)getChar(intValue & 0x3f);
135 
136         _outputStream.write(_outputBuffer);
137     }
138 
139     protected void encodeUnit(byte byte1, byte byte2, byte byte3)
140         throws IOException {
141 
142         int intVallue = byte1 & 0xff;
143 
144         intVallue <<= 8;
145         intVallue |= byte2 & 0xff;
146         intVallue <<= 8;
147         intVallue |= byte3 & 0xff;
148 
149         _outputBuffer[3] = (byte)getChar(intVallue & 0x3f);
150 
151         intVallue >>= 6;
152 
153         _outputBuffer[2] = (byte)getChar(intVallue & 0x3f);
154 
155         intVallue >>= 6;
156 
157         _outputBuffer[1] = (byte)getChar(intVallue & 0x3f);
158 
159         intVallue >>= 6;
160 
161         _outputBuffer[0] = (byte)getChar(intVallue & 0x3f);
162 
163         _outputStream.write(_outputBuffer);
164     }
165 
166     protected char getChar(int sixbit) {
167         if (sixbit >= 0 && sixbit <= 25) {
168             return (char)(65 + sixbit);
169         }
170 
171         if (sixbit >= 26 && sixbit <= 51) {
172             return (char)(97 + (sixbit - 26));
173         }
174 
175         if (sixbit >= 52 && sixbit <= 61) {
176             return (char)(48 + (sixbit - 52));
177         }
178 
179         if (sixbit == 62) {
180             return CharPool.PLUS;
181         }
182 
183         if (sixbit != 63) {
184             return CharPool.QUESTION;
185         }
186         else {
187             return CharPool.SLASH;
188         }
189     }
190 
191     private byte[] _outputBuffer;
192     private OutputStream _outputStream;
193     private byte[] _unitBuffer;
194     private int _unitBufferIndex;
195 
196 }