1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package com.beetstra.jutf7;
25
26 import java.io.UnsupportedEncodingException;
27 import java.nio.ByteBuffer;
28 import java.nio.CharBuffer;
29 import java.nio.charset.CharacterCodingException;
30 import java.nio.charset.Charset;
31 import java.nio.charset.CharsetDecoder;
32 import java.nio.charset.CharsetEncoder;
33 import java.nio.charset.CoderResult;
34 import junit.framework.TestCase;
35
36 public class AcceptanceTest extends TestCase {
37 private CharsetProvider provider;
38 private Charset charset;
39 private CharsetDecoder decoder;
40 private CharsetEncoder encoder;
41
42 protected void setUp() throws Exception {
43 provider = new CharsetProvider();
44 }
45
46 public void testUTF7() throws Exception {
47 init("UTF-7");
48 assertEquals("A+ImIDkQ.", encodeGetBytes("A\u2262\u0391."));
49 assertEquals("A+ImIDkQ.", encodeCharsetEncode("A\u2262\u0391."));
50 assertEquals("+ACEAIgAj-", encodeGetBytes("!\"#"));
51 verifyAll();
52 }
53
54 public void testUTF7o() throws Exception {
55 init("X-UTF-7-OPTIONAL");
56 assertEquals("A+ImIDkQ.", encodeGetBytes("A\u2262\u0391."));
57 assertEquals("A+ImIDkQ.", encodeCharsetEncode("A\u2262\u0391."));
58 assertEquals("!\"#", encodeGetBytes("!\"#"));
59 verifyAll();
60 }
61
62 public void testModifiedUTF7() throws Exception {
63 init("x-IMAP4-MODIFIED-UTF7");
64 assertEquals("A&ImIDkQ-.", encodeGetBytes("A\u2262\u0391."));
65 assertEquals("A&ImIDkQ-.", encodeCharsetEncode("A\u2262\u0391."));
66 verifyAll();
67 }
68
69 private void init(final String init) {
70 charset = provider.charsetForName(init);
71 decoder = charset.newDecoder();
72 encoder = charset.newEncoder();
73 }
74
75 private void verifyAll() throws Exception {
76 verifySymmetrical("áéíóúäëïöüàèìòùâêîôûãõçñ€");
77 verifySymmetrical("aábécídóeúfägëhïiöjükàlèmìnòoùpâqêrîsôtûuãvõwçxñy€z");
78 verifySymmetrical("abcáéídefóúäghiëïöjklüàèmnoìòùpqrâêîstuôûãvwxõçñyz€");
79 verifySymmetrical("abcdefghijklmnopqrstuvwyxzáéíóúäëïöüàèìòùâêîôûãõçñ€abcdefghijklmnopqrstuvwyxz");
80 verifySymmetrical("aáb+écí+-dóe-úfä-+gëh+ïiö+-jük-àlè-+mìn+òoù+-pâq-êrî-+sôt+ûuã+-võwç-xñy-+€z+");
81 verifySymmetrical("á+éí+óúä+ëïö++ü++àè++ìòù+++â+++êî+++ôûã+++õçñ€");
82 verifySymmetrical("á+-éí+-óúä+-ëïö++-ü++-àè++-ìòù+++-â+++-êî+++-ôûã+++-õçñ€");
83 verifySymmetrical("++++++++");
84 verifySymmetrical("+-++--+++---++");
85 verifySymmetrical("+áéí+");
86 verifySymmetrical("`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?\u0000\r\n\t\b\f€");
87 verifySymmetrical("#aáa#á#áá#ááá#");
88 }
89
90 protected void verifySymmetrical(String s) throws Exception {
91 final String encoded = encodeGetBytes(s);
92 assertEquals(encoded, encodeCharsetEncode(s));
93 assertEquals("problem decoding " + encoded, s, decode(encoded));
94 for (int i = 4; i < encoded.length(); i++) {
95 ByteBuffer in = CharsetTestUtil.wrap(encoded);
96 decoder.reset();
97 verifyChunkedOutDecode(i, in, s);
98 }
99 for (int i = 10; i < encoded.length(); i++) {
100 CharBuffer in = CharBuffer.wrap(s);
101 encoder.reset();
102 verifyChunkedOutEncode(i, in, encoded);
103 }
104 for (int i = 10; i < encoded.length(); i++) {
105 decoder.reset();
106 verifyChunkedInDecode(i, encoded, s);
107 }
108 for (int i = 4; i < encoded.length(); i++) {
109 encoder.reset();
110 verifyChunkedInEncode(i, s, encoded);
111 }
112 }
113
114 private String encodeCharsetEncode(String string) throws UnsupportedEncodingException {
115 String charsetEncode = CharsetTestUtil.asString(charset.encode(string));
116 return charsetEncode;
117 }
118
119
120
121
122
123 private String encodeGetBytes(String string) throws CharacterCodingException,
124 UnsupportedEncodingException {
125 ByteBuffer bb = ByteBuffer.allocate((int) (encoder.maxBytesPerChar() * string.length()));
126 CharBuffer cb = CharBuffer.wrap(string);
127 encoder.reset();
128 CoderResult cr = encoder.encode(cb, bb, true);
129 if (!cr.isUnderflow())
130 cr.throwException();
131 cr = encoder.flush(bb);
132 if (!cr.isUnderflow())
133 cr.throwException();
134 bb.flip();
135 String stringGetBytes = CharsetTestUtil.asString(bb);
136 return stringGetBytes;
137 }
138
139 protected String decode(String string) throws UnsupportedEncodingException {
140 final ByteBuffer buffer = CharsetTestUtil.wrap(string);
141 final CharBuffer decoded = charset.decode(buffer);
142 return decoded.toString();
143 }
144
145 protected void verifyChunkedInDecode(int i, String encoded, String decoded)
146 throws UnsupportedEncodingException {
147 ByteBuffer in = ByteBuffer.allocate(i);
148 CharBuffer out = CharBuffer.allocate(decoded.length() + 5);
149 int pos = 0;
150 CoderResult result = CoderResult.UNDERFLOW;
151 while (pos < encoded.length()) {
152 int end = Math.min(encoded.length(), pos + i);
153 in.put(CharsetTestUtil.wrap(encoded.substring(pos + in.position(), end)));
154 in.flip();
155 result = decoder.decode(in, out, false);
156 assertEquals("at position: " + pos, CoderResult.UNDERFLOW, result);
157 assertTrue("no progress after " + pos + " of " + encoded.length(), in.position() > 0);
158 pos += in.position();
159 in.compact();
160 }
161 in.limit(0);
162 result = decoder.decode(in, out, true);
163 assertEquals(CoderResult.UNDERFLOW, result);
164 result = decoder.flush(out);
165 assertEquals(CoderResult.UNDERFLOW, result);
166 assertEquals(encoded.length(), pos);
167 assertEquals(decoded.length(), out.position());
168 out.flip();
169 assertEquals("for length: " + i, decoded, out.toString());
170 }
171
172 protected void verifyChunkedInEncode(int i, String decoded, String encoded)
173 throws UnsupportedEncodingException {
174 CharBuffer in = CharBuffer.allocate(i);
175 ByteBuffer out = ByteBuffer.allocate(encoded.length() + 40);
176 int pos = 0;
177 CoderResult result = CoderResult.UNDERFLOW;
178 while (pos < decoded.length()) {
179 int end = Math.min(decoded.length(), pos + i);
180 in.put(decoded.substring(pos + in.position(), end));
181 in.flip();
182 assertTrue("unexpected end at " + pos, in.limit() > 0);
183 result = encoder.encode(in, out, false);
184 if (result.isUnderflow())
185 assertTrue("no progress after " + pos + " of " + decoded.length() + " in "
186 + decoded, in.position() > 0);
187 pos += in.position();
188 in.compact();
189 }
190 pos += in.position();
191 in.limit(0);
192 result = encoder.encode(in, out, true);
193 result = encoder.flush(out);
194 assertEquals(CoderResult.UNDERFLOW, result);
195 out.flip();
196 assertEquals("for length: " + i, encoded, CharsetTestUtil.asString(out));
197 }
198
199 protected void verifyChunkedOutEncode(int i, CharBuffer in, String encoded)
200 throws UnsupportedEncodingException {
201 ByteBuffer out = ByteBuffer.allocate(i);
202 int encodeCount = 0;
203 StringBuffer sb = new StringBuffer();
204 CoderResult result;
205 while (in.hasRemaining()) {
206 result = encoder.encode(in, out, false);
207 encodeCount += out.position();
208 if (in.hasRemaining()) {
209 assertEquals("at position: " + encodeCount, CoderResult.OVERFLOW, result);
210 assertTrue("at position: " + encodeCount, out.position() > 0);
211 }
212 CharsetTestUtil.outToSB(out, sb);
213 }
214 result = encoder.encode(in, out, true);
215 assertFalse(!result.isOverflow() && in.hasRemaining());
216 CharsetTestUtil.outToSB(out, sb);
217 result = encoder.flush(out);
218 CharsetTestUtil.outToSB(out, sb);
219 assertEquals(encoded, sb.toString());
220 in.rewind();
221 }
222
223 protected void verifyChunkedOutDecode(int i, ByteBuffer in, String decoded) {
224 CharBuffer out = CharBuffer.allocate(i);
225 int decodeCount = 0;
226 StringBuffer sb = new StringBuffer();
227 CoderResult result = CoderResult.OVERFLOW;
228 while (decodeCount < decoded.length()) {
229 assertEquals("at position: " + decodeCount, CoderResult.OVERFLOW, result);
230 result = decoder.decode(in, out, true);
231 assertTrue(out.position() > 0);
232 decodeCount += out.position();
233 out.flip();
234 sb.append(out.toString());
235 out.clear();
236 }
237 assertEquals(decoded, sb.toString());
238 in.rewind();
239 }
240 }