1
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
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 }