1 /* 2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 6227608 26 * @summary Test proper handling of flush() 27 * @author Martin Buchholz 28 */ 29 30 import java.util.*; 31 import java.io.*; 32 import java.nio.*; 33 import java.nio.charset.*; 34 35 public class Flush { 36 private static byte[] contents(ByteBuffer bb) { 37 byte[] contents = new byte[bb.position()]; 38 ((ByteBuffer)(bb.duplicate().flip())).get(contents); 39 return contents; 40 } 41 42 private static ByteBuffer extend(ByteBuffer bb) { 43 ByteBuffer x = ByteBuffer.allocate(2*bb.capacity()+10); 44 bb.flip(); 45 x.put(bb); 46 return x; 47 } 48 49 private static void realMain(String[] args) throws Throwable { 50 // A japanese character should decode as a 3-byte 51 // switch-to-japanese escape sequence, followed by a 2-byte 52 // encoding of the char itself, followed by a 3-byte return to 53 // ASCII escape sequence. 54 char[] jis0208 = {'\u3001'}; 55 CharBuffer cb = CharBuffer.wrap(jis0208); 56 ByteBuffer bb = ByteBuffer.allocate(6); 57 CharsetEncoder enc = Charset.forName("ISO-2022-JP").newEncoder(); 58 59 check(enc.encode(cb, bb, true).isUnderflow()); 60 61 System.out.println(Arrays.toString(contents(bb))); 62 check(! cb.hasRemaining()); 63 equal(contents(bb).length, 3 + 2); 64 equal(bb.get(0), (byte)0x1b); 65 66 //---------------------------------------------------------------- 67 // We must be able to recover if flush() returns OVERFLOW 68 //---------------------------------------------------------------- 69 check(enc.flush(bb).isOverflow()); 70 check(enc.flush(bb).isOverflow()); 71 equal(contents(bb).length, 3 + 2); 72 73 bb = extend(bb); 74 75 check(enc.flush(bb).isUnderflow()); 76 equal(bb.get(3 + 2), (byte)0x1b); 77 System.out.println(Arrays.toString(contents(bb))); 78 equal(contents(bb).length, 3 + 2 + 3); 79 80 //---------------------------------------------------------------- 81 // A final redundant flush() is a no-op 82 //---------------------------------------------------------------- 83 check(enc.flush(bb).isUnderflow()); 84 check(enc.flush(bb).isUnderflow()); 85 equal(contents(bb).length, 3 + 2 + 3); 86 87 //---------------------------------------------------------------- 88 // CharsetEncoder.encode(ByteBuffer) must call flush(ByteBuffer) 89 //---------------------------------------------------------------- 90 bb = enc.encode(CharBuffer.wrap(jis0208)); 91 byte[] expected = "\u001b$B!\"\u001b(B".getBytes("ASCII"); 92 byte[] contents = new byte[bb.limit()]; bb.get(contents); 93 check(Arrays.equals(contents, expected)); 94 } 95 96 //--------------------- Infrastructure --------------------------- 97 static volatile int passed = 0, failed = 0; 98 static void pass() { passed++; } 99 static void fail() { failed++; Thread.dumpStack(); } 100 static void fail(String msg) { System.out.println(msg); fail(); } 101 static void unexpected(Throwable t) { failed++; t.printStackTrace(); } 102 static void check(boolean cond) { if (cond) pass(); else fail(); } 103 static void equal(Object x, Object y) { 104 if (x == null ? y == null : x.equals(y)) pass(); 105 else {System.out.println(x + " not equal to " + y); fail(); }} 106 107 public static void main(String[] args) throws Throwable { 108 try { realMain(args); } catch (Throwable t) { unexpected(t); } 109 110 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 111 if (failed > 0) throw new Exception("Some tests failed"); 112 } 113 }