
dorkbox.annotation.ClassFileBuffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Annotations Show documentation
Show all versions of Annotations Show documentation
Extremely fast, lightweight annotation scanner for the classpath, classloader, or specified location for java applications.
The newest version!
/* ClassFileBuffer.java
*
* Created: 2011-10-10 (Year-Month-Day)
* Character encoding: UTF-8
*
****************************************** LICENSE *******************************************
*
* Copyright (c) 2011 - 2013 XIAM Solutions B.V. (http://www.xiam.nl)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.annotation;
import java.io.*;
/**
* {@code ClassFileBuffer} is used by {@link AnnotationDetector} to efficiently read Java
* ClassFile files from an {@link InputStream} and parse the content via the {@link DataInput}
* interface.
*
* Note that Java ClassFile files can grow really big,
* {@code com.sun.corba.se.impl.logging.ORBUtilSystemException} is 128.2 kb!
*
* @author Ronald K. Muller
* @since annotation-detector 3.0.0
*/
final
class ClassFileBuffer implements DataInput {
private byte[] buffer;
private int size; // the number of significant bytes read
private int pointer; // the "read pointer"
/**
* Create a new, empty {@code ClassFileBuffer} with the default initial capacity (8 kb).
*/
ClassFileBuffer() {
this(8 * 1024);
}
/**
* Create a new, empty {@code ClassFileBuffer} with the specified initial capacity.
* The initial capacity must be greater than zero. The internal buffer will grow
* automatically when a higher capacity is required. However, buffer resizing occurs
* extra overhead. So in good initial capacity is important in performance critical
* situations.
*/
ClassFileBuffer(final int initialCapacity) {
if (initialCapacity < 1) {
throw new IllegalArgumentException("initialCapacity < 1: " + initialCapacity);
}
this.buffer = new byte[initialCapacity];
}
/**
* Clear and fill the buffer of this {@code ClassFileBuffer} with the
* supplied byte stream.
* The read pointer is reset to the start of the byte array.
*/
public
void readFrom(final InputStream in) throws IOException {
this.pointer = 0;
this.size = 0;
int n;
do {
n = in.read(this.buffer, this.size, this.buffer.length - this.size);
if (n > 0) {
this.size += n;
}
resizeIfNeeded();
} while (n >= 0);
}
/**
* Sets the file-pointer offset, measured from the beginning of this file,
* at which the next read or write occurs.
*/
public
void seek(final int position) throws IOException {
if (position < 0) {
throw new IllegalArgumentException("position < 0: " + position);
}
if (position > this.size) {
throw new EOFException();
}
this.pointer = position;
}
/**
* Return the size (in bytes) of this Java ClassFile file.
*/
public
int size() {
return this.size;
}
// DataInput
@Override
public
void readFully(final byte[] bytes) throws IOException {
readFully(bytes, 0, bytes.length);
}
@Override
public
void readFully(final byte[] bytes, final int offset, final int length) throws IOException {
if (length < 0 || offset < 0 || offset + length > bytes.length) {
throw new IndexOutOfBoundsException();
}
if (this.pointer + length > this.size) {
throw new EOFException();
}
System.arraycopy(this.buffer, this.pointer, bytes, offset, length);
this.pointer += length;
}
@Override
public
int skipBytes(final int n) throws IOException {
seek(this.pointer + n);
return n;
}
@Override
public
byte readByte() throws IOException {
if (this.pointer >= this.size) {
throw new EOFException();
}
return this.buffer[this.pointer++];
}
@Override
public
boolean readBoolean() throws IOException {
return readByte() != 0;
}
@Override
public
int readUnsignedByte() throws IOException {
if (this.pointer >= this.size) {
throw new EOFException();
}
return read();
}
@Override
public
int readUnsignedShort() throws IOException {
if (this.pointer + 2 > this.size) {
throw new EOFException();
}
return (read() << 8) + read();
}
@Override
public
short readShort() throws IOException {
return (short) readUnsignedShort();
}
@Override
public
char readChar() throws IOException {
return (char) readUnsignedShort();
}
@Override
public
int readInt() throws IOException {
if (this.pointer + 4 > this.size) {
throw new EOFException();
}
return (read() << 24) +
(read() << 16) +
(read() << 8) +
read();
}
@Override
public
long readLong() throws IOException {
if (this.pointer + 8 > this.size) {
throw new EOFException();
}
return ((long) read() << 56) +
((long) read() << 48) +
((long) read() << 40) +
((long) read() << 32) +
(read() << 24) +
(read() << 16) +
(read() << 8) +
read();
}
@Override
public
float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
@Override
public
double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
/**
* This methods throws an {@link UnsupportedOperationException} because the method
* is deprecated and not used in the context of this implementation.
*
* @deprecated Does not support UTF-8, use readUTF() instead
*/
@Override
@Deprecated
public
String readLine() throws IOException {
throw new UnsupportedOperationException("readLine() is deprecated and not supported");
}
@Override
public
String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
// private
private
int read() {
return this.buffer[this.pointer++] & 0xff;
}
private
void resizeIfNeeded() {
if (this.size >= this.buffer.length) {
final byte[] newBuffer = new byte[this.buffer.length * 2];
System.arraycopy(this.buffer, 0, newBuffer, 0, this.buffer.length);
this.buffer = newBuffer;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy