001
014
015 package com.liferay.portal.kernel.io;
016
017 import com.liferay.portal.kernel.util.CharPool;
018
019 import java.io.IOException;
020 import java.io.OutputStream;
021
022
025 public class Base64OutputStream extends OutputStream {
026
027 public Base64OutputStream(OutputStream outputStream) {
028 _outputStream = outputStream;
029 _unitBuffer = new byte[3];
030 _unitBufferIndex = 0;
031 _outputBuffer = new byte[4];
032 }
033
034 public void close() throws IOException {
035 flush();
036
037 _outputStream.close();
038 }
039
040 public void flush() throws IOException {
041 if (_unitBufferIndex == 1) {
042 encodeUnit(_unitBuffer[0]);
043 }
044 else if (_unitBufferIndex == 2) {
045 encodeUnit(_unitBuffer[0], _unitBuffer[1]);
046 }
047
048 _unitBufferIndex = 0;
049
050 _outputStream.flush();
051 }
052
053 public void write(byte[] bytes) throws IOException {
054 write(bytes, 0, bytes.length);
055 }
056
057 public void write(byte[] bytes, int offset, int length) throws IOException {
058 if (length <= 0) {
059 return;
060 }
061
062 while ((_unitBufferIndex != 0) && (length > 0)) {
063 write(bytes[offset++]);
064
065 length--;
066 }
067
068 if (length <= 0) {
069 return;
070 }
071
072 int bytesLength = length - (length % 3);
073
074 length -= bytesLength;
075
076 while (bytesLength > 0) {
077 encodeUnit(bytes[offset], bytes[offset + 1], bytes[offset + 2]);
078
079 bytesLength -=3 ;
080 offset += 3;
081 }
082
083 while (length > 0) {
084 write(bytes[offset++]);
085
086 length--;
087 }
088 }
089
090 public void write(int byteValue) throws IOException {
091 _unitBuffer[_unitBufferIndex++] = (byte)byteValue;
092
093 if (_unitBufferIndex == 3) {
094 encodeUnit(_unitBuffer[0], _unitBuffer[1], _unitBuffer[2]);
095
096 _unitBufferIndex = 0;
097 }
098 }
099
100 protected void encodeUnit(byte byteValue) throws IOException {
101 int intValue = byteValue & 0xff;
102
103 intValue <<= 4;
104
105 _outputBuffer[3] = (byte)CharPool.EQUAL;
106 _outputBuffer[2] = (byte)CharPool.EQUAL;
107 _outputBuffer[1] = (byte)getChar(intValue & 0x3f);
108
109 intValue >>= 6;
110
111 _outputBuffer[0] = (byte)getChar(intValue & 0x3f);
112
113 _outputStream.write(_outputBuffer);
114 }
115
116 protected void encodeUnit(byte byte1, byte byte2) throws IOException {
117 int intValue = byte1 & 0xff;
118
119 intValue <<= 8;
120 intValue |= byte2 & 0xff;
121 intValue <<= 2;
122
123 _outputBuffer[3] = (byte)CharPool.EQUAL;
124 _outputBuffer[2] = (byte)getChar(intValue & 0x3f);
125
126 intValue >>= 6;
127
128 _outputBuffer[1] = (byte)getChar(intValue & 0x3f);
129
130 intValue >>= 6;
131
132 _outputBuffer[0] = (byte)getChar(intValue & 0x3f);
133
134 _outputStream.write(_outputBuffer);
135 }
136
137 protected void encodeUnit(byte byte1, byte byte2, byte byte3)
138 throws IOException {
139
140 int intVallue = byte1 & 0xff;
141
142 intVallue <<= 8;
143 intVallue |= byte2 & 0xff;
144 intVallue <<= 8;
145 intVallue |= byte3 & 0xff;
146
147 _outputBuffer[3] = (byte)getChar(intVallue & 0x3f);
148
149 intVallue >>= 6;
150
151 _outputBuffer[2] = (byte)getChar(intVallue & 0x3f);
152
153 intVallue >>= 6;
154
155 _outputBuffer[1] = (byte)getChar(intVallue & 0x3f);
156
157 intVallue >>= 6;
158
159 _outputBuffer[0] = (byte)getChar(intVallue & 0x3f);
160
161 _outputStream.write(_outputBuffer);
162 }
163
164 protected char getChar(int sixbit) {
165 if (sixbit >= 0 && sixbit <= 25) {
166 return (char)(65 + sixbit);
167 }
168
169 if (sixbit >= 26 && sixbit <= 51) {
170 return (char)(97 + (sixbit - 26));
171 }
172
173 if (sixbit >= 52 && sixbit <= 61) {
174 return (char)(48 + (sixbit - 52));
175 }
176
177 if (sixbit == 62) {
178 return CharPool.PLUS;
179 }
180
181 if (sixbit != 63) {
182 return CharPool.QUESTION;
183 }
184 else {
185 return CharPool.SLASH;
186 }
187 }
188
189 private byte[] _outputBuffer;
190 private OutputStream _outputStream;
191 private byte[] _unitBuffer;
192 private int _unitBufferIndex;
193
194 }