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