/** * Try to read a specified number of bytes. * * @param amountToRead is the number of bytes we need * @param collectData is true if we need to actually look at the data. If false, we know we're * skipping this entry, and all we need to do is to count until we get to the right spot. * @return a byte buffer positioned at the head of the desired portion, or null if we reached eof. */ private ByteBuffer readData(int amountToRead, boolean collectData) throws ChecksumException, EOFException, FileNotFoundException, DatabaseException { int alreadyRead = 0; ByteBuffer completeBuffer = null; saveBuffer.clear(); while ((alreadyRead < amountToRead) && !eof) { int bytesNeeded = amountToRead - alreadyRead; if (window.hasRemaining()) { /* There's data in the window, process it. */ if (collectData) { /* * Save data in a buffer for processing. */ if ((alreadyRead > 0) || (window.remaining() < bytesNeeded)) { /* We need to piece an entry together. */ copyToSaveBuffer(bytesNeeded); alreadyRead = threadSafeBufferPosition(saveBuffer); completeBuffer = saveBuffer; } else { /* A complete entry is available in this buffer. */ completeBuffer = window.getBuffer(); alreadyRead = amountToRead; } } else { /* * We're not processing the data, so need to save it. just * move buffer positions. */ int positionIncrement = (window.remaining() > bytesNeeded) ? bytesNeeded : window.remaining(); alreadyRead += positionIncrement; window.incrementBufferPosition(positionIncrement); completeBuffer = window.getBuffer(); } } else { /* * Look for more data. */ if (window.fillNext(singleFile, bytesNeeded)) { /* This call to fillNext slid the window to a new file. */ nextEntryOffset = 0; } } } /* Flip the save buffer just in case we've been accumulating in it. */ threadSafeBufferFlip(saveBuffer); return completeBuffer; }