com.twelvemonkeys.io.WriterOutputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.fop Show documentation
Show all versions of org.apache.fop Show documentation
The core maven build properties
The newest version!
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.io;
import com.twelvemonkeys.lang.DateUtil;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
/**
* Wraps a {@code Writer} in an {@code OutputStream}.
*
* Instances of this class are not thread-safe.
*
*
* NOTE: This class is probably not the right way of solving your problem,
* however it might prove useful in JSPs etc.
* If possible, it's always better to use the {@code Writer}'s underlying
* {@code OutputStream}, or wrap it's native backing.
*
*
*
* @author Harald Kuhr
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/WriterOutputStream.java#2 $
*/
public class WriterOutputStream extends OutputStream {
protected Writer writer;
final protected Decoder decoder;
final ByteArrayOutputStream bufferStream = new FastByteArrayOutputStream(1024);
private volatile boolean isFlushing = false; // Ugly but critical...
private static final boolean NIO_AVAILABLE = isNIOAvailable();
private static boolean isNIOAvailable() {
try {
Class.forName("java.nio.charset.Charset");
return true;
}
catch (Throwable t) {
// Ignore
}
return false;
}
public WriterOutputStream(final Writer pWriter, final String pCharset) {
writer = pWriter;
decoder = getDecoder(pCharset);
}
public WriterOutputStream(final Writer pWriter) {
this(pWriter, null);
}
private static Decoder getDecoder(final String pCharset) {
// NOTE: The CharsetDecoder is typically 10-20% faster than
// StringDecoder according to my tests
// StringEncoder is horribly slow on 1.2 systems, but there's no
// alternative...
if (NIO_AVAILABLE) {
return new CharsetDecoder(pCharset);
}
return new StringDecoder(pCharset);
}
@Override
public void close() throws IOException {
flush();
writer.close();
writer = null;
}
@Override
public void flush() throws IOException {
flushBuffer();
writer.flush();
}
@Override
public final void write(byte[] pBytes) throws IOException {
if (pBytes == null) {
throw new NullPointerException("bytes == null");
}
write(pBytes, 0, pBytes.length);
}
@Override
public final void write(byte[] pBytes, int pOffset, int pLength) throws IOException {
flushBuffer();
decoder.decodeTo(writer, pBytes, pOffset, pLength);
}
@Override
public final void write(int pByte) {
// TODO: Is it possible to know if this is a good place in the stream to
// flush? It might be in the middle of a multi-byte encoded character..
bufferStream.write(pByte);
}
private void flushBuffer() throws IOException {
if (!isFlushing && bufferStream.size() > 0) {
isFlushing = true;
bufferStream.writeTo(this); // NOTE: Avoids cloning buffer array
bufferStream.reset();
isFlushing = false;
}
}
///////////////////////////////////////////////////////////////////////////
public static void main(String[] pArgs) throws IOException {
int iterations = 1000000;
byte[] bytes = "������ klashf lkash ljah lhaaklhghdfgu ksd".getBytes("UTF-8");
Decoder d;
long start;
long time;
Writer sink = new PrintWriter(new NullOutputStream());
StringWriter writer;
String str;
d = new StringDecoder("UTF-8");
for (int i = 0; i < 10000; i++) {
d.decodeTo(sink, bytes, 0, bytes.length);
}
start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
d.decodeTo(sink, bytes, 0, bytes.length);
}
time = DateUtil.delta(start);
System.out.println("StringDecoder");
System.out.println("time: " + time);
writer = new StringWriter();
d.decodeTo(writer, bytes, 0, bytes.length);
str = writer.toString();
System.out.println("str: \"" + str + "\"");
System.out.println("chars.length: " + str.length());
System.out.println();
if (NIO_AVAILABLE) {
d = new CharsetDecoder("UTF-8");
for (int i = 0; i < 10000; i++) {
d.decodeTo(sink, bytes, 0, bytes.length);
}
start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
d.decodeTo(sink, bytes, 0, bytes.length);
}
time = DateUtil.delta(start);
System.out.println("CharsetDecoder");
System.out.println("time: " + time);
writer = new StringWriter();
d.decodeTo(writer, bytes, 0, bytes.length);
str = writer.toString();
System.out.println("str: \"" + str + "\"");
System.out.println("chars.length: " + str.length());
System.out.println();
}
OutputStream os = new WriterOutputStream(new PrintWriter(System.out), "UTF-8");
os.write(bytes);
os.flush();
System.out.println();
for (byte b : bytes) {
os.write(b & 0xff);
}
os.flush();
}
///////////////////////////////////////////////////////////////////////////
private static interface Decoder {
void decodeTo(Writer pWriter, byte[] pBytes, int pOffset, int pLength) throws IOException;
}
private static final class CharsetDecoder implements Decoder {
final Charset mCharset;
CharsetDecoder(String pCharset) {
// Handle null-case, to get default charset
String charset = pCharset != null ? pCharset :
System.getProperty("file.encoding", "ISO-8859-1");
mCharset = Charset.forName(charset);
}
public void decodeTo(Writer pWriter, byte[] pBytes, int pOffset, int pLength) throws IOException {
CharBuffer cb = mCharset.decode(ByteBuffer.wrap(pBytes, pOffset, pLength));
pWriter.write(cb.array(), 0, cb.length());
}
}
private static final class StringDecoder implements Decoder {
final String mCharset;
StringDecoder(String pCharset) {
mCharset = pCharset;
}
public void decodeTo(Writer pWriter, byte[] pBytes, int pOffset, int pLength) throws IOException {
String str = mCharset == null ?
new String(pBytes, pOffset, pLength) :
new String(pBytes, pOffset, pLength, mCharset);
pWriter.write(str);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy