/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.util;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.wc.IOExceptionWrapper;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
/**
* @author TMate Software Ltd.
* @version 1.3
*/
public class SVNCharsetOutputStream extends FilterOutputStream {
private static final byte[] EMPTY_ARRAY = new byte[0];
private SVNCharsetConvertor myCharsetConvertor;
private ByteBuffer myOutputBuffer;
private boolean myFlushed;
public SVNCharsetOutputStream(OutputStream out, Charset inputCharset, Charset outputCharset,
CodingErrorAction malformedInputAction, CodingErrorAction unmappableCharAction) {
super(out);
CharsetDecoder decoder = inputCharset.newDecoder();
decoder.onMalformedInput(malformedInputAction);
decoder.onUnmappableCharacter(unmappableCharAction);
CharsetEncoder encoder = outputCharset.newEncoder();
encoder.onMalformedInput(malformedInputAction);
encoder.onUnmappableCharacter(unmappableCharAction);
myCharsetConvertor = new SVNCharsetConvertor(decoder, encoder);
myFlushed = false;
}
public void write(int b) throws IOException {
write(new byte[]{(byte) (b & 0xFF)});
}
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) throws IOException {
try {
myOutputBuffer = myCharsetConvertor.convertChunk(b, off, len, myOutputBuffer, false);
myOutputBuffer.flip();
out.write(myOutputBuffer.array(), myOutputBuffer.arrayOffset(), myOutputBuffer.limit());
} catch (SVNException e) {
throw new IOExceptionWrapper(e);
}
}
public void flush() throws IOException {
if (!myFlushed) {
try {
myOutputBuffer = myCharsetConvertor.convertChunk(EMPTY_ARRAY, 0, 0, myOutputBuffer, true);
myOutputBuffer = myCharsetConvertor.flush(myOutputBuffer);
myOutputBuffer.flip();
out.write(myOutputBuffer.array(), myOutputBuffer.arrayOffset(), myOutputBuffer.limit());
} catch (SVNException e) {
throw new IOExceptionWrapper(e);
} finally {
myFlushed = true;
}
}
super.flush();
}
public void close() throws IOException {
flush();
out.close();
}
public String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append("SVNCharsetOutputStream");
buffer.append("[").append(myCharsetConvertor);
buffer.append(']');
return buffer.toString();
}
}