151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.cs; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.*; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.charset.*; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class StreamEncoder extends Writer 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile boolean isOpen = true; 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws IOException { 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen) 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Stream closed"); 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Factories for java.io.OutputStreamWriter 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static StreamEncoder forOutputStreamWriter(OutputStream out, 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object lock, 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String charsetName) 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws UnsupportedEncodingException 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String csn = charsetName; 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (csn == null) 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski csn = Charset.defaultCharset().name(); 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (Charset.isSupported(csn)) 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new StreamEncoder(out, lock, Charset.forName(csn)); 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IllegalCharsetNameException x) { } 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedEncodingException (csn); 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static StreamEncoder forOutputStreamWriter(OutputStream out, 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object lock, 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Charset cs) 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new StreamEncoder(out, lock, cs); 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static StreamEncoder forOutputStreamWriter(OutputStream out, 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object lock, 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CharsetEncoder enc) 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new StreamEncoder(out, lock, enc); 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Factory for java.nio.channels.Channels.newWriter 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static StreamEncoder forEncoder(WritableByteChannel ch, 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CharsetEncoder enc, 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int minBufferCap) 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new StreamEncoder(ch, enc, minBufferCap); 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Public methods corresponding to those in OutputStreamWriter -- 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // All synchronization and state/argument checking is done in these public 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // methods; the concrete stream-encoder subclasses defined below need not 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // do any such checking. 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getEncoding() { 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen()) 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return encodingName(); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void flushBuffer() throws IOException { 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen()) 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implFlushBuffer(); 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Stream closed"); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(int c) throws IOException { 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char cbuf[] = new char[1]; 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cbuf[0] = (char) c; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski write(cbuf, 0, 1); 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(char cbuf[], int off, int len) throws IOException { 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((off < 0) || (off > cbuf.length) || (len < 0) || 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((off + len) > cbuf.length) || ((off + len) < 0)) { 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (len == 0) { 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implWrite(cbuf, off, len); 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(String str, int off, int len) throws IOException { 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Check the len before creating a char buffer */ 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len < 0) 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char cbuf[] = new char[len]; 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski str.getChars(off, off + len, cbuf, 0); 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski write(cbuf, 0, len); 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void flush() throws IOException { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implFlush(); 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen) 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implClose(); 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isOpen = false; 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isOpen() { 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isOpen; 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Charset-based stream encoder impl -- 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Charset cs; 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CharsetEncoder encoder; 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ByteBuffer bb; 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Exactly one of these is non-null 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final OutputStream out; 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private WritableByteChannel ch; 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Leftover first char in a surrogate pair 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean haveLeftoverChar = false; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private char leftoverChar; 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CharBuffer lcb = null; 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private StreamEncoder(OutputStream out, Object lock, Charset cs) { 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(out, lock, 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cs.newEncoder() 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .onMalformedInput(CodingErrorAction.REPLACE) 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .onUnmappableCharacter(CodingErrorAction.REPLACE)); 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) { 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(lock); 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.out = out; 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.ch = null; 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.cs = enc.charset(); 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.encoder = enc; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This path disabled until direct buffers are faster 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (false && out instanceof FileOutputStream) { 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ch = ((FileOutputStream)out).getChannel(); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch != null) 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE); 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch == null) { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private StreamEncoder(WritableByteChannel ch, CharsetEncoder enc, int mbc) { 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.out = null; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.ch = ch; 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.cs = enc.charset(); 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.encoder = enc; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.bb = ByteBuffer.allocate(mbc < 0 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ? DEFAULT_BYTE_BUFFER_SIZE 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski : mbc); 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void writeBytes() throws IOException { 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lim = bb.limit(); 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos = bb.position(); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (pos <= lim); 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rem > 0) { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch != null) { 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch.write(bb) != rem) 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert false : rem; 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.write(bb.array(), bb.arrayOffset() + pos, rem); 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.clear(); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void flushLeftoverChar(CharBuffer cb, boolean endOfInput) 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!haveLeftoverChar && !endOfInput) 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lcb == null) 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lcb = CharBuffer.allocate(2); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lcb.clear(); 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (haveLeftoverChar) 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lcb.put(leftoverChar); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cb != null) && cb.hasRemaining()) 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lcb.put(cb.get()); 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lcb.flip(); 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (lcb.hasRemaining() || endOfInput) { 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CoderResult cr = encoder.encode(lcb, bb, endOfInput); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isUnderflow()) { 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lcb.hasRemaining()) { 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski leftoverChar = lcb.get(); 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cb != null && cb.hasRemaining()) 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flushLeftoverChar(cb, endOfInput); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isOverflow()) { 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert bb.position() > 0; 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writeBytes(); 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cr.throwException(); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski haveLeftoverChar = false; 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void implWrite(char cbuf[], int off, int len) 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CharBuffer cb = CharBuffer.wrap(cbuf, off, len); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (haveLeftoverChar) 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flushLeftoverChar(cb, false); 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (cb.hasRemaining()) { 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CoderResult cr = encoder.encode(cb, bb, false); 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isUnderflow()) { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (cb.remaining() <= 1) : cb.remaining(); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cb.remaining() == 1) { 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski haveLeftoverChar = true; 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski leftoverChar = cb.get(); 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isOverflow()) { 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert bb.position() > 0; 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writeBytes(); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cr.throwException(); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void implFlushBuffer() throws IOException { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bb.position() > 0) 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writeBytes(); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void implFlush() throws IOException { 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implFlushBuffer(); 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (out != null) 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.flush(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void implClose() throws IOException { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flushLeftoverChar(null, true); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CoderResult cr = encoder.flush(bb); 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isUnderflow()) 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cr.isOverflow()) { 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert bb.position() > 0; 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writeBytes(); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cr.throwException(); 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bb.position() > 0) 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writeBytes(); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ch != null) 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ch.close(); 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski out.close(); 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException x) { 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski encoder.reset(); 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String encodingName() { 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((cs instanceof HistoricallyNamedCharset) 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ? ((HistoricallyNamedCharset)cs).historicalName() 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski : cs.name()); 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 333