All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.internal.content.LazyInputStream Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.content;

import java.io.IOException;
import java.io.InputStream;

public class LazyInputStream extends InputStream implements ILazySource {
	private int blockCapacity;
	byte[][] blocks = {};
	private int bufferSize;
	private InputStream in;
	private int mark;
	private int offset;

	public LazyInputStream(InputStream in, int blockCapacity) {
		this.in = in;
		this.blockCapacity = blockCapacity;
	}

	@Override
	public int available() throws IOException {
		try {
			return bufferSize - offset + in.available();
		} catch (IOException ioe) {
			throw new LowLevelIOException(ioe);
		}
	}

	private int computeBlockSize(int blockIndex) {
		if (blockIndex < blocks.length - 1)
			return blockCapacity;
		int blockSize = bufferSize % blockCapacity;
		return blockSize == 0 ? blockCapacity : blockSize;
	}

	private int copyFromBuffer(byte[] userBuffer, int userOffset, int needed) {
		int copied = 0;
		int current = offset / blockCapacity;
		while ((needed - copied) > 0 && current < blocks.length) {
			int blockSize = computeBlockSize(current);
			int offsetInBlock = offset % blockCapacity;
			int availableInBlock = blockSize - offsetInBlock;
			int toCopy = Math.min(availableInBlock, needed - copied);
			System.arraycopy(blocks[current], offsetInBlock, userBuffer, userOffset + copied, toCopy);
			copied += toCopy;
			current++;
			offset += toCopy;
		}
		return copied;
	}

	private void ensureAvailable(long bytesToRead) throws IOException {
		int loadedBlockSize = blockCapacity;
		while (bufferSize < offset + bytesToRead && loadedBlockSize == blockCapacity) {
			try {
				loadedBlockSize = loadBlock();
			} catch (IOException e) {
				throw new LowLevelIOException(e);
			}
			bufferSize += loadedBlockSize;
		}
	}

	// for testing purposes
	protected int getBlockCount() {
		return blocks.length;
	}

	// for testing purposes
	protected int getBufferSize() {
		return bufferSize;
	}

	// for testing purposes
	protected int getMark() {
		return mark;
	}

	// for testing purposes
	protected int getOffset() {
		return offset;
	}

	@Override
	public boolean isText() {
		return false;
	}

	private int loadBlock() throws IOException {
		// read a block from the underlying stream
		byte[] newBlock = new byte[blockCapacity];
		int readCount = in.read(newBlock);
		if (readCount == -1)
			return 0;
		// expand blocks array
		byte[][] tmpBlocks = new byte[blocks.length + 1][];
		System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
		blocks = tmpBlocks;
		blocks[blocks.length - 1] = newBlock;
		return readCount;
	}

	@Override
	public synchronized void mark(int readlimit) {
		mark = offset;
	}

	@Override
	public boolean markSupported() {
		return true;
	}

	@Override
	public int read() throws IOException {
		ensureAvailable(1);
		if (bufferSize <= offset)
			return -1;
		int nextByte = 0xFF & blocks[offset / blockCapacity][offset % blockCapacity];
		offset++;
		return nextByte;
	}

	@Override
	public int read(byte[] b) throws IOException {
		return read(b, 0, b.length);
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		ensureAvailable(len);
		int copied = copyFromBuffer(b, off, len);
		return copied == 0 ? -1 : copied;
	}

	@Override
	public synchronized void reset() {
		offset = mark;
	}

	@Override
	public void rewind() {
		mark = 0;
		offset = 0;
	}

	@Override
	public long skip(long toSkip) throws IOException {
		if (toSkip <= 0)
			return 0;
		ensureAvailable(toSkip);
		long skipped = Math.min(toSkip, bufferSize - offset);
		offset += skipped;
		return skipped;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy