/*
* `gnu.iou'
* Copyright (C) 2006 John Pritchard.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package gnu.iou ;
/**
* Wrapper for {@link bbuf} exporting standard output API plus
* others.
*
* @author John Pritchard (john@syntelos.org)
*
* @see bbuf
* @see bbi
*/
public class bbo extends java.io.OutputStream {
/**
* Newline terminal is CRLF
*/
protected final static char[] CRLF = {
'\r',
'\n'
};
private final static byte[] CRLF_BYTE = {
(byte)'\r',
(byte)'\n'
};
/**
* <p> Scans output replacing lone LF with CRLF. This is slow and
* used only for receivers absolutely intolerant of any lone LFs
* (QMail).</p>
*
* @author jdp
*/
public static class crlf extends bbo {
private final static byte LF = (byte)'\n';
private final static byte CR = (byte)'\r';
boolean require = true;
public crlf( int capacity){
super(capacity);
}
public crlf(){
super();
}
public crlf ( bbuf buf){
super(buf);
}
public void write ( int b) throws java.io.IOException {
switch(b){
case CR:
this.require = false;
break;
case LF:
if (this.require)
super.write(CR);
this.require = true;
break;
default:
this.require = true;
break;
}
super.write(b);
}
public void write ( byte[] b) throws java.io.IOException {
this.write(b, 0, b.length);
}
public void write ( byte[] b, int ofs, int len) throws java.io.IOException {
byte ch;
for (int cc = ofs, mark = ofs; cc < len; cc++){
ch = b[cc];
switch (ch){
case CR:
this.require = false;
super.write(ch);
break;
case LF:
if (this.require)
super.write(CR);
super.write(ch);
this.require = true;
break;
default:
this.require = true;
super.write(ch);
break;
}
}
}
}
private bbuf buf ;
public bbo( int capacity){
super();
buf = new bbuf(capacity);
}
public bbo(){
super();
buf = new bbuf();
}
public bbo ( bbuf buf){
super();
if ( null == buf)
throw new IllegalArgumentException("Null argument to `new bbo(bbuf)'.");
else
this.buf = buf;
}
// OutputStream
public void write ( int b) throws java.io.IOException {
buf.write(b);
}
public void write ( byte[] b) throws java.io.IOException {
buf.write(b, 0, b.length);
}
public void write ( byte[] b, int ofs, int len) throws java.io.IOException {
buf.write(b, ofs, len);
}
public void flush() throws java.io.IOException {
}
public void close() throws java.io.IOException {
}
// bbuf
/**
* @return Offset of the last byte written, or negative one before
* the first byte has been written
*/
public int offset(){
return this.buf.offset_write();
}
public bbuf getByteBuffer(){ return buf;}
public int length(){ return buf.length();}
public void reset(){ buf.reset();}
public byte[] toByteArray(){ return buf.toByteArray();}
public String toString(){ return buf.toString();}
public void mark(){
this.buf.mark_write();
}
public byte[] marked(){
return this.buf.marked_write();
}
public boolean markSupported(){
return true;
}
/**
* Write to format UTF-8
* @param ch Output character to format encoding
*/
public void print(char ch)
throws java.io.IOException
{
if (ch < 0x80)
this.write(ch);
else {
char[] cary = new char[]{ch};
byte[] bary = utf8.encode(cary);
this.write(bary,0,bary.length);
}
}
/**
* @param ch Output character to format encoding
* @param many Repeat output this many times
*/
public void nprint(char ch, int many)
throws java.io.IOException
{
if (ch < 0x80)
this.buf.nwrite((byte)(ch & 0xff),many);
else {
char[] cary = new char[]{ch};
byte[] bary = utf8.encode(cary);
for (int cc = 0; cc < many; cc++)
this.write(bary,0,bary.length);
}
}
/**
* Write to format UTF-8
* @param string Output data to format encoding
*/
public void print(String string)
throws java.io.IOException
{
if (null != string){
char[] cary = string.toCharArray();
if (0 < cary.length){
byte[] bary = utf8.encode(cary);
this.write(bary,0,bary.length);
}
}
}
/**
* Write to format UTF-8
* @param indent Indentation level
* @param string Output data to format encoding
*/
public void print(int indent, String string)
throws java.io.IOException
{
this.nprint(' ',indent);
this.print(string);
}
/**
* Write to format UTF-8
* @param ch Output character to format encoding
*/
public void println(char ch)
throws java.io.IOException
{
char[] cary = gnu.iou.chbuf.cat(ch,CRLF);
byte[] bary = gnu.iou.utf8.encode(cary);
this.write(bary,0,bary.length);
}
/**
* Write to format UTF-8
* @param string Output data to format encoding with newline
*/
public void println(String string)
throws java.io.IOException
{
char[] cary = null;
if (null != string)
cary = string.toCharArray();
cary = gnu.iou.chbuf.cat(cary,CRLF);
byte[] bary = gnu.iou.utf8.encode(cary);
this.write(bary,0,bary.length);
}
/**
* Write to format UTF-8
* @param indent Indentation level
* @param string Output data to format encoding
*/
public void println(int indent, String string)
throws java.io.IOException
{
this.nprint(' ',indent);
this.println(string);
}
public void println()
throws java.io.IOException
{
this.write(CRLF_BYTE,0,2);
}
}