/** Copy the required number of bytes into the save buffer. */ private void copyToSaveBuffer(int bytesNeeded) { /* How much can we get from this current read buffer? */ int bytesFromThisBuffer; if (bytesNeeded <= window.remaining()) { bytesFromThisBuffer = bytesNeeded; } else { bytesFromThisBuffer = window.remaining(); } /* Gather it all into this save buffer. */ ByteBuffer temp; /* Make sure the save buffer is big enough. */ if (saveBuffer.capacity() - threadSafeBufferPosition(saveBuffer) < bytesFromThisBuffer) { /* Grow the save buffer. */ temp = ByteBuffer.allocate(saveBuffer.capacity() + bytesFromThisBuffer); threadSafeBufferFlip(saveBuffer); temp.put(saveBuffer); saveBuffer = temp; } /* * Bulk copy only the required section from the read buffer into the * save buffer. We need from readBuffer.position() to * readBuffer.position() + bytesFromThisBuffer */ temp = window.getBuffer().slice(); temp.limit(bytesFromThisBuffer); saveBuffer.put(temp); window.incrementBufferPosition(bytesFromThisBuffer); }
/** * 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; }