Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion shared/src/main/scala/scorex/util/Extensions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ object Extensions {
* If `Long` value is out of the possible range for a [[scala.Int]] result,
* then a `java.lang.ArithmeticException` is thrown.
*/
@deprecated("Use Reader#getUIntExact() instead")
def toIntExact: Int = {
if (x < Int.MinValue || x > Int.MaxValue)
throw new ArithmeticException("Int overflow")
Expand All @@ -86,7 +87,7 @@ object Extensions {

/**
* Safely casting each element of collection to be type of `B`.
* If element can not to be cast to `B` then `AssertionError` is thrown
* If element can not to be cast to `B` then `IllegalArgumentException` is thrown
*/
def cast[B:ClassTag]: Source[B] = {

Expand Down
7 changes: 7 additions & 0 deletions shared/src/main/scala/scorex/util/serialization/Reader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,15 @@ abstract class Reader {
* Decode positive Int.
* @return signed Long
*/
@deprecated("Use getUIntExact() instead")
def getUInt(): Long

/**
* Decode positive Int.
* @return unsigned 31-bit Int
*/
def getUIntExact(): Int

/**
* Decode signed Long.
* @return signed Long
Expand Down
15 changes: 14 additions & 1 deletion shared/src/main/scala/scorex/util/serialization/VLQReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ trait VLQReader extends Reader {
* Decode Short previously encoded with [[VLQWriter.putUShort]] using VLQ.
* @see [[https://en.wikipedia.org/wiki/Variable-length_quantity]]
* @return Int
* @throws AssertionError for deserialized values not in unsigned Short range
* @throws IllegalArgumentException for deserialized values not in unsigned Short range
*/
@inline override def getUShort(): Int = {
val x = getULong().toInt
Expand All @@ -50,13 +50,26 @@ trait VLQReader extends Reader {
* Decode Int previously encoded with [[VLQWriter.putUInt]] using VLQ.
* @see [[https://en.wikipedia.org/wiki/Variable-length_quantity]]
* @return Long
* @throws IllegalArgumentException for deserialized values not in unsigned Int range
*/
@inline override def getUInt(): Long = {
val x = getULong()
require(x >= 0L && x <= 0xFFFFFFFFL, s"$x is out of unsigned int range")
x
}

/**
* Decode Int previously encoded with [[VLQWriter.putUInt]] using VLQ.
* @see [[https://en.wikipedia.org/wiki/Variable-length_quantity]]
* @return Int
* @throws IllegalArgumentException for deserialized values not in unsigned 31-bit Int range
*/
@inline override def getUIntExact(): Int = {
val x = getULong()
require(x >= 0L && x <= Int.MaxValue.toLong, s"$x is out of unsigned 31-bit int range")
x.toInt
}

/**
* Decode signed Long previously encoded with [[VLQWriter.putLong]] using VLQ with ZigZag.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trait VLQWriter extends Writer {
*
* @see [[https://en.wikipedia.org/wiki/Variable-length_quantity]]
* @param x unsigned Short in a range 0 <= x <= 0xFFFF represented as Int
* @throws AssertionError for values not in unsigned Short range
* @throws IllegalArgumentException for values not in unsigned Short range
*/
@inline override def putUShort(x: Int): this.type = {
require(x >= 0 && x <= 0xFFFF, s"Value $x is out of unsigned short range")
Expand Down Expand Up @@ -59,7 +59,7 @@ trait VLQWriter extends Writer {
*
* @see [[https://en.wikipedia.org/wiki/Variable-length_quantity]]
* @param x unsigned Int
* @throws AssertionError for values not in unsigned Int range
* @throws IllegalArgumentException for values not in unsigned Int range
*/
@inline override def putUInt(x: Long): this.type = {
require(x >= 0 && x <= 0xFFFFFFFFL, s"$x is out of unsigned int range")
Expand Down Expand Up @@ -151,7 +151,7 @@ trait VLQWriter extends Writer {
* Encode String is shorter than 256 bytes
*
* @param s String
* @return
* @throws IllegalArgumentException for strings longer than 255 bytes
*/
override def putShortString(s: String): this.type = {
val bytes = s.getBytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ abstract class Writer {
* Encode integer as an unsigned byte asserting the range check
* @param x integer value to encode
* @return
* @throws AssertionError if x is outside of the unsigned byte range
* @throws IllegalArgumentException if x is outside of the unsigned byte range
*/
def putUByte(x: Int): this.type = {
require(x >= 0 && x <= 0xFF, s"$x is out of unsigned byte range")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,18 @@ trait VLQReaderWriterSpecification extends AnyPropSpec
}
}

property("unsigned Int roundtrip exact"){
forAll(Gen.chooseNum(0, Int.MaxValue)) { x: Int =>
byteBufReader(byteArrayWriter().putUInt(x.toLong).toBytes).getUIntExact() shouldBe x
}
forAll(Gen.chooseNum(Long.MinValue, -1L)) { x: Long =>
an[IllegalArgumentException] should be thrownBy byteBufReader(byteArrayWriter().putULong(x).toBytes).getUIntExact()
}
forAll(Gen.chooseNum(Int.MaxValue.toLong + 1L, Long.MaxValue)) { x: Long =>
an[IllegalArgumentException] should be thrownBy byteBufReader(byteArrayWriter().putULong(x).toBytes).getUIntExact()
}
}

property("Long roundtrip") {
forAll { (v: Long) => byteBufReader(byteArrayWriter().putLong(v).toBytes).getLong() shouldBe v }
}
Expand Down
Loading