package org.basex.io.out;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.basex.core.Prop;
import org.basex.util.Token;
/**
* This class is a stream-wrapper for textual data. Note that the internal
* byte representation (usually UTF8) will be directly output without
* further character conversion.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public class PrintOutput extends OutputStream {
/** Output stream reference. */
private final OutputStream os;
/** Maximum numbers of bytes to write. */
long max = Long.MAX_VALUE;
/** Number of bytes written. */
long size;
/** Protected default constructor. */
PrintOutput() {
this((OutputStream) null);
}
/**
* Constructor, given a filename.
* @param fn filename
* @throws IOException I/O exception
*/
public PrintOutput(final String fn) throws IOException {
this(new BufferOutput(fn));
}
/**
* Constructor, given an output stream.
* @param out output stream reference
*/
private PrintOutput(final OutputStream out) {
os = out;
}
/**
* Returns a new instance for the given output stream.
* @param out output stream reference
* @return print output
*/
public static PrintOutput get(final OutputStream out) {
return out instanceof PrintOutput ? (PrintOutput) out :
new PrintOutput(
out instanceof ByteArrayOutputStream ||
out instanceof BufferedOutputStream ||
out instanceof BufferOutput ||
out instanceof ArrayOutput ? out : new BufferOutput(out));
}
@Override
public void write(final int b) throws IOException {
if(size++ < max) os.write(b);
}
/**
* Writes a character as UTF8.
* @param ch character to be printed
* @throws IOException I/O exception
*/
public void utf8(final int ch) throws IOException {
if(ch <= 0x7F) {
write(ch);
} else if(ch <= 0x7FF) {
write(ch >> 6 & 0x1F | 0xC0);
write(ch & 0x3F | 0x80);
} else if(ch <= 0xFFFF) {
write(ch >> 12 & 0x0F | 0xE0);
write(ch >> 6 & 0x3F | 0x80);
write(ch & 0x3F | 0x80);
} else {
write(ch >> 18 & 0x07 | 0xF0);
write(ch >> 12 & 0x3F | 0x80);
write(ch >> 6 & 0x3F | 0x80);
write(ch & 0x3F | 0x80);
}
}
/**
* Writes a string to the output stream, suffixed by a 0 byte.
* @param str string to be written
* @throws IOException I/O exception
*/
public final void writeString(final String str) throws IOException {
print(Token.token(str));
write(0);
}
/**
* Prints a string to the output stream.
* @param str string to be written
* @throws IOException I/O exception
*/
public final void print(final String str) throws IOException {
print(Token.token(str));
}
/**
* Prints a string and newline to the output stream.
* @param str string to be written
* @throws IOException I/O exception
*/
public final void println(final String str) throws IOException {
print(str);
print(Prop.NL);
}
/**
* Prints a token to the output stream.
* @param token token to be written
* @throws IOException I/O exception
*/
public final void print(final byte[] token) throws IOException {
for(final byte t : token) write(t);
}
/**
* Prints a token to the output stream.
* @param token token to be written
* @throws IOException I/O exception
*/
public final void println(final byte[] token) throws IOException {
print(token);
print(Prop.NL);
}
/**
* Returns the number of written bytes.
* @return number of written bytes
*/
public final long size() {
return size;
}
@Override
public final void flush() throws IOException {
if(os != null) os.flush();
}
@Override
public final void close() throws IOException {
if(os != null) {
if(os == System.out || os == System.err) os.flush();
else os.close();
}
}
/**
* Checks if stream can output more characters; can be overwritten to
* interrupt streaming at some point.
* @return result of check
*/
public boolean finished() {
return false;
}
}