Home | History | Annotate | Download | only in io
      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