Methods Summary |
---|
public void | alignTo(int alignment){@inheritDoc}
int mask = alignment - 1;
if ((alignment < 0) || ((mask & alignment) != 0)) {
throw new IllegalArgumentException("bogus alignment");
}
int end = (cursor + mask) & ~mask;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
/*
* There is no need to actually write zeroes, since the array is
* already preinitialized with zeroes.
*/
cursor = end;
|
public void | annotate(java.lang.String msg){@inheritDoc}
if (annotations == null) {
return;
}
endAnnotation();
annotations.add(new Annotation(cursor, msg));
|
public void | annotate(int amt, java.lang.String msg){@inheritDoc}
if (annotations == null) {
return;
}
endAnnotation();
int asz = annotations.size();
int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();
int startAt;
if (lastEnd <= cursor) {
startAt = cursor;
} else {
startAt = lastEnd;
}
annotations.add(new Annotation(startAt, startAt + amt, msg));
|
public boolean | annotates(){@inheritDoc}
return (annotations != null);
|
public void | assertCursor(int expectedCursor){@inheritDoc}
if (cursor != expectedCursor) {
throw new ExceptionWithContext("expected cursor " +
expectedCursor + "; actual value: " + cursor);
}
|
public void | enableAnnotations(int annotationWidth, boolean verbose)Indicates that this instance should keep annotations. This method may
be called only once per instance, and only before any data has been
written to the it.
if ((annotations != null) || (cursor != 0)) {
throw new RuntimeException("cannot enable annotations");
}
if (annotationWidth < 40) {
throw new IllegalArgumentException("annotationWidth < 40");
}
int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;
if (hexCols < 6) {
hexCols = 6;
} else if (hexCols > 10) {
hexCols = 10;
}
this.annotations = new ArrayList<Annotation>(1000);
this.annotationWidth = annotationWidth;
this.hexCols = hexCols;
this.verbose = verbose;
|
public void | endAnnotation(){@inheritDoc}
if (annotations == null) {
return;
}
int sz = annotations.size();
if (sz != 0) {
annotations.get(sz - 1).setEndIfUnset(cursor);
}
|
private void | ensureCapacity(int desiredSize)Reallocates the underlying array if necessary. Calls to this method
should be guarded by a test of {@link #stretchy}.
if (data.length < desiredSize) {
byte[] newData = new byte[desiredSize * 2 + 1000];
System.arraycopy(data, 0, newData, 0, cursor);
data = newData;
}
|
public void | finishAnnotating()Finishes up annotation processing. This closes off any open
annotations and removes annotations that don't refer to written
data.
// Close off the final annotation, if any.
endAnnotation();
// Remove annotations that refer to unwritten data.
if (annotations != null) {
int asz = annotations.size();
while (asz > 0) {
Annotation last = annotations.get(asz - 1);
if (last.getStart() > cursor) {
annotations.remove(asz - 1);
asz--;
} else if (last.getEnd() > cursor) {
last.setEnd(cursor);
break;
} else {
break;
}
}
}
|
public int | getAnnotationWidth(){@inheritDoc}
int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);
return annotationWidth - leftWidth;
|
public byte[] | getArray()Gets the underlying {@code byte[]} of this instance, which
may be larger than the number of bytes written
return data;
|
public int | getCursor(){@inheritDoc}
return cursor;
|
public boolean | isVerbose(){@inheritDoc}
return verbose;
|
private static void | throwBounds()Throws the excpetion for when an attempt is made to write past the
end of the instance.
throw new IndexOutOfBoundsException("attempt to write past the end");
|
public byte[] | toByteArray()Constructs and returns a new {@code byte[]} that contains
the written contents exactly (that is, with no extra unwritten
bytes at the end).
byte[] result = new byte[cursor];
System.arraycopy(data, 0, result, 0, cursor);
return result;
|
public void | write(ByteArray bytes){@inheritDoc}
int blen = bytes.size();
int writeAt = cursor;
int end = writeAt + blen;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
bytes.getBytes(data, writeAt);
cursor = end;
|
public void | write(byte[] bytes, int offset, int length){@inheritDoc}
int writeAt = cursor;
int end = writeAt + length;
int bytesEnd = offset + length;
// twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {
throw new IndexOutOfBoundsException("bytes.length " +
bytes.length + "; " +
offset + "..!" + end);
}
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
System.arraycopy(bytes, offset, data, writeAt, length);
cursor = end;
|
public void | write(byte[] bytes){@inheritDoc}
write(bytes, 0, bytes.length);
|
public void | writeAnnotationsTo(java.io.Writer out)Writes the annotated content of this instance to the given writer.
int width2 = getAnnotationWidth();
int width1 = annotationWidth - width2 - 1;
TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, "|");
Writer left = twoc.getLeft();
Writer right = twoc.getRight();
int leftAt = 0; // left-hand byte output cursor
int rightAt = 0; // right-hand annotation index
int rightSz = annotations.size();
while ((leftAt < cursor) && (rightAt < rightSz)) {
Annotation a = annotations.get(rightAt);
int start = a.getStart();
int end;
String text;
if (leftAt < start) {
// This is an area with no annotation.
end = start;
start = leftAt;
text = "";
} else {
// This is an area with an annotation.
end = a.getEnd();
text = a.getText();
rightAt++;
}
left.write(Hex.dump(data, start, end - start, start, hexCols, 6));
right.write(text);
twoc.flush();
leftAt = end;
}
if (leftAt < cursor) {
// There is unannotated output at the end.
left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt,
hexCols, 6));
}
while (rightAt < rightSz) {
// There are zero-byte annotations at the end.
right.write(annotations.get(rightAt).getText());
rightAt++;
}
twoc.flush();
|
public void | writeByte(int value){@inheritDoc}
int writeAt = cursor;
int end = writeAt + 1;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
data[writeAt] = (byte) value;
cursor = end;
|
public void | writeInt(int value){@inheritDoc}
int writeAt = cursor;
int end = writeAt + 4;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
data[writeAt] = (byte) value;
data[writeAt + 1] = (byte) (value >> 8);
data[writeAt + 2] = (byte) (value >> 16);
data[writeAt + 3] = (byte) (value >> 24);
cursor = end;
|
public void | writeLong(long value){@inheritDoc}
int writeAt = cursor;
int end = writeAt + 8;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
int half = (int) value;
data[writeAt] = (byte) half;
data[writeAt + 1] = (byte) (half >> 8);
data[writeAt + 2] = (byte) (half >> 16);
data[writeAt + 3] = (byte) (half >> 24);
half = (int) (value >> 32);
data[writeAt + 4] = (byte) half;
data[writeAt + 5] = (byte) (half >> 8);
data[writeAt + 6] = (byte) (half >> 16);
data[writeAt + 7] = (byte) (half >> 24);
cursor = end;
|
public void | writeShort(int value){@inheritDoc}
int writeAt = cursor;
int end = writeAt + 2;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
data[writeAt] = (byte) value;
data[writeAt + 1] = (byte) (value >> 8);
cursor = end;
|
public int | writeSignedLeb128(int value){@inheritDoc}
int remaining = value >> 7;
int count = 0;
boolean hasMore = true;
int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
while (hasMore) {
hasMore = (remaining != end)
|| ((remaining & 1) != ((value >> 6) & 1));
writeByte((value & 0x7f) | (hasMore ? 0x80 : 0));
value = remaining;
remaining >>= 7;
count++;
}
return count;
|
public int | writeUnsignedLeb128(int value){@inheritDoc}
int remaining = value >> 7;
int count = 0;
while (remaining != 0) {
writeByte((value & 0x7f) | 0x80);
value = remaining;
remaining >>= 7;
count++;
}
writeByte(value & 0x7f);
return count + 1;
|
public void | writeZeroes(int count){@inheritDoc}
if (count < 0) {
throw new IllegalArgumentException("count < 0");
}
int end = cursor + count;
if (stretchy) {
ensureCapacity(end);
} else if (end > data.length) {
throwBounds();
return;
}
/*
* There is no need to actually write zeroes, since the array is
* already preinitialized with zeroes.
*/
cursor = end;
|