@@ -45,7 +45,7 @@ package object io extends ioplatform {
4545 fis,
4646 F .delay(new Array [Byte ](chunkSize)),
4747 closeAfterUse
48- )((is, buf) => F .blocking(is.read(buf)))
48+ )((is, buf, off ) => F .blocking(is.read(buf, off, buf.length - off )))
4949
5050 private [io] def readInputStreamCancelable [F [_]](
5151 fis : F [InputStream ],
@@ -57,7 +57,7 @@ package object io extends ioplatform {
5757 fis,
5858 F .delay(new Array [Byte ](chunkSize)),
5959 closeAfterUse
60- )((is, buf) => F .blocking(is.read(buf)).cancelable(cancel))
60+ )((is, buf, off ) => F .blocking(is.read(buf, off, buf.length - off )).cancelable(cancel))
6161
6262 /** Reads all bytes from the specified `InputStream` with a buffer size of `chunkSize`.
6363 * Set `closeAfterUse` to false if the `InputStream` should not be closed after use.
@@ -76,31 +76,28 @@ package object io extends ioplatform {
7676 fis,
7777 F .pure(new Array [Byte ](chunkSize)),
7878 closeAfterUse
79- )((is, buf) => F .blocking(is.read(buf)))
79+ )((is, buf, off ) => F .blocking(is.read(buf, off, buf.length - off )))
8080
81- private def readBytesFromInputStream [F [_]](is : InputStream , buf : Array [Byte ])(
82- read : (InputStream , Array [Byte ]) => F [Int ]
81+ private def readBytesFromInputStream [F [_]](is : InputStream , buf : Array [Byte ], offset : Int )(
82+ read : (InputStream , Array [Byte ], Int ) => F [Int ]
8383 )(implicit
8484 F : Sync [F ]
85- ): F [Option [Chunk [Byte ]]] =
86- read(is, buf).map { numBytes =>
85+ ): F [Option [( Chunk [Byte ], Option [( Array [ Byte ], Int )]) ]] =
86+ read(is, buf, offset ).map { numBytes =>
8787 if (numBytes < 0 ) None
88- else if (numBytes == 0 ) Some (Chunk .empty)
89- else if (numBytes < buf.size) Some (Chunk .array(buf, 0 , numBytes))
90- else Some (Chunk .array(buf))
88+ else if (offset + numBytes == buf.size) Some (Chunk .array(buf, offset, numBytes) -> None )
89+ else Some (Chunk .array(buf, offset, numBytes) -> Some (buf -> (offset + numBytes)))
9190 }
9291
9392 private [fs2] def readInputStreamGeneric [F [_]](
9493 fis : F [InputStream ],
9594 buf : F [Array [Byte ]],
9695 closeAfterUse : Boolean
97- )(read : (InputStream , Array [Byte ]) => F [Int ])(implicit F : Sync [F ]): Stream [F , Byte ] = {
98- def useIs (is : InputStream ) =
99- Stream
100- .eval(buf.flatMap(b => readBytesFromInputStream(is, b)(read)))
101- .repeat
102- .unNoneTerminate
103- .flatMap(c => Stream .chunk(c))
96+ )(read : (InputStream , Array [Byte ], Int ) => F [Int ])(implicit F : Sync [F ]): Stream [F , Byte ] = {
97+ def useIs (is : InputStream ) = Stream .unfoldChunkEval(Option .empty[(Array [Byte ], Int )]) {
98+ case None => buf.flatMap(b => readBytesFromInputStream(is, b, 0 )(read))
99+ case Some ((b, offset)) => readBytesFromInputStream(is, b, offset)(read)
100+ }
104101
105102 if (closeAfterUse)
106103 Stream .bracket(fis)(is => Sync [F ].blocking(is.close())).flatMap(useIs)
0 commit comments