Description
Describe the bug
Summary: stream reading in StreamByteBuffer
is incomplete.
When a DicomFile
is created from a Stream
, by default large tags will be saved as a StreamByteBuffer
, so that the data can be retrieved on demand but not block other operations. When the bytes are requested from the StreamByteBuffer
, the Data accessor and GetByteRange both make a single call to Stream.Read
. However, the underlying Stream
is not guaranteed to have all of the requested bytes available, and so what can be returned is a byte array with only part of the requested data.
This came to light in the context of an Azure Storage LazyLoadingReadOnlyStream
, which buffers 4MB by default. The returned byte array for a pixel data element > 4MB will have 4MB of data and the
5A44
rest of the array will be null values.
As this issue makes clear, this is expected behavior for all Streams
, and so the consumer should check the return value of calls to Stream.Read
until no more bytes are returned. The same logic is already implemented in the CopyToStream*
methods.
To Reproduce
Here's a code sample that uses a toy buffered stream to simulate the buffering behavior, and gets StreamByteBuffer.Data
with the existing logic (which results in incomplete data) versus updated logic (which results in complete data).
Expected behavior
I expect StreamByteBuffer.Data
to return the entire requested range of bytes. There should be no concerns about blocking since this is an on-demand retrieval.
Environment
Fellow Oak DICOM version: (5.0.2)
OS: (Windows 10 x64)
Platform: (all)