src.it.unimi.dsi.io.DebugOutputBitStream Maven / Gradle / Ivy
package it.unimi.dsi.io;
/*
* DSI utilities
*
* Copyright (C) 2006-2017 Paolo Boldi and Sebastiano Vigna
*
* 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 3 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 program; if not, see .
*
*/
import it.unimi.dsi.lang.MutableString;
import java.io.IOException;
import java.io.PrintStream;
/** A debugging wrapper for output bit streams.
*
* This class can be used to wrap an output bit stream. The semantics of the
* resulting write operations is unchanged, but each operation will be logged.
*
*
To simplify the output, some operations have a simplified representation. In particular:
*
*
* |
* - {@link OutputBitStream#flush() flush()};
*
->
* - {@link OutputBitStream#position(long) position()};
*
[
* - creation;
*
]
* - {@link OutputBitStream#close() close()};
*
{x}
* - explicit bits;
*
{x:b}
* - minimal binary coding of x with bound b;
*
{M:x}
* - write x with coding M; the latter can be U (unary), g (γ), z (ζ), d (δ), G (Golomb), GS (skewed Golomb);
* when appropriate, x is followed by an extra integer (modulus, etc.).
*
*
* @author Paolo Boldi
* @author Sebastiano Vigna
* @since 0.7.1
*/
public class DebugOutputBitStream extends OutputBitStream {
private final PrintStream pw;
private final OutputBitStream obs;
/** Creates a new debug output bit stream wrapping a given output bit stream and logging on a given writer.
*
* @param obs the output bit stream to wrap.
* @param pw a print stream that will receive the logging data.
*/
public DebugOutputBitStream(final OutputBitStream obs, final PrintStream pw) {
this.obs = obs;
this.pw = pw;
pw.print("[");
}
/** Creates a new debug output bit stream wrapping a given output bit stream and logging on standard error.
*
* @param obs the output bit stream to wrap.
*/
public DebugOutputBitStream(final OutputBitStream obs) {
this(obs, System.err);
}
@Override
public void flush() throws IOException {
pw.print(" |");
obs.flush();
}
@Override
public void close() throws IOException {
pw.print(" |]");
obs.close();
}
@Override
public long writtenBits() {
return obs.writtenBits();
}
@Override
public void writtenBits(final long writtenBits) {
obs.writtenBits(writtenBits);
}
@Override
public int align() throws IOException {
pw.print(" |");
return obs.align();
}
@Override
public void position(final long position) throws IOException {
pw.print(" ->" + position);
obs.position(position);
}
static MutableString byte2Binary(int x) {
MutableString s = new MutableString();
for(int i = 0 ; i < 8; i++) {
s.append((char)('0' + (x % 2)));
x >>= 1;
}
return s.reverse();
}
static MutableString int2Binary(long x, final int len) {
MutableString s = new MutableString();
for(int i = 0 ; i < 64; i++) {
s.append((char)('0' + (x % 2)));
x >>= 1;
}
return s.length(len).reverse();
}
@Override
public long write(final byte bits[], final long len) throws IOException {
if (len > Integer.MAX_VALUE) throw new IllegalArgumentException();
MutableString s = new MutableString(" {");
for(int i = 0; i < bits.length; i++) s.append(byte2Binary(bits[i]));
pw.print(s.length((int)len).append("}"));
return obs.write(bits, len);
}
@Override
public int writeBit(final boolean bit) throws IOException {
pw.print(" {" + (bit ? '1' : '0') + "}");
return obs.writeBit(bit);
}
@Override
public int writeBit(final int bit) throws IOException {
pw.print(" {" + bit + "}");
return obs.writeBit(bit);
}
@Override
public int writeInt(final int x, final int len) throws IOException {
pw.print(" {" + int2Binary(x, len) + "}");
return obs.writeInt(x, len);
}
@Override
public int writeLong(final long x, final int len) throws IOException {
pw.print(" {" + int2Binary(x, len) + "}");
return obs.writeLong(x, len);
}
@Override
public int writeUnary(final int x) throws IOException {
pw.print(" {U:" + x + "}");
return obs.writeUnary(x);
}
@Override
public long writeLongUnary(final long x) throws IOException {
pw.print(" {U:" + x + "}");
return obs.writeLongUnary(x);
}
@Override
public int writeGamma(final int x) throws IOException {
pw.print(" {g:" + x + "}");
return obs.writeGamma(x);
}
@Override
public int writeLongGamma(final long x) throws IOException {
pw.print(" {g:" + x + "}");
return obs.writeLongGamma(x);
}
@Override
public int writeDelta(final int x) throws IOException {
pw.print(" {d:" + x + "}");
return obs.writeDelta(x);
}
@Override
public int writeLongDelta(final long x) throws IOException {
pw.print(" {d:" + x + "}");
return obs.writeLongDelta(x);
}
@Override
public int writeMinimalBinary(final int x, final int b) throws IOException {
pw.print(" {m:" + x + "<" + b + "}");
return obs.writeMinimalBinary(x, b);
}
@Override
public int writeMinimalBinary(final int x, final int b, final int log2b) throws IOException {
pw.print(" {m:" + x + "<" + b + "}");
return obs.writeMinimalBinary(x, b, log2b);
}
@Override
public int writeLongMinimalBinary(final long x, final long b) throws IOException {
pw.print(" {m:" + x + "<" + b + "}");
return obs.writeLongMinimalBinary(x, b);
}
@Override
public int writeLongMinimalBinary(final long x, final long b, final int log2b) throws IOException {
pw.print(" {m:" + x + "<" + b + "}");
return obs.writeLongMinimalBinary(x, b, log2b);
}
@Override
public int writeGolomb(final int x, final int b) throws IOException {
pw.print(" {G:" + x + ":" + b + "}");
return obs.writeGolomb(x, b);
}
@Override
public int writeGolomb(final int x, final int b, final int log2b) throws IOException {
pw.print(" {G:" + x + ":" + b + "}");
return obs.writeGolomb(x, b, log2b);
}
@Override
public long writeLongGolomb(final long x, final long b) throws IOException {
pw.print(" {G:" + x + ":" + b + "}");
return obs.writeLongGolomb(x, b);
}
@Override
public long writeLongGolomb(final long x, final long b, final int log2b) throws IOException {
pw.print(" {G:" + x + ":" + b + "}");
return obs.writeLongGolomb(x, b, log2b);
}
@Override
public int writeSkewedGolomb(final int x, final int b) throws IOException {
pw.print(" {SG:" + x + ":" + b + "}");
return obs.writeSkewedGolomb(x, b);
}
@Override
public long writeLongSkewedGolomb(final long x, final long b) throws IOException {
pw.print(" {SG:" + x + ":" + b + "}");
return obs.writeLongSkewedGolomb(x, b);
}
@Override
public int writeZeta(final int x, final int k) throws IOException {
pw.print(" {z" + k + ":" + x + "}");
return obs.writeZeta(x, k);
}
@Override
public int writeLongZeta(final long x, final int k) throws IOException {
pw.print(" {z" + k + ":" + x + "}");
return obs.writeLongZeta(x, k);
}
@Override
public int writeNibble(final int x) throws IOException {
pw.print(" {N:" + x + "}");
return obs.writeNibble(x);
}
@Override
public int writeLongNibble(final long x) throws IOException {
pw.print(" {N:" + x + "}");
return obs.writeLongNibble(x);
}
}