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 java.io.IOException;
20import java.nio.BufferOverflowException;
21import java.nio.ByteBuffer;
22import java.nio.CharBuffer;
23import java.nio.charset.Charset;
24import java.nio.charset.CharsetDecoder;
25import java.nio.charset.CharsetEncoder;
26import java.nio.charset.CoderMalfunctionError;
27import java.nio.charset.CoderResult;
28
29import junit.framework.TestCase;
30
31public class CharsetEncoder2Test extends TestCase {
32
33    /**
34     * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
35     *        java.nio.charset.Charset, float, float)
36     */
37    public void test_ConstructorLjava_nio_charset_CharsetFF() {
38        // Regression for HARMONY-141
39        try {
40            Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
41            new MockCharsetEncoderForHarmony141(cs, 1.1f, 1);
42            fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
43        } catch (IllegalArgumentException e) {
44            // expected
45        }
46
47        try {
48            Charset cs = Charset.forName("ISO8859-1"); //$NON-NLS-1$
49            new MockCharsetEncoderForHarmony141(cs, 1.1f, 1,
50                    new byte[] { 0x1a });
51            fail("Assert 1: Should throw IllegalArgumentException."); //$NON-NLS-1$
52        } catch (IllegalArgumentException e) {
53            // expected
54        }
55    }
56
57    /**
58     * @tests java.nio.charset.CharsetEncoder.CharsetEncoder(
59     *        java.nio.charset.Charset, float, float)
60     */
61    public void test_ConstructorLjava_nio_charset_CharsetNull() {
62        // Regression for HARMONY-491
63        CharsetEncoder ech = new MockCharsetEncoderForHarmony491(null, 1, 1);
64        assertNull(ech.charset());
65    }
66
67    /**
68     * Helper for constructor tests
69     */
70
71    public static class MockCharsetEncoderForHarmony141 extends CharsetEncoder {
72
73        protected MockCharsetEncoderForHarmony141(Charset cs,
74                float averageBytesPerChar, float maxBytesPerChar) {
75            super(cs, averageBytesPerChar, maxBytesPerChar);
76        }
77
78        public MockCharsetEncoderForHarmony141(Charset cs,
79                float averageBytesPerChar, float maxBytesPerChar,
80                byte[] replacement) {
81            super(cs, averageBytesPerChar, maxBytesPerChar, replacement);
82        }
83
84        protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
85            return null;
86        }
87    }
88
89    public static class MockCharsetEncoderForHarmony491 extends CharsetEncoder {
90
91        public MockCharsetEncoderForHarmony491(Charset arg0, float arg1,
92                float arg2) {
93            super(arg0, arg1, arg2);
94        }
95
96        protected CoderResult encodeLoop(CharBuffer arg0, ByteBuffer arg1) {
97            return null;
98        }
99
100        public boolean isLegalReplacement(byte[] arg0) {
101            return true;
102        }
103    }
104
105    /*
106     * Test malfunction encode(CharBuffer)
107     */
108    public void test_EncodeLjava_nio_CharBuffer() throws Exception {
109        MockMalfunctionCharset cs = new MockMalfunctionCharset("mock", null);
110        try {
111            cs.encode(CharBuffer.wrap("AB"));
112            fail("should throw CoderMalfunctionError");// NON-NLS-1$
113        } catch (CoderMalfunctionError e) {
114            // expected
115        }
116    }
117
118    /*
119     * Mock charset class with malfunction decode & encode.
120     */
121    static final class MockMalfunctionCharset extends Charset {
122
123        public MockMalfunctionCharset(String canonicalName, String[] aliases) {
124            super(canonicalName, aliases);
125        }
126
127        public boolean contains(Charset cs) {
128            return false;
129        }
130
131        public CharsetDecoder newDecoder() {
132            return Charset.forName("UTF-8").newDecoder();
133        }
134
135        public CharsetEncoder newEncoder() {
136            return new MockMalfunctionEncoder(this);
137        }
138    }
139
140    /*
141     * Mock encoder. encodeLoop always throws unexpected exception.
142     */
143    static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
144
145        public MockMalfunctionEncoder(Charset cs) {
146            super(cs, 1, 3, new byte[] { (byte) '?' });
147        }
148
149        protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
150            throw new BufferOverflowException();
151        }
152    }
153
154    /*
155     * Test reserve bytes encode(CharBuffer,ByteBuffer,boolean)
156     */
157    public void test_EncodeLjava_nio_CharBufferLjava_nio_ByteBufferB() throws Exception {
158        Charset utf8 = Charset.forName("utf-8");
159        CharsetEncoder encoder = utf8.newEncoder();
160        CharBuffer char1 = CharBuffer.wrap("\ud800");
161        CharBuffer char2 = CharBuffer.wrap("\udc00");
162        ByteBuffer bytes = ByteBuffer.allocate(4);
163        encoder.reset();
164
165        // If we supply just the high surrogate...
166        CoderResult result = encoder.encode(char1, bytes, false);
167        // ...we're not done...
168        assertTrue(result.isUnderflow());
169        assertEquals(4, bytes.remaining());
170        // ...but if we then supply the low surrogate...
171        result = encoder.encode(char2, bytes, true);
172        assertTrue(result.isUnderflow());
173        // ...we're done. Note that the RI loses its state in
174        // between the two characters, so it can't do this.
175        assertEquals(0, bytes.remaining());
176
177        // Did we get the UTF-8 for U+10000?
178        assertEquals(4, bytes.limit());
179        assertEquals((byte) 0xf0, bytes.get(0));
180        assertEquals((byte) 0x90, bytes.get(1));
181        assertEquals((byte) 0x80, bytes.get(2));
182        assertEquals((byte) 0x80, bytes.get(3));
183
184        // See what we got in the output buffer by decoding and checking that we
185        // get back the same surrogate pair.
186        bytes.flip();
187        CharBuffer chars = utf8.newDecoder().decode(bytes);
188        assertEquals(0, bytes.remaining());
189        assertEquals(2, chars.limit());
190        assertEquals(0xd800, chars.get(0));
191        assertEquals(0xdc00, chars.get(1));
192    }
193
194    /**
195     * @tests {@link java.nio.charset.Charset#encode(java.nio.CharBuffer)
196     */
197    public void testUtf8Encoding() throws IOException {
198        byte[] orig = new byte[] { (byte) 0xed, (byte) 0xa0,
199                (byte) 0x80 };
200        String s = new String(orig, "UTF-8");
201        assertEquals(1, s.length());
202        assertEquals(55296, s.charAt(0));
203        Charset.forName("UTF-8").encode(CharBuffer.wrap(s));
204//        ByteBuffer buf = <result>
205//        for (byte o : orig) {
206//            byte b = 0;
207//            buf.get(b);
208//            assertEquals(o, b);
209//        }
210    }
211
212}
213