2

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
    }
  }
}
2
  • what about byte b=(byte)intValue-128; Commented May 15, 2015 at 10:20
  • It seems rather unintuitive esp. to those who are not familiar that such problem even exists. I would like to avoid that if possible, since due to the nature and scale of the data I'm dealing with, it is very hard to recover the data once it is corrupted Commented May 15, 2015 at 15:01

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.