1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.apache.harmony.tests.java.nio.charset;
18
19import junit.framework.TestCase;
20import java.nio.ByteBuffer;
21import java.nio.CharBuffer;
22import java.nio.charset.CharacterCodingException;
23import java.nio.charset.Charset;
24import java.nio.charset.CharsetEncoder;
25import java.nio.charset.CoderResult;
26import java.nio.charset.CodingErrorAction;
27import java.nio.charset.MalformedInputException;
28import java.nio.charset.UnmappableCharacterException;
29
30public class ASCIICharsetEncoderTest extends TestCase {
31
32    // charset for ascii
33    private final Charset cs = Charset.forName("ascii");
34    private final CharsetEncoder encoder = cs.newEncoder();
35    private static final int MAXCODEPOINT = 0x7F;
36
37    /*
38      * @see CharsetEncoderTest#setUp()
39      */
40    protected void setUp() throws Exception {
41    }
42
43    /*
44      * @see CharsetEncoderTest#tearDown()
45      */
46    protected void tearDown() throws Exception {
47    }
48
49    public void testCanEncodeCharSequence() {
50        // normal case for ascCS
51        assertTrue(encoder.canEncode("\u0077"));
52        assertFalse(encoder.canEncode("\uc2a3"));
53        assertFalse(encoder.canEncode("\ud800\udc00"));
54        try {
55            encoder.canEncode(null);
56        } catch (NullPointerException e) {
57        }
58        assertTrue(encoder.canEncode(""));
59    }
60
61    public void testCanEncodeSurrogate() {
62        assertFalse(encoder.canEncode('\ud800'));
63        assertFalse(encoder.canEncode("\udc00"));
64    }
65
66    public void testCanEncodechar() throws CharacterCodingException {
67        assertTrue(encoder.canEncode('\u0077'));
68        assertFalse(encoder.canEncode('\uc2a3'));
69    }
70
71    public void testSpecificDefaultValue() {
72        assertEquals(1.0, encoder.averageBytesPerChar(), 0.0);
73        assertEquals(1.0, encoder.maxBytesPerChar(), 0.0);
74    }
75
76    public void testMultiStepEncode() throws CharacterCodingException {
77        encoder.onMalformedInput(CodingErrorAction.REPORT);
78        encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
79        try {
80            encoder.encode(CharBuffer.wrap("\ud800\udc00"));
81            fail("should unmappable");
82        } catch (UnmappableCharacterException e) {
83        }
84        encoder.reset();
85        ByteBuffer out = ByteBuffer.allocate(10);
86        assertEquals(CoderResult.UNDERFLOW,
87                encoder.encode(CharBuffer.wrap("\ud800"), out, true));
88        assertTrue(encoder.flush(out).isMalformed());
89        encoder.reset();
90
91        out = ByteBuffer.allocate(10);
92        CharBuffer buffer1 = CharBuffer.wrap("\ud800");
93        CharBuffer buffer2 = CharBuffer.wrap("\udc00");
94        assertSame(CoderResult.UNDERFLOW, encoder.encode(buffer1, out, false));
95        // We consume the entire input buffer because we're in an underflow
96        // state. We can't make a decision on whether the char in this buffer
97        // is unmappable or malformed without looking at the next input buffer.
98        assertEquals(1, buffer1.position());
99        assertTrue(encoder.encode(buffer2, out, true).isUnmappable());
100        assertEquals(0, buffer2.position());
101    }
102
103    public void testEncodeMapping() throws CharacterCodingException {
104        encoder.reset();
105
106        for (int i = 0; i <= MAXCODEPOINT; i++) {
107            char[] chars = Character.toChars(i);
108            CharBuffer cb = CharBuffer.wrap(chars);
109            ByteBuffer bb = encoder.encode(cb);
110            assertEquals(i, bb.get(0));
111        }
112
113        CharBuffer cb = CharBuffer.wrap("\u0080");
114        try {
115            encoder.encode(cb);
116        } catch (UnmappableCharacterException e) {
117            //expected
118        }
119
120        cb = CharBuffer.wrap("\ud800");
121        try {
122            encoder.encode(cb);
123        } catch (MalformedInputException e) {
124            //expected
125        }
126
127        ByteBuffer bb = ByteBuffer.allocate(0x10);
128        cb = CharBuffer.wrap("A");
129        encoder.reset();
130        encoder.encode(cb, bb, false);
131        try {
132            encoder.encode(cb);
133        } catch (IllegalStateException e) {
134            //expected
135        }
136    }
137
138    public void testInternalState() {
139        CharBuffer in = CharBuffer.wrap("A");
140        ByteBuffer out = ByteBuffer.allocate(0x10);
141
142        //normal encoding process
143        encoder.reset();
144        encoder.encode(in, out, false);
145        in = CharBuffer.wrap("B");
146        encoder.encode(in, out, true);
147        encoder.flush(out);
148    }
149
150    //reset could be called at any time
151    public void testInternalState_Reset() {
152        CharsetEncoder newEncoder = cs.newEncoder();
153        //Init - > reset
154        newEncoder.reset();
155
156        //reset - > reset
157        newEncoder.reset();
158
159        //encoding - >reset
160        {
161            CharBuffer in = CharBuffer.wrap("A");
162            ByteBuffer out = ByteBuffer.allocate(0x10);
163            newEncoder.encode(in, out, false);
164            newEncoder.reset();
165        }
166
167        //encoding end -> reset
168        {
169            CharBuffer in = CharBuffer.wrap("A");
170            ByteBuffer out = ByteBuffer.allocate(0x10);
171            newEncoder.encode(in, out, true);
172            newEncoder.reset();
173        }
174        //flused -> reset
175        {
176            CharBuffer in = CharBuffer.wrap("A");
177            ByteBuffer out = ByteBuffer.allocate(0x10);
178            newEncoder.encode(in, out, true);
179            newEncoder.flush(out);
180            newEncoder.reset();
181        }
182    }
183
184    public void testInternalState_Encoding() {
185        CharsetEncoder newEncoder = cs.newEncoder();
186        //Init - > encoding
187        {
188            CharBuffer in = CharBuffer.wrap("A");
189            ByteBuffer out = ByteBuffer.allocate(0x10);
190            newEncoder.encode(in, out, false);
191        }
192
193        //reset - > encoding
194        {
195            CharBuffer in = CharBuffer.wrap("A");
196            ByteBuffer out = ByteBuffer.allocate(0x10);
197            newEncoder.reset();
198            newEncoder.encode(in, out, false);
199        }
200        //reset - > encoding - > encoding
201        {
202            newEncoder.reset();
203            CharBuffer in = CharBuffer.wrap("A");
204            ByteBuffer out = ByteBuffer.allocate(0x10);
205            newEncoder.encode(in, out, false);
206            in = CharBuffer.wrap("BC");
207            newEncoder.encode(in, out, false);
208        }
209
210        //encoding_end - > encoding
211        {
212            newEncoder.reset();
213            CharBuffer in = CharBuffer.wrap("A");
214            ByteBuffer out = ByteBuffer.allocate(0x10);
215            newEncoder.encode(in, out, true);
216            in = CharBuffer.wrap("BC");
217            try {
218                newEncoder.encode(in, out, false);
219                fail("Should throw IllegalStateException");
220            } catch (IllegalStateException e) {
221                //expected
222            }
223        }
224        //flushed - > encoding
225        {
226            newEncoder.reset();
227            CharBuffer in = CharBuffer.wrap("A");
228            ByteBuffer out = ByteBuffer.allocate(0x10);
229            newEncoder.encode(in, out, true);
230            newEncoder.flush(out);
231            in = CharBuffer.wrap("BC");
232            try {
233                newEncoder.encode(in, out, false);
234                fail("Should throw IllegalStateException");
235            } catch (IllegalStateException e) {
236                //expected
237            }
238        }
239    }
240
241    public void testInternalState_Encoding_END() {
242        CharsetEncoder newEncoder = cs.newEncoder();
243
244        //Init - >encoding_end
245        {
246            CharBuffer in = CharBuffer.wrap("A");
247            ByteBuffer out = ByteBuffer.allocate(0x10);
248            newEncoder.encode(in, out, true);
249        }
250
251        //Reset -> encoding_end
252        {
253            CharBuffer in = CharBuffer.wrap("A");
254            ByteBuffer out = ByteBuffer.allocate(0x10);
255            newEncoder.reset();
256            newEncoder.encode(in, out, true);
257        }
258
259        //encoding -> encoding_end
260        {
261            newEncoder.reset();
262            CharBuffer in = CharBuffer.wrap("A");
263            ByteBuffer out = ByteBuffer.allocate(0x10);
264            newEncoder.encode(in, out, false);
265            in = CharBuffer.wrap("BC");
266            newEncoder.encode(in, out, true);
267        }
268
269        //Reset -> encoding_end
270        {
271            newEncoder.reset();
272            CharBuffer in = CharBuffer.wrap("A");
273            ByteBuffer out = ByteBuffer.allocate(0x10);
274            newEncoder.encode(in, out, true);
275            in = CharBuffer.wrap("BC");
276            newEncoder.encode(in, out, true);
277        }
278
279        //Flushed -> encoding_end
280        {
281            newEncoder.reset();
282            CharBuffer in = CharBuffer.wrap("A");
283            ByteBuffer out = ByteBuffer.allocate(0x10);
284            newEncoder.encode(in, out, true);
285            newEncoder.flush(out);
286            in = CharBuffer.wrap("BC");
287            try {
288                newEncoder.encode(in, out, true);
289                fail("Should throw IllegalStateException");
290            } catch (IllegalStateException e) {
291                //expected
292            }
293        }
294    }
295
296    public void testInternalState_Flushed() {
297        CharsetEncoder newEncoder = cs.newEncoder();
298
299        // init -> flushed
300        {
301            ByteBuffer out = ByteBuffer.allocate(0x10);
302            try {
303                newEncoder.flush(out);
304                fail("Should throw IllegalStateException");
305            } catch (IllegalStateException e) {
306                //expected
307            }
308
309        }
310
311        // reset - > flushed
312        {
313            newEncoder.reset();
314            CharBuffer in = CharBuffer.wrap("A");
315            ByteBuffer out = ByteBuffer.allocate(0x10);
316            newEncoder.encode(in, out, true);
317            newEncoder.reset();
318            try {
319                newEncoder.flush(out);
320                fail("Should throw IllegalStateException");
321            } catch (IllegalStateException e) {
322                //expected
323            }
324        }
325
326        //encoding - > flushed
327        {
328            newEncoder.reset();
329            CharBuffer in = CharBuffer.wrap("A");
330            ByteBuffer out = ByteBuffer.allocate(0x10);
331            newEncoder.encode(in, out, false);
332            try {
333
334                newEncoder.flush(out);
335                fail("Should throw IllegalStateException");
336            } catch (IllegalStateException e) {
337                // expected
338            }
339        }
340
341        //encoding_end -> flushed
342        {
343            newEncoder.reset();
344            CharBuffer in = CharBuffer.wrap("A");
345            ByteBuffer out = ByteBuffer.allocate(0x10);
346            newEncoder.encode(in, out, true);
347            newEncoder.flush(out);
348        }
349
350        //flushd - > flushed
351        {
352            newEncoder.reset();
353            CharBuffer in = CharBuffer.wrap("A");
354            ByteBuffer out = ByteBuffer.allocate(0x10);
355            newEncoder.encode(in, out, true);
356            newEncoder.flush(out);
357            newEncoder.flush(out);
358        }
359    }
360
361    public void testInternalState_Encode() throws CharacterCodingException {
362        CharsetEncoder newEncoder = cs.newEncoder();
363        //Init - > encode
364        {
365            CharBuffer in = CharBuffer.wrap("A");
366            newEncoder.encode(in);
367        }
368
369        //Reset - > encode
370        {
371            newEncoder.reset();
372            CharBuffer in = CharBuffer.wrap("A");
373            newEncoder.encode(in);
374        }
375
376        //Encoding -> encode
377        {
378            newEncoder.reset();
379            CharBuffer in = CharBuffer.wrap("A");
380            ByteBuffer out = ByteBuffer.allocate(0x10);
381            newEncoder.encode(in, out, false);
382            in = CharBuffer.wrap("BC");
383            newEncoder.encode(in);
384        }
385
386        //Encoding_end -> encode
387        {
388            newEncoder.reset();
389            CharBuffer in = CharBuffer.wrap("A");
390            ByteBuffer out = ByteBuffer.allocate(0x10);
391            newEncoder.encode(in, out, true);
392            in = CharBuffer.wrap("BC");
393            newEncoder.encode(in);
394        }
395
396        //Flushed -> reset
397        {
398            newEncoder.reset();
399            CharBuffer in = CharBuffer.wrap("A");
400            ByteBuffer out = ByteBuffer.allocate(0x10);
401            newEncoder.encode(in, out, true);
402            in = CharBuffer.wrap("BC");
403            newEncoder.flush(out);
404            out = newEncoder.encode(in);
405        }
406    }
407
408    public void testInternalState_from_Encode() throws CharacterCodingException {
409        CharsetEncoder newEncoder = cs.newEncoder();
410
411        //Encode -> Reset
412        {
413            CharBuffer in = CharBuffer.wrap("A");
414            newEncoder.encode(in);
415            newEncoder.reset();
416        }
417
418        // Encode -> encoding
419        {
420            CharBuffer in = CharBuffer.wrap("A");
421            newEncoder.encode(in);
422            ByteBuffer out = ByteBuffer.allocate(0x10);
423            try {
424                newEncoder.encode(in, out, false);
425                fail("Should throw IllegalStateException");
426            } catch (IllegalStateException e) {
427                // expected
428            }
429        }
430
431        //Encode -> Encoding_end
432        {
433            CharBuffer in = CharBuffer.wrap("A");
434            ByteBuffer out = ByteBuffer.allocate(0x10);
435            newEncoder.reset();
436            newEncoder.encode(in, out, false);
437            newEncoder.encode(in, out, true);
438        }
439
440        //Encode -> Flushed
441        {
442            CharBuffer in = CharBuffer.wrap("A");
443            ByteBuffer out = newEncoder.encode(in);
444            newEncoder.flush(out);
445        }
446
447        //Encode - > encode
448        {
449            CharBuffer in = CharBuffer.wrap("A");
450            newEncoder.encode(in);
451            in = CharBuffer.wrap("BC");
452            newEncoder.encode(in);
453        }
454    }
455}
456