public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); while (length > 0) { var off = start % fullChunkSize; int read; if (off < chunkStart.Length) { read = (int)Math.Min(length, chunkStart.Length - off); chunkStart.ReadBytesToBuffer(buffer, off, read, offset); } else if (off > fullChunkSize - 3) { read = (int)Math.Min(length, fullChunkSize - off); chunkEnd.ReadBytesToBuffer(buffer, off - (fullChunkSize - 2), read, offset); } else { var chunk = start / fullChunkSize; off -= chunkStart.Length; read = (int)Math.Min(length, chunkSize - off); innerStream.ReadBytesToBuffer(buffer, chunk * chunkSize + off, read, offset); } length -= read; offset += read; start += read; } }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); innerStream.ReadBytesToBuffer(buffer, start, length, offset); for (long i = 0; i < length; ++i) { buffer[offset + i] = (byte)(buffer[offset + i] ^ mask[(start + i) % 4]); } }
/// <inheritdoc/> public byte ReadByte(long index) { IDataStreamHelpers.ReadByteArgsCheck(this, index); ChunkHint hint; lock (dataLock) { var hintIdx = locateChunk(index); hint = chunkHints[hintIdx]; } var seg = new StreamSegment(stream, hint.StreamStart); return(seg.ReadByte(index - hint.DataStart)); }
/// <inheritdoc/> public void ReadBytesToBuffer(byte[] buffer, long start = 0, int length = -1, int offset = 0) { IDataStreamHelpers.ReadBytesToBufferArgsCheck(this, buffer, start, ref length, offset); if (length == 0) { return; } var remaining = length; var hintIdx = locateChunk(start); var hint = chunkHints[hintIdx]; // these 2 must be close together, 2GiB chunks are too big int chunkOffset = (int)(start - hint.DataStart); while (remaining > 0) { lock (dataLock) { if (chunkHints.Count <= hintIdx) { hint = hint.ComputeNextHint(this); chunkHints.Add(hint); } else { hint = chunkHints[hintIdx]; } } var seg = new StreamSegment(stream, hint.StreamStart); var read = (int)Math.Min(hint.DataLength - chunkOffset, remaining); seg.ReadBytesToBuffer(buffer, chunkOffset, read, offset); offset += read; remaining -= read; chunkOffset = 0; ++hintIdx; } }