42 |
|
|
43 |
private static final String US_ASCII = "US-ASCII"; |
private static final String US_ASCII = "US-ASCII"; |
44 |
|
|
45 |
private static final byte[] src = |
private static final byte[] src = { |
|
{ |
|
46 |
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, |
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, |
47 |
0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, |
0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, |
48 |
0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, |
0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, |
51 |
0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
52 |
0x38, 0x39, 0x2b, 0x2c |
0x38, 0x39, 0x2b, 0x2c |
53 |
}; |
}; |
54 |
|
|
55 |
private static final byte[] dst; |
private static final byte[] dst; |
56 |
static |
static |
57 |
{ |
{ |
58 |
dst = new byte[0x100]; |
dst = new byte[0x100]; |
59 |
for (int i = 0; i<0xff; i++) |
for (int i = 0; i < 0xff; i++) |
60 |
dst[i] = -1; |
dst[i] = -1; |
61 |
for (int i = 0; i<src.length; i++) |
for (int i = 0; i < src.length; i++) |
62 |
dst[src[i]] = (byte)i; |
dst[src[i]] = (byte) i; |
63 |
|
|
64 |
} |
} |
65 |
|
|
66 |
private UTF7imap() |
private UTF7imap() |
67 |
{ |
{ |
68 |
} |
} |
73 |
* |
* |
74 |
* @param bs the source byte array |
* @param bs the source byte array |
75 |
*/ |
*/ |
76 |
static byte[] encode(byte[] bs) |
static byte[] encode(byte[]bs) |
77 |
{ |
{ |
78 |
int si = 0, ti = 0; // source/target array indices |
int si = 0, ti = 0; // source/target array indices |
79 |
byte[] bt = new byte[((bs.length+2)/3)*4]; // target byte array |
byte[]bt = new byte[((bs.length + 2) / 3) * 4]; // target byte array |
80 |
for (; si<bs.length; si+=3) |
for (; si < bs.length; si += 3) |
81 |
{ |
{ |
82 |
int buflen = bs.length-si; |
int buflen = bs.length - si; |
83 |
if (buflen==1) |
if (buflen == 1) |
84 |
{ |
{ |
85 |
byte b = bs[si]; |
byte b = bs[si]; |
86 |
int i = 0; |
int i = 0; |
87 |
boolean flag = false; |
boolean flag = false; |
88 |
bt[ti++] = src[b>>>2 & 0x3f]; |
bt[ti++] = src[b >>> 2 & 0x3f]; |
89 |
bt[ti++] = src[(b<<4 & 0x30) + (i>>>4 & 0xf)]; |
bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)]; |
90 |
} |
} |
91 |
else if (buflen==2) |
else if (buflen == 2) |
92 |
{ |
{ |
93 |
byte b1 = bs[si], b2 = bs[si+1]; |
byte b1 = bs[si], b2 = bs[si + 1]; |
94 |
int i = 0; |
int i = 0; |
95 |
bt[ti++] = src[b1>>>2 & 0x3f]; |
bt[ti++] = src[b1 >>> 2 & 0x3f]; |
96 |
bt[ti++] = src[(b1<<4 & 0x30) + (b2>>>4 & 0xf)]; |
bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)]; |
97 |
bt[ti++] = src[(b2<<2 & 0x3c) + (i>>>6 & 0x3)]; |
bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)]; |
98 |
} |
} |
99 |
else if (buflen==3) |
else if (buflen == 3) |
100 |
{ |
{ |
101 |
byte b1 = bs[si], b2 = bs[si+1], b3 = bs[si+2]; |
byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2]; |
102 |
bt[ti++] = src[b1>>>2 & 0x3f]; |
bt[ti++] = src[b1 >>> 2 & 0x3f]; |
103 |
bt[ti++] = src[(b1<<4 & 0x30) + (b2>>>4 & 0xf)]; |
bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)]; |
104 |
bt[ti++] = src[(b2<<2 & 0x3c) + (b3>>>6 & 0x3)]; |
bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)]; |
105 |
bt[ti++] = src[b3 & 0x3f]; |
bt[ti++] = src[b3 & 0x3f]; |
106 |
} |
} |
107 |
} |
} |
114 |
* |
* |
115 |
* @param bs the source byte array |
* @param bs the source byte array |
116 |
*/ |
*/ |
117 |
static int[] decode(byte[] bs) |
static int[] decode(byte[]bs) |
118 |
{ |
{ |
119 |
int[] buffer = new int[bs.length]; |
int[] buffer = new int[bs.length]; |
120 |
int buflen = 0; |
int buflen = 0; |
121 |
int si = 0; |
int si = 0; |
122 |
int len = bs.length-si; |
int len = bs.length - si; |
123 |
while (len>0) |
while (len > 0) |
124 |
{ |
{ |
125 |
byte b0 = dst[bs[si++] & 0xff]; |
byte b0 = dst[bs[si++] & 0xff]; |
126 |
byte b2 = dst[bs[si++] & 0xff]; |
byte b2 = dst[bs[si++] & 0xff]; |
127 |
buffer[buflen++] = (b0<<2 & 0xfc | b2>>>4 & 0x3); |
buffer[buflen++] = (b0 << 2 & 0xfc | b2 >>> 4 & 0x3); |
128 |
if (len>2) |
if (len > 2) |
129 |
{ |
{ |
130 |
b0 = b2; |
b0 = b2; |
131 |
b2 = dst[bs[si++] & 0xff]; |
b2 = dst[bs[si++] & 0xff]; |
132 |
buffer[buflen++] = (b0<<4 & 0xf0 | b2>>>2 & 0xf); |
buffer[buflen++] = (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf); |
133 |
if (len>3) |
if (len > 3) |
134 |
{ |
{ |
135 |
b0 = b2; |
b0 = b2; |
136 |
b2 = dst[bs[si++] & 0xff]; |
b2 = dst[bs[si++] & 0xff]; |
137 |
buffer[buflen++] = (b0<<6 & 0xc0 | b2 & 0x3f); |
buffer[buflen++] = (b0 << 6 & 0xc0 | b2 & 0x3f); |
138 |
} |
} |
139 |
} |
} |
140 |
len = bs.length-si; |
len = bs.length - si; |
141 |
} |
} |
142 |
int[] bt = new int[buflen]; |
int[] bt = new int[buflen]; |
143 |
System.arraycopy(buffer, 0, bt, 0, buflen); |
System.arraycopy(buffer, 0, bt, 0, buflen); |
156 |
ByteArrayOutputStream encoderSink = null; |
ByteArrayOutputStream encoderSink = null; |
157 |
char[] chars = name.toCharArray(); |
char[] chars = name.toCharArray(); |
158 |
boolean encoding = false; |
boolean encoding = false; |
159 |
for (int i=0; i<chars.length; i++) |
for (int i = 0; i < chars.length; i++) |
160 |
{ |
{ |
161 |
char c = chars[i]; |
char c = chars[i]; |
162 |
if (c=='&') |
if (c == '&') |
163 |
{ |
{ |
164 |
if (buffer==null) |
if (buffer == null) |
165 |
{ |
{ |
166 |
buffer = new StringBuffer(); |
buffer = new StringBuffer(); |
167 |
for (int j=0; j<i; j++) |
for (int j = 0; j < i; j++) |
168 |
buffer.append(chars[j]); |
buffer.append(chars[j]); |
169 |
} |
} |
170 |
buffer.append('&'); |
buffer.append('&'); |
171 |
buffer.append('-'); |
buffer.append('-'); |
172 |
} |
} |
173 |
if (c<0x1f || c>0x7f) |
if (c < 0x1f || c > 0x7f) |
174 |
{ |
{ |
175 |
// needs encoding |
// needs encoding |
176 |
if (buffer==null) |
if (buffer == null) |
177 |
{ |
{ |
178 |
buffer = new StringBuffer(); |
buffer = new StringBuffer(); |
179 |
for (int j=0; j<i; j++) |
for (int j = 0; j < i; j++) |
180 |
buffer.append(chars[j]); |
buffer.append(chars[j]); |
181 |
encoderSink = new ByteArrayOutputStream(); |
encoderSink = new ByteArrayOutputStream(); |
182 |
} |
} |
186 |
buffer.append('&'); |
buffer.append('&'); |
187 |
encoding = true; |
encoding = true; |
188 |
} |
} |
189 |
encoderSink.write(((int)c)/0x100); |
encoderSink.write(((int) c) / 0x100); |
190 |
encoderSink.write(((int)c)%0x100); |
encoderSink.write(((int) c) % 0x100); |
191 |
} |
} |
192 |
else if (encoding) |
else if (encoding) |
193 |
{ |
{ |
194 |
encoderSink.flush(); |
encoderSink.flush(); |
195 |
byte[] encoded = encode(encoderSink.toByteArray()); |
byte[]encoded = encode(encoderSink.toByteArray()); |
196 |
buffer.append(new String(encoded, US_ASCII)); |
buffer.append(new String(encoded, US_ASCII)); |
197 |
buffer.append('-'); |
buffer.append('-'); |
198 |
encoding = false; |
encoding = false; |
199 |
if (c!='-') |
if (c != '-') |
200 |
buffer.append(c); |
buffer.append(c); |
201 |
} |
} |
202 |
else if (buffer!=null) |
else if (buffer != null) |
203 |
buffer.append(c); |
buffer.append(c); |
204 |
} |
} |
205 |
if (encoding) |
if (encoding) |
206 |
{ |
{ |
207 |
encoderSink.flush(); |
encoderSink.flush(); |
208 |
byte[] encoded = encode(encoderSink.toByteArray()); |
byte[]encoded = encode(encoderSink.toByteArray()); |
209 |
buffer.append(new String(encoded, US_ASCII)); |
buffer.append(new String(encoded, US_ASCII)); |
210 |
buffer.append('-'); |
buffer.append('-'); |
211 |
} |
} |
212 |
if (buffer!=null) |
if (buffer != null) |
213 |
return buffer.toString(); |
return buffer.toString(); |
214 |
} |
} |
215 |
catch (IOException e) |
catch(IOException e) |
216 |
{ |
{ |
217 |
// This should never happen |
// This should never happen |
218 |
throw new RuntimeException(e.getMessage()); |
throw new RuntimeException(e.getMessage()); |
230 |
ByteArrayOutputStream decoderSink = null; |
ByteArrayOutputStream decoderSink = null; |
231 |
char[] chars = name.toCharArray(); |
char[] chars = name.toCharArray(); |
232 |
boolean encoded = false; |
boolean encoded = false; |
233 |
for (int i=0; i<chars.length; i++) |
for (int i = 0; i < chars.length; i++) |
234 |
{ |
{ |
235 |
char c = chars[i]; |
char c = chars[i]; |
236 |
if (c=='&') |
if (c == '&') |
237 |
{ |
{ |
238 |
if (buffer==null) |
if (buffer == null) |
239 |
{ |
{ |
240 |
buffer = new StringBuffer(); |
buffer = new StringBuffer(); |
241 |
decoderSink = new ByteArrayOutputStream(); |
decoderSink = new ByteArrayOutputStream(); |
242 |
for (int j=0; j<i; j++) |
for (int j = 0; j < i; j++) |
243 |
buffer.append(chars[j]); |
buffer.append(chars[j]); |
244 |
} |
} |
245 |
decoderSink.reset(); |
decoderSink.reset(); |
246 |
encoded = true; |
encoded = true; |
247 |
} |
} |
248 |
else if (c=='-' && encoded) |
else if (c == '-' && encoded) |
249 |
{ |
{ |
250 |
if (decoderSink.size()==0) |
if (decoderSink.size() == 0) |
251 |
buffer.append('&'); |
buffer.append('&'); |
252 |
else |
else |
253 |
{ |
{ |
254 |
int[] decoded = decode(decoderSink.toByteArray()); |
int[] decoded = decode(decoderSink.toByteArray()); |
255 |
for (int j=0; j<decoded.length-1; j+=2) |
for (int j = 0; j < decoded.length - 1; j += 2) |
256 |
{ |
{ |
257 |
int hibyte = decoded[j]; |
int hibyte = decoded[j]; |
258 |
int lobyte = decoded[j+1]; |
int lobyte = decoded[j + 1]; |
259 |
int d = (hibyte*0x100) | lobyte; |
int d = (hibyte * 0x100) | lobyte; |
260 |
buffer.append((char)d); |
buffer.append((char) d); |
261 |
} |
} |
262 |
} |
} |
263 |
encoded = false; |
encoded = false; |
264 |
} |
} |
265 |
else if (encoded) |
else if (encoded) |
266 |
decoderSink.write((byte)c); |
decoderSink.write((byte) c); |
267 |
else if (buffer!=null) |
else if (buffer != null) |
268 |
buffer.append(c); |
buffer.append(c); |
269 |
} |
} |
270 |
if (buffer!=null) |
if (buffer != null) |
271 |
return buffer.toString(); |
return buffer.toString(); |
272 |
return name; |
return name; |
273 |
} |
} |
274 |
|
|
275 |
public static void main(String[] args) |
public static void main(String[]args) |
276 |
{ |
{ |
277 |
boolean decode = false; |
boolean decode = false; |
278 |
for (int i=0; i<args.length; i++) |
for (int i = 0; i < args.length; i++) |
279 |
{ |
{ |
280 |
if (args[i].equals("-d")) |
if (args[i].equals("-d")) |
281 |
decode = true; |
decode = true; |
282 |
else |
else |
283 |
{ |
{ |
284 |
if (decode) |
if (decode) |
285 |
System.out.println(args[i]+" = "+decode(args[i])); |
System.out.println(args[i] + " = " + decode(args[i])); |
286 |
else |
else |
287 |
System.out.println(args[i]+" = "+encode(args[i])); |
System.out.println(args[i] + " = " + encode(args[i])); |
288 |
} |
} |
289 |
} |
} |
290 |
} |
} |