private void ensure(int bytesNeeded) throws IOException {
		checkOpen();
		long oldFileStartIndex = bufferFileStartIndex;
		long oldBufferOffset = bufferOffset;
		long oldSeekPos = oldFileStartIndex + oldBufferOffset;

		if (bufferOffset + bytesNeeded > buffer.length) {
			// check if the last buffer contained it, and swap in if necessary
			swapInLast();
			// must ensure that current read pos is in old buffer, and enough bytes
			long newBufferOffset = (oldSeekPos - bufferFileStartIndex);
			if (oldSeekPos < bufferFileStartIndex ||
				oldSeekPos >= bufferFileStartIndex + BUFFER_SIZE ||
				(newBufferOffset + bytesNeeded > buffer.length)) {
				bufferFileStartIndex = oldFileStartIndex + oldBufferOffset;

				buffer = new byte[BUFFER_SIZE];
				randomAccessFile.seek(bufferFileStartIndex);
				int bytesRead = randomAccessFile.read(buffer);
				bufferOffset = 0;
				if (bytesRead <= 0) {
					throw new EOFException();
				}
			}
			else {
				bufferOffset = newBufferOffset;
			}
		}
	}
Ensures that enough bytes are cached to
satisfy the next request to read.
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/GhidraRandomAccessFile.java