@GuardedBy("lock") private void ensureAllocated(long startOffset, int length) { long endOffset = startOffset + length; int desiredSize = getOffsetLocation(endOffset).bufferSequence + 1; while (this.data.size() < desiredSize) { this.data.add(new byte[BUFFER_SIZE]); } }
int read(long startOffset, byte[] target, int targetOffset, int length) { synchronized (this.lock) { Exceptions.checkArrayRange(targetOffset, length, target.length, "targetOffset", "length"); Exceptions.checkArrayRange(startOffset, length, this.length, "startOffset", "length"); long offset = startOffset; int readBytes = 0; while (readBytes < length) { OffsetLocation ol = getOffsetLocation(offset); int bytesToCopy = Math.min(BUFFER_SIZE - ol.bufferOffset, length - readBytes); System.arraycopy(this.data.get(ol.bufferSequence), ol.bufferOffset, target, targetOffset + readBytes, bytesToCopy); readBytes += bytesToCopy; offset += bytesToCopy; } return readBytes; } }
@GuardedBy("lock") @SneakyThrows(IOException.class) private void writeInternal(long startOffset, InputStream data, int length) throws BadOffsetException, StreamSegmentSealedException { Exceptions.checkArgument(length >= 0, "length", "bad length"); if (startOffset != this.length) { throw new BadOffsetException(this.name, this.length, startOffset); } if (this.sealed) { throw new StreamSegmentSealedException(this.name); } long offset = startOffset; ensureAllocated(offset, length); int writtenBytes = 0; while (writtenBytes < length) { OffsetLocation ol = getOffsetLocation(offset); int readBytes = data.read(this.data.get(ol.bufferSequence), ol.bufferOffset, Math.min(length - writtenBytes, BUFFER_SIZE - ol.bufferOffset)); if (readBytes < 0) { throw new IOException("reached end of stream while still expecting data"); } writtenBytes += readBytes; offset += readBytes; } this.length = Math.max(this.length, startOffset + length); }