Fixed ByteIterator InputStream wrapping
Result of ByteIterator.asInputStream did not work correctly in all cases
This commit is contained in:
parent
696cd5a192
commit
c185f72c37
1 changed files with 52 additions and 22 deletions
|
|
@ -16,27 +16,6 @@ import scala.annotation.tailrec
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
object ByteIterator {
|
object ByteIterator {
|
||||||
/**
|
|
||||||
* An InputStream that directly wraps a ByteIterator without copying
|
|
||||||
*/
|
|
||||||
final class InputStreamWrapper(val iterator: ByteIterator) extends java.io.InputStream {
|
|
||||||
override def available: Int = iterator.len
|
|
||||||
|
|
||||||
def read: Int = if (iterator.hasNext) (iterator.next.toInt & 0xff) else -1
|
|
||||||
|
|
||||||
override def read(b: Array[Byte], off: Int, len: Int): Int = {
|
|
||||||
val nRead = math.min(iterator.len, len - off)
|
|
||||||
iterator.copyToArray(b, off, nRead)
|
|
||||||
nRead
|
|
||||||
}
|
|
||||||
|
|
||||||
override def skip(n: Long): Long = {
|
|
||||||
val nSkip = math.min(iterator.len, n.toInt)
|
|
||||||
iterator.drop(nSkip)
|
|
||||||
nSkip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object ByteArrayIterator {
|
object ByteArrayIterator {
|
||||||
private val emptyArray: Array[Byte] = Array.ofDim[Byte](0)
|
private val emptyArray: Array[Byte] = Array.ofDim[Byte](0)
|
||||||
|
|
||||||
|
|
@ -50,6 +29,8 @@ object ByteIterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ByteArrayIterator private (private var array: Array[Byte], private var from: Int, private var until: Int) extends ByteIterator {
|
class ByteArrayIterator private (private var array: Array[Byte], private var from: Int, private var until: Int) extends ByteIterator {
|
||||||
|
iterator ⇒
|
||||||
|
|
||||||
protected[util] final def internalArray = array
|
protected[util] final def internalArray = array
|
||||||
protected[util] final def internalFrom = from
|
protected[util] final def internalFrom = from
|
||||||
protected[util] final def internalUntil = until
|
protected[util] final def internalUntil = until
|
||||||
|
|
@ -171,6 +152,28 @@ object ByteIterator {
|
||||||
}
|
}
|
||||||
copyLength
|
copyLength
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def asInputStream: java.io.InputStream = new java.io.InputStream {
|
||||||
|
override def available: Int = iterator.len
|
||||||
|
|
||||||
|
def read: Int = if (hasNext) (next().toInt & 0xff) else -1
|
||||||
|
|
||||||
|
override def read(b: Array[Byte], off: Int, len: Int): Int = {
|
||||||
|
if ((off < 0) || (len < 0) || (off + len > b.length)) throw new IndexOutOfBoundsException
|
||||||
|
if (len == 0) 0
|
||||||
|
else if (!isEmpty) {
|
||||||
|
val nRead = math.min(available, len)
|
||||||
|
copyToArray(b, off, nRead)
|
||||||
|
nRead
|
||||||
|
} else -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override def skip(n: Long): Long = {
|
||||||
|
val nSkip = math.min(iterator.len, n.toInt)
|
||||||
|
iterator.drop(nSkip)
|
||||||
|
nSkip
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object MultiByteArrayIterator {
|
object MultiByteArrayIterator {
|
||||||
|
|
@ -351,6 +354,33 @@ object ByteIterator {
|
||||||
normalize()
|
normalize()
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def asInputStream: java.io.InputStream = new java.io.InputStream {
|
||||||
|
override def available: Int = current.len
|
||||||
|
|
||||||
|
def read: Int = if (hasNext) (next().toInt & 0xff) else -1
|
||||||
|
|
||||||
|
override def read(b: Array[Byte], off: Int, len: Int): Int = {
|
||||||
|
val nRead = current.asInputStream.read(b, off, len)
|
||||||
|
normalize()
|
||||||
|
nRead
|
||||||
|
}
|
||||||
|
|
||||||
|
override def skip(n: Long): Long = {
|
||||||
|
@tailrec def skipImpl(n: Long, skipped: Long): Long = if (n > 0) {
|
||||||
|
if (!isEmpty) {
|
||||||
|
val m = current.asInputStream.skip(n)
|
||||||
|
normalize()
|
||||||
|
val newN = n - m
|
||||||
|
val newSkipped = skipped + m
|
||||||
|
if (newN > 0) skipImpl(newN, newSkipped)
|
||||||
|
else newSkipped
|
||||||
|
} else 0
|
||||||
|
} else 0
|
||||||
|
|
||||||
|
skipImpl(n, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -598,5 +628,5 @@ abstract class ByteIterator extends BufferedIterator[Byte] {
|
||||||
* Read and skip operations on the stream will advance the iterator
|
* Read and skip operations on the stream will advance the iterator
|
||||||
* accordingly.
|
* accordingly.
|
||||||
*/
|
*/
|
||||||
def asInputStream: java.io.InputStream = new ByteIterator.InputStreamWrapper(this)
|
def asInputStream: java.io.InputStream
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue