1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * 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 17 package libcore.java.io; 18 19 import java.io.*; 20 import java.util.Arrays; 21 import junit.framework.TestCase; 22 23 public class OutputStreamWriterTest extends TestCase { 24 private class FlushCountingOutputStream extends OutputStream { 25 int flushCount; 26 public void write(int b) { 27 } 28 @Override public void flush() throws IOException { 29 ++flushCount; 30 } 31 } 32 33 public void testFlushCount() throws Exception { 34 FlushCountingOutputStream os = new FlushCountingOutputStream(); 35 OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8"); 36 char[] chars = new char[16*1024]; 37 Arrays.fill(chars, 'x'); 38 for (int i = 0; i < 10; ++i) { 39 writer.write(chars); 40 } 41 assertEquals(0, os.flushCount); 42 writer.flush(); 43 assertEquals(1, os.flushCount); 44 writer.close(); 45 assertEquals(1, os.flushCount); 46 } 47 48 private void testFlush(boolean includeSecondHalf) throws Exception { 49 // OutputStreamWriter has an internal 8KiB buffer. 50 // We write enough characters to fill that, but leave data in the encoder. 51 // (Specifically, half a surrogate pair.) 52 // On flush/close, the writer needs to admit defeat and write the replacement character. 53 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 54 OutputStreamWriter writer = new OutputStreamWriter(baos, "UTF-32BE"); 55 char[] cs = new char[8192/4 + 1]; 56 Arrays.fill(cs, 'x'); 57 cs[cs.length - 1] = '\ud842'; // One half of a surrogate pair (the other being U+df9f). 58 writer.write(cs, 0, cs.length); 59 writer.flush(); 60 assertEquals(8192, baos.size()); // Just the 'x's so far. 61 if (includeSecondHalf) { 62 writer.write(0xdf9f); 63 } 64 writer.close(); 65 // We should have 8192 32-bit big-endian 'x's... 66 byte[] bytes = baos.toByteArray(); 67 assertEquals(8196, bytes.length); 68 int i = 0; 69 while (i < 8192) { 70 assertEquals((byte) 0, bytes[i++]); 71 assertEquals((byte) 0, bytes[i++]); 72 assertEquals((byte) 0, bytes[i++]); 73 assertEquals((byte) 'x', bytes[i++]); 74 } 75 if (includeSecondHalf) { 76 // ...followed by a 32-bit big-endian U+20b9f. 77 assertEquals((byte) 0x00, bytes[i++]); 78 assertEquals((byte) 0x02, bytes[i++]); 79 assertEquals((byte) 0x0b, bytes[i++]); 80 assertEquals((byte) 0x9f, bytes[i++]); 81 } else { 82 // ...followed by a 32-bit big-endian replacement character (U+fffd). 83 assertEquals((byte) 0, bytes[i++]); 84 assertEquals((byte) 0, bytes[i++]); 85 assertEquals((byte) 0xff, bytes[i++]); 86 assertEquals((byte) 0xfd, bytes[i++]); 87 } 88 } 89 90 public void testFlush_halfSurrogate() throws Exception { 91 testFlush(false); 92 } 93 94 public void testFlush_wholeSurrogate() throws Exception { 95 testFlush(true); 96 } 97 } 98