/* * `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 ; import java.io.PrintStream; /** * Print stream over <tt>`linebuf'</tt>. This uses an intermediate * "line" buffer for <tt>"print"</tt> that can be flushed to the * output (final) buffer using <tt>"flush()"</tt>. This scheme * (without extra flushing) works in normal Print Stream usage for * <tt>"print"</tt> followed by <tt>"println"</tt>, but breaks when, * for example, <tt>"print"</tt> contains a newline. * * @author John Pritchard (john@syntelos.org) * * @see linebuf */ public class bpo extends PrintStream { private linebuf lb ; private chbuf line = new chbuf(); public bpo ( linebuf lb ){ super(new bbo()/*not-used*/); if ( null != lb) this.lb = lb; else this.lb = new linebuf(); } public bpo (){ this(new linebuf()); } public final String[] toStringArray(){ this.flush(); return lb.toStringArray(); } public final char[][] toCharCharArray(){ this.flush(); return lb.toCharCharArray(); } public final String toString(){ this.flush(); return lb.toString(); } public final char[] toCharArray(){ this.flush(); return lb.toCharArray(); } public final byte[] toByteArray(){ this.flush(); return utf8.encode(lb.toCharArray()); } /** * Delete the first line in the buffer (ignores state of line * buffer, which should have been flushed). */ public final void pop(){ lb.pop(); } /** * Reset (intermediate) line, and output buffers. */ public final void reset(){ line.reset(); lb.reset(); } /** * Number of lines */ public final int length(){ return lb.length(); } public final linebuf linebuf(){ return lb;} public final chbuf chbuf(){ return line;} /** * Produce a string from the stack trace print from the argument. * * @param t Throwable to print. */ public final static String toString ( Throwable t){ bpo buf = new bpo(); t.printStackTrace(buf); return buf.toString(); } public final static String atStack( Throwable t){ return atStack(t,0); } /** * @param t Exception to trace * @param pop Number of lines to pop from the stack trace. This * is for an artificial trace of a throwable constructed just to * know where the code is. Pop one (argument value 1) to skip the * exception itself, another (2) to drop the caller. A value less * than one preserves the entire trace. * @return Condensed stack trace for logging. */ public final static String atStack( Throwable t, int pop){ bpo ps = new bpo(); t.printStackTrace(ps); for (int cc = 0; cc < pop; cc++) ps.pop(); linebuf buf = ps.linebuf(); String strary[] = buf.toStringArray(), lin; chbuf cb = ps.chbuf(); //reuse cb.reset(); int len = strary.length; if ( 8 < len) len = 8; for (int idx, idx2, cc = 0; cc < len; cc++){ lin = strary[cc]; idx = lin.lastIndexOf('('); idx2 = lin.lastIndexOf(".java"); if (0 < idx && 0 < idx2) lin = chbuf.cat(lin.substring(0,idx+1),lin.substring(idx2+5)); idx = lin.lastIndexOf(' '); if (-1 < idx) lin = lin.substring(idx+1); cb.append('@'); cb.append(lin); } return cb.toString(); } /** * Produce a stack trace of the current position, deleting the * <tt>`Throwable.toString()'</tt> and <tt>`bbo.stackTrace()'</tt> * lines produced by <tt>`new Exception()'</tt>. */ public final static String stackTrace(){ Throwable stack = new Exception(); bpo buf = new bpo(); stack.printStackTrace(buf); buf.pop(); buf.pop(); return buf.toString(); } public final void write ( int b) { line.append( (char)b); } public final void write ( byte[] b) { this.write(b,0,b.length); } public final void write ( byte[] b, int ofs, int len) { char[] cary = utf8.decode(b,ofs,len); line.append(cary); } public final void flush() { String str = line.toString(); if ( null != str) lb.append(str); line.reset(); } public final void close() { this.flush(); } public final boolean checkError() { return false; } public final void print(boolean o) { line.append(o); } public final void print(char o) { line.append(o); } public final void print(int o) { line.append(o); } public final void print(long o) { line.append(o); } public final void print(float o) { line.append(o); } public final void print(double o) { line.append(o); } public final void print(char o[]) { line.append(o); } public final void print(String o) { line.append(o); } public final void print(Object o) { line.append(o); } public final void println() { lb.append(line.toString()); line.reset(); } public final void println(boolean o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(char o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(int o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(long o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(float o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(double o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(char[] o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(String o) { line.append(o); lb.append(line.toString()); line.reset(); } public final void println(Object o) { line.append(o); lb.append(line.toString()); line.reset(); } }