Reputation: 1861
What is the equivalent Scala for the following Python statement? It looks like it's using an unsigned long or something (which Scala doesn't have).
size = pack('!L', len(someString))
Upvotes: 3
Views: 955
Reputation: 24042
There's not an exact one-for-one mapping for this statement, but you can get close.
In Scala, you typically don't store binary data in a string as pack
does. Instead you store it in an Array[Byte]
.
Scala itself doesn't have any libraries for this, but Java does, and you can use them in your Scala code.
val out = new java.io.ByteArrayOutputStream()
val writer = new java.io.DataOutputStream(out)
writer.writeInt(someString.length)
writer.close()
val data = out.toByteArray
There are several things to note about why this works:
DataOutputStream
writes in big-endian order, which matches your use of !
in the Python code. If you were writing in little-endian order, you'd have to use a little-endian implementation of DataOutputStream.pack
method writes a long as 4 bytes, which matches writeInt
in DataOutputStream
. writeLong
would be the same as long long
(q
or Q
) in pack
.Upvotes: 1
Reputation: 297205
Scala has no such thing in its standard library: you should look at Java for that.
By the way, you can't do this with String
: you need to apply such methods to Array[Byte]
. The problem with String
is that it is composed by UTF-16 characters, so some byte sequences are illegal strings.
Upvotes: 1
Reputation: 24423
According to the python docs the pack
method does the following:
Return a string containing the values v1, v2, ... packed according to the given format. The arguments must match the values required by the format exactly.
The !
means Big Endian, the L
means Unsigned Long
.
You're right, Scala does not have unsigned numerics. But this is not important, because it only means, that the passed in value must be in the range of an unsigned long.
See this output:
>>> pack("!L", 2442442424)
'\x91\x94\xb6\xb8'
>>> pack("!l", 2442442424)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: 'l' format requires -2147483648 <= number <= 2147483647
I don't think there is an equivalent method in scala's or java's stdlib, but it shouldn't be hard to write one. You only have to convert your number to big endian and then convert it to a byte array.
Upvotes: 2