Reputation: 17511
I am representing a data object as an Iterator[Byte]
, which is created from an InputStream
instance.
The problem lies in that Byte
is a signed integer from -128 to 127, while the read
method in InputStream
returns an unsigned integer from 0 to 255. This is in particular problematic since by semantics -1 should denote the end of an input stream.
What is the best way to alleviate the incompatibility between these two types? Is there an elegant way of converting between one to another? Or should I just use Int
instead of Bytes
, even though it feels less elegant?
def toByteIterator(in: InputStream): Iterator[Byte] = {
Iterator.continually(in.read).takeWhile(-1 !=).map { elem =>
convert // need to convert unsigned int to Byte here
}
}
def toInputStream(_it: Iterator[Byte]): InputStream = {
new InputStream {
val (it, _) = _it.duplicate
override def read(): Int = {
if (it.hasNext) it.next() // need to convert Byte to unsigned int
else -1
}
}
}
Upvotes: 2
Views: 2946
Reputation: 128111
Yes, you can convert byte to int and vice versa easily.
First, int to byte can be converted with just toByte
:
scala> 128.toByte
res0: Byte = -128
scala> 129.toByte
res1: Byte = -127
scala> 255.toByte
res2: Byte = -1
so your elem => convert
could be just _.toByte
.
Second, a signed byte can be converted to an unsigned int
with a handy function in java.lang.Byte
, called toUnsignedInt
:
scala> java.lang.Byte.toUnsignedInt(-1)
res1: Int = 255
scala> java.lang.Byte.toUnsignedInt(-127)
res2: Int = 129
scala> java.lang.Byte.toUnsignedInt(-128)
res3: Int = 128
so you can write java.lang.Byte.toUnsignedInt(it.next())
in your second piece of code.
However, the last method is only available since Java 8. I don't know about its alternatives in older versions of Java, but its actual implementation is astonishingly simple:
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
so all you need is just to write
it.next().toInt & 0xff
Upvotes: 1
Reputation: 2804
Unfortunately it is something related with a bad design of the class InputStream
. If you use read() you will have that problem. You should use read(byte[]) instead.
But as you say, you could also use Int
. That is up to you.
Upvotes: 1