/*
Copyright (C) 2003 EBI, GRL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.ensembl.mart.util;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
/**
* Extended PrintStream to allow users to print fasta
* formatted sequence output with an unformatted header, and sequence formatted to a
* user-specified column width maximum, using a user supplied line ending.
* Users should use the normal PrintStream methods to write header elements.
* Users should use the various *Sequence methods to print out sequences.
* Note, the default line ending is a newline, but this can be over ridden.
*
* @author <a href="mailto:dlondon@ebi.ac.uk">Darin London</a>
* @author <a href="mailto:craig@ebi.ac.uk">Craig Melsopp</a>
*/
public class FormattedSequencePrintStream extends PrintStream {
private Logger logger = Logger.getLogger(FormattedSequencePrintStream.class.getName());
private final int maxColumnLen; // default, eg. no limit
private int currentColumn = 0;
private static final String DEFAULTLINEEND = "\n"; // default, but can be overridden
private final String LINEEND;
/**
* Constructor for a basic FormattedSequencePrintStream, with maxColumn and an underlying OutputStream.
* The default line ending, a newline, is used to add line endings to sequences.
* Autoflush is set to false.
*
* @param maxColumnLen - integer, column length max. A maxColumnLen of 0 signals that no formatting should occur
* @param out - underlying OutputStream for the PrintStream
*/
public FormattedSequencePrintStream(int maxColumnLen, OutputStream out) {
this(maxColumnLen, DEFAULTLINEEND, out, false);
}
public FormattedSequencePrintStream(int maxColumnLen, String lineEnd, OutputStream out) {
this(maxColumnLen, lineEnd, out, false);
}
/**
* Constructor for a FormattedSequencePrintStream, stating whether the underlying PrintStream should be in autoFlush
* mode, or not. The default line ending, a newline, is used to add line endings to sequences.
*
* @param maxColumnLen - integer, column length max. A maxColumnLen of 0 signals that no formatting should occur
* @param out - underlying OutputStream for the PrintStream
* @param autoFlush - boolean, if true, underlying PrintStream is set to autoFlush true
* @see java.io.PrintStream
*/
public FormattedSequencePrintStream(int maxColumnLen, OutputStream out, boolean autoFlush) {
this(maxColumnLen, DEFAULTLINEEND, out, autoFlush);
}
/**
* Constructor for a FormattedSequencePrintStream, setting the autoFlush and the lineEnd string to
* print when adding a line end to formatted sequence output. Useful for output such as HTML, where
* the newline should be </p> instead of \n.
*
* @param maxColumnLen - integer, column length max. A maxColumnLen of 0 signals that no formatting should occur
* @param lineEnd - String to end sequence lines with when the formatter inserts a new line to the sequences (default is newline).
* @param out - underlying OutputStream for the PrintStream
* @param autoFlush - boolean, if true, underlying PrintStream is set to autoFlush true
* @see java.io.PrintStream
*/
public FormattedSequencePrintStream(int maxColumnLen, String lineEnd, OutputStream out, boolean autoFlush) {
super(out, autoFlush);
this.maxColumnLen = maxColumnLen;
this.LINEEND = lineEnd;
}
/**
* Constructor for a FormattedSequencePrintStream, with a specified encoding.
*
* @param maxColumnLen - integer, column length max. A maxColumnLen of 0 signals that no formatting should occur
* @param out - underlying OutputStream for the PrintStream
* @param autoFlush - boolean, if true, underlying PrintStream is set to autoFlush true
* @param encoding - encoding to use for character/string conversion
* @throws java.io.UnsupportedEncodingException
* @see java.io.PrintStream
*/
public FormattedSequencePrintStream(int maxColumnLen, OutputStream out, String encoding) throws UnsupportedEncodingException {
this(maxColumnLen, DEFAULTLINEEND, out, false, encoding);
}
/**
* Constructor for a FormattedSequencePrintStream, with a specified lineEnd, autoFlush, and encoding.
*
* @param maxColumnLen - integer, column length max. A maxColumnLen of 0 signals that no formatting should occur
* @param out - underlying OutputStream for the PrintStream
* @param autoFlush - boolean, if true, underlying PrintStream is set to autoFlush true
* @param encoding - encoding to use for character/string conversion
* @throws java.io.UnsupportedEncodingException
* @see java.io.PrintStream
*/
public FormattedSequencePrintStream(int maxColumnLen, String lineEnd, OutputStream out, boolean autoFlush, String encoding) throws UnsupportedEncodingException {
super(out, autoFlush, encoding);
this.maxColumnLen = maxColumnLen;
this.LINEEND = lineEnd;
}
/**
* Write out a char of sequence, with formatting.
*
* @param x - char of sequence to be written
*/
public void printSequence(char x) {
if (currentColumn == maxColumnLen)
printLineAndReset();
print(x);
currentColumn++;
}
/**
* Write out a char[] object of sequence, with formatting.
*
* @param x - char[] with sequence to be printed
*/
public void printSequence(char[] x) {
int len = x.length;
int newlen = Math.min(len, maxColumnLen - currentColumn);
for (int i = 0; i < len; i += newlen, currentColumn += newlen) {
if (currentColumn == maxColumnLen)
printLineAndReset();
newlen = Math.min(newlen, len - i);
print(x,i,newlen);
}
}
private void print(char[] x, int off, int len) {
char[] newx = new char[len];
System.arraycopy(x, off, newx, 0, len);
print(newx);
}
/**
* Write out a String of sequence. Resolves to writeSequence(sequence.getBytes()).
* @param x
*/
public void printSequence(String x) {
writeSequence(x.getBytes());
}
/**
* Write out a byte of sequence, with formatting.
*
* @param b - byte of sequence to be printed
*/
public void writeSequence(byte b) {
if (currentColumn == maxColumnLen)
printLineAndReset();
write(b);
currentColumn++;
}
/**
* write an entire byte[] object containing sequence, with formatting.
*
* @param buf - byte[] containing sequence to be printed
*/
public void writeSequence(byte[] buf) {
writeSequence(buf, 0, buf.length);
}
/**
* write a portion of a byte[] object containing sequence, with formatting.
*
* @param buf - byte[] containing sequence bytes to be printed
* @param off - beginning offset, eg. byte[off] will be the first byte printed
* @param len - number of bytes to print, eg. byte[off] - byte[off + len - 1] will be printed
*/
public void writeSequence(byte[] buf, int off, int len) {
// if (logger.isLoggable(Level.WARNING))
// logger.warning("Recieved buf from off " + off + " to len " + len + "\n\n");
for (int i = off, newlen = Math.min(len - i, maxColumnLen - currentColumn); i < len; i += newlen, newlen = Math.min(len - i, maxColumnLen - currentColumn)) {
// if (logger.isLoggable(Level.WARNING))
// logger.warning( "maxColumnLen = "+ maxColumnLen + " currentColumn = " + currentColumn + " i = " + i + " newlen = " + newlen + "\nlen - i = " + (len - i) + " maxColumnLen - currentColumn = " + (maxColumnLen - currentColumn) + "\n");
write(buf,i,newlen);
currentColumn += newlen;
if (currentColumn == maxColumnLen)
printLineAndReset();
}
}
/**
* sets the columnCount to 0, to signal that a new output of sequence has begun
*/
public void resetColumnCount() {
currentColumn = 0;
}
private void printLineAndReset() {
print(LINEEND);
currentColumn = 0;
}
}