blob: 485f56a6bc482648618c73f4966d81d29816e164 [file] [log] [blame]
package org.eclipse.jdi.internal.spy;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.*;
import java.io.*;
public class VerboseWriter extends BufWriter {
/** Length of verbose description. */
public static final int VERBOSE_DESCRIPTION_LENGTH = 21;
/** Number of hexadecimal verbose bytes per line. */
public static final int VERBOSE_HEX_BYTES_PER_LINE = 16;
/** Width of hex dump. */
public static final int VERBOSE_HEX_WIDTH = 16*3+2;
/** Number extra verbose lines. These are caused by hex dumps that span more than one line. */
int fExtraVerboseLines = 0;
/**
* Creates new VerboseWriter.
*/
public VerboseWriter(PrintWriter out) {
super(out);
}
/**
* Terminate the current line by writing the line separator string.
* If autoflush is set and there are extra vebose lines caused by printHex, these lines are
* also printed.
*/
public void println() {
while (fExtraVerboseLines > 0) {
fExtraVerboseLines--;
super.println();
}
super.println();
}
/**
* Prints verbose line.
*/
public void println(String description, byte value) {
printDescription(description);
printHex(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, short value) {
printDescription(description);
printHex(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, int value) {
printDescription(description);
printHex(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, long value) {
printDescription(description);
printHex(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, byte value, Map valueToString) {
printDescription(description);
printHex(value);
printValue(value, valueToString);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, short value, Map valueToString) {
printDescription(description);
printHex(value);
printValue(value, valueToString);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, int value, Map valueToString) {
printDescription(description);
printHex(value);
printValue(value, valueToString);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, byte value, Vector bitNames) {
printDescription(description);
printHex(value);
printValue(value, bitNames);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, short value, Vector bitNames) {
printDescription(description);
printHex(value);
printValue(value, bitNames);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, int value, Vector bitNames) {
printDescription(description);
printHex(value);
printValue(value, bitNames);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, String value) {
printDescription(description);
printHex(value);
print(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, boolean value) {
printDescription(description);
printHex(value);
print(new Boolean(value).toString());
println();
}
/**
* Prints verbose line.
*/
public void println(String description, char value) {
printDescription(description);
printHex(value);
print(value);
println();
}
/**
* Prints verbose line.
*/
public void println(String description, double value) {
printDescription(description);
printHex(value);
print(new Double(value).toString());
println();
}
/**
* Prints verbose line.
*/
public void println(String description, float value) {
printDescription(description);
printHex(value);
print(new Float(value).toString());
println();
}
/**
* Prints verbose line.
*/
public void println(String description, byte[] value) {
printDescription(description);
printHex(value);
println();
}
/**
* Prints string with right size.
*/
public void printWidth(String str, int width) {
print(str);
int spaces = width - str.length();
if (spaces > 0) {
for (int i = 0; i < spaces; i++)
print(' ');
}
}
/**
* Prints description string with right size plus its seperator spaces.
*/
public void printDescription(String str) {
printWidth(str, VERBOSE_DESCRIPTION_LENGTH);
}
/**
* Prints hex substitution string with right size plus its seperator spaces.
*/
public void printHexSubstitution(String str) {
// Note that bytes also start with a space.
print(' ');
printWidth(str, VERBOSE_HEX_WIDTH - 1);
}
/**
* Appends hex representation of given byte to an array.
*/
private static void appendHexByte(byte b, char[] buffer, int pos) {
int count = 2;
int abspos = 3*pos;
buffer[abspos] = ' ';
do {
int t = b & 15;
if (t > 9)
t = t - 10 + (int) 'a';
else
t += (int) '0';
buffer[count-- + abspos] = (char) t;
b >>>= 4;
} while (count > 0);
}
/**
* Appends remaining spaces to hex dump.
*/
private static void appendHexSpaces(char[] buffer, int pos) {
for (int i = 3*pos; i <= VERBOSE_HEX_WIDTH - 3; i+=3) {
buffer[i] = ' ';
buffer[i+1] = ' ';
buffer[i+2] = ' ';
}
// Two extra spaces as seperator
buffer[VERBOSE_HEX_WIDTH - 1] = ' ';
buffer[VERBOSE_HEX_WIDTH - 2] = ' ';
}
/**
* Prints hex representation of a byte.
*/
public void printHex(byte b) {
char buffer[] = new char[VERBOSE_HEX_WIDTH];
appendHexByte((byte)b, buffer, 0);
appendHexSpaces(buffer, 1);
print(buffer);
}
/**
* Prints hex representation of an int.
*/
public void printHex(short s) {
char buffer[] = new char[VERBOSE_HEX_WIDTH];
for (int i = 1; i >= 0; i--)
appendHexByte((byte)(s >>> i*8), buffer, 1 - i);
appendHexSpaces(buffer, 2);
print(buffer);
}
/**
* Prints hex representation of an int.
*/
public void printHex(int integer) {
char buffer[] = new char[VERBOSE_HEX_WIDTH];
for (int i = 3; i >= 0; i--)
appendHexByte((byte)(integer >>> i*8), buffer, 3 - i);
appendHexSpaces(buffer, 4);
print(buffer);
}
/**
* Prints hex representation of a long.
*/
public void printHex(long l) {
char buffer[] = new char[VERBOSE_HEX_WIDTH];
for (int i = 7; i >= 0; i--)
appendHexByte((byte)(l >>> i*8), buffer, 7 - i);
appendHexSpaces(buffer, 8);
print(buffer);
}
/**
* Prints hex representation of a long.
*/
public void printHex(boolean b) {
printHexSubstitution("<boolean>");
}
/**
* Prints hex representation of a long.
*/
public void printHex(char c) {
printHexSubstitution("<char>");
}
/**
* Prints hex representation of a long.
*/
public void printHex(double d) {
printHexSubstitution("<double>");
}
/**
* Prints hex representation of a long.
*/
public void printHex(float f) {
printHexSubstitution("<float>");
}
/**
* Prints hex representation of a String.
*/
public void printHex(String str) {
printHexSubstitution("<string>");
}
/**
* Prints hex representation of a byte array.
* Note that this can span more than one line, but is considered to be part of one
* 'verbose line'. Therefore, a println after a printHex can result in more than one line
* being printed to the PrintWriter.
*/
public void printHex(byte[] bytes) {
int startPosition = position();
char linebuf[] = new char[VERBOSE_HEX_WIDTH];
int extraLines = 0;
int byteOnLine = 0;
for (int i = 0; i < bytes.length; i++) {
if (byteOnLine == VERBOSE_HEX_BYTES_PER_LINE) {
appendHexSpaces(linebuf, VERBOSE_HEX_BYTES_PER_LINE);
if (extraLines++ > 0)
printDescription("");
print(linebuf);
super.println();
byteOnLine = 0;
}
appendHexByte(bytes[i], linebuf, byteOnLine++);
}
appendHexSpaces(linebuf, byteOnLine);
if (extraLines > 0)
printDescription("");
fExtraVerboseLines += extraLines;
print(linebuf);
if (extraLines > 0)
gotoPosition(startPosition);
}
/**
* Prints string representation of a value given a Map from values to strings.
*/
public void printValue(int value, Map valueToString) {
Integer val = new Integer(value);
if (valueToString == null)
print(val.toString());
String result = (String)valueToString.get(val);
if (result == null)
print(val.toString() + " <unknown value>");
else
print(result);
}
/**
* Prints string representation of a value given a Vector with the names of the bits.
*/
public void printValue(byte value, Vector bitNames) {
printValue(value & 0xff, bitNames);
}
/**
* Prints string representation of a value given a Vector with the names of the bits.
*/
public void printValue(short value, Vector bitNames) {
printValue(value & 0xffff, bitNames);
}
/**
* Prints string representation of a value given a Vector with the names of the bits.
*/
public void printValue(int value, Vector bitNames) {
Integer val = new Integer(value);
if (bitNames == null)
print(val.toString());
boolean bitsSet = false;
for (int i = 0; i < bitNames.size(); i++) {
// Test if bit is set in value.
if ((1 << i & value) == 0)
continue;
// See if we have a desciption for the bit.
String bitString = (String)bitNames.elementAt(i);
if (bitString == null)
bitString = "<unknown bit>";
if (!bitsSet) {
print(bitString);
} else {
print(" & ");
print(bitString);
}
bitsSet = true;
}
if (!bitsSet)
print("<none>");
}
/**
* @return Returns string without XXX_ prefix.
*/
public static String removePrefix(String str) {
int i = str.indexOf('_');
if (i < 0)
return str;
else
return str.substring(i + 1);
}
}