13bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes/* 23bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * Copyright (C) 2010 The Android Open Source Project 33bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * 43bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 53bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * you may not use this file except in compliance with the License. 63bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * You may obtain a copy of the License at 73bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * 83bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 93bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * 103bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * Unless required by applicable law or agreed to in writing, software 113bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 123bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * See the License for the specific language governing permissions and 143bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes * limitations under the License. 153bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes */ 163bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 173bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughespackage libcore.java.io; 183bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 193bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughesimport java.io.*; 203bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughesimport java.util.Arrays; 213bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughesimport junit.framework.TestCase; 223bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 233bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughespublic class OutputStreamWriterTest extends TestCase { 243bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes private class FlushCountingOutputStream extends OutputStream { 253bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes int flushCount; 263bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes public void write(int b) { 273bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 283bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes @Override public void flush() throws IOException { 293bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes ++flushCount; 303bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 313bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 323bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 333bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes public void testFlushCount() throws Exception { 343bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes FlushCountingOutputStream os = new FlushCountingOutputStream(); 353bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8"); 363bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes char[] chars = new char[16*1024]; 373bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes Arrays.fill(chars, 'x'); 383bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes for (int i = 0; i < 10; ++i) { 393bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.write(chars); 403bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 413bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals(0, os.flushCount); 423bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.flush(); 433bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals(1, os.flushCount); 443bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.close(); 453bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals(1, os.flushCount); 463bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 473bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 483bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes private void testFlush(boolean includeSecondHalf) throws Exception { 493bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // OutputStreamWriter has an internal 8KiB buffer. 503bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // We write enough characters to fill that, but leave data in the encoder. 513bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // (Specifically, half a surrogate pair.) 523bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // On flush/close, the writer needs to admit defeat and write the replacement character. 533bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes ByteArrayOutputStream baos = new ByteArrayOutputStream(); 543bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes OutputStreamWriter writer = new OutputStreamWriter(baos, "UTF-32BE"); 553bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes char[] cs = new char[8192/4 + 1]; 563bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes Arrays.fill(cs, 'x'); 573bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes cs[cs.length - 1] = '\ud842'; // One half of a surrogate pair (the other being U+df9f). 583bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.write(cs, 0, cs.length); 593bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.flush(); 60555453327f26f4c9c610caa2851c87c3794c7764Elliott Hughes assertEquals(8192, baos.size()); // Just the 'x's so far. 613bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes if (includeSecondHalf) { 623bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.write(0xdf9f); 633bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 643bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes writer.close(); 653bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // We should have 8192 32-bit big-endian 'x's... 663bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes byte[] bytes = baos.toByteArray(); 673bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals(8196, bytes.length); 683bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes int i = 0; 693bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes while (i < 8192) { 703bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0, bytes[i++]); 713bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0, bytes[i++]); 723bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0, bytes[i++]); 733bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 'x', bytes[i++]); 743bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 753bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes if (includeSecondHalf) { 763bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // ...followed by a 32-bit big-endian U+20b9f. 773bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0x00, bytes[i++]); 783bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0x02, bytes[i++]); 793bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0x0b, bytes[i++]); 803bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0x9f, bytes[i++]); 813bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } else { 823bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes // ...followed by a 32-bit big-endian replacement character (U+fffd). 833bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0, bytes[i++]); 843bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0, bytes[i++]); 853bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0xff, bytes[i++]); 863bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes assertEquals((byte) 0xfd, bytes[i++]); 873bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 883bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 893bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 903bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes public void testFlush_halfSurrogate() throws Exception { 913bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes testFlush(false); 923bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 933bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes 943bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes public void testFlush_wholeSurrogate() throws Exception { 953bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes testFlush(true); 963bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes } 973bdd9bb460941429ab11dfa13596768f3dc246adElliott Hughes} 98