Fix varint writing
This commit is contained in:
parent
4b07f97168
commit
848c402246
@ -20,9 +20,15 @@ val projectGroup: String by project
|
|||||||
val projectVersion: String by project
|
val projectVersion: String by project
|
||||||
val specifyKotlinAsDependency: String by project
|
val specifyKotlinAsDependency: String by project
|
||||||
val fastutilVersion: String by project
|
val fastutilVersion: String by project
|
||||||
|
val jupiterVersion: String by project
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter:${jupiterVersion}")
|
||||||
|
|
||||||
implementation("it.unimi.dsi:fastutil:$fastutilVersion")
|
implementation("it.unimi.dsi:fastutil:$fastutilVersion")
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,9 @@ kotlin.code.style=official
|
|||||||
specifyKotlinAsDependency=false
|
specifyKotlinAsDependency=false
|
||||||
|
|
||||||
projectGroup=ru.dbotthepony.kommons
|
projectGroup=ru.dbotthepony.kommons
|
||||||
projectVersion=2.1.7
|
projectVersion=2.1.8
|
||||||
|
|
||||||
guavaDepVersion=33.0.0
|
guavaDepVersion=33.0.0
|
||||||
gsonDepVersion=2.8.9
|
gsonDepVersion=2.8.9
|
||||||
fastutilVersion=8.5.6
|
fastutilVersion=8.5.6
|
||||||
|
jupiterVersion=5.9.2
|
||||||
|
@ -89,7 +89,7 @@ private fun readVarLongInfo(supplier: IntSupplier): VarLongReadResult {
|
|||||||
throw EOFException()
|
throw EOFException()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
result = (result shl 7) or (read.toLong() and 0x7F)
|
result = (result shl 7) or (read.toLong() and 0x7FL)
|
||||||
|
|
||||||
if (read and 0x80 == 0)
|
if (read and 0x80 == 0)
|
||||||
break
|
break
|
||||||
@ -154,22 +154,85 @@ private fun VarLongReadResult.fromSignedVar(): VarLongReadResult {
|
|||||||
return VarLongReadResult(-(this.value ushr 1) - 1, this.cells)
|
return VarLongReadResult(-(this.value ushr 1) - 1, this.cells)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readVarLong() = readVarLong(::readUnsignedByte)
|
fun RandomAccessFile.readVarLong() = readVarLong(::readUnsignedByte)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readVarInt() = readVarInt(::readUnsignedByte)
|
fun RandomAccessFile.readVarInt() = readVarInt(::readUnsignedByte)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readVarLongInfo() = readVarLongInfo(::readUnsignedByte)
|
fun RandomAccessFile.readVarLongInfo() = readVarLongInfo(::readUnsignedByte)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readVarIntInfo() = readVarIntInfo(::readUnsignedByte)
|
fun RandomAccessFile.readVarIntInfo() = readVarIntInfo(::readUnsignedByte)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readVarLong() = readVarLong(::read)
|
fun InputStream.readVarLong() = readVarLong(::read)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readVarInt() = readVarInt(::read)
|
fun InputStream.readVarInt() = readVarInt(::read)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readVarLongInfo() = readVarLongInfo(::read)
|
fun InputStream.readVarLongInfo() = readVarLongInfo(::read)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readVarIntInfo() = readVarIntInfo(::read)
|
fun InputStream.readVarIntInfo() = readVarIntInfo(::read)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readSignedVarLong() = readVarLong(::readUnsignedByte).fromSignedVar()
|
fun RandomAccessFile.readSignedVarLong() = readVarLong(::readUnsignedByte).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readSignedVarInt() = readVarInt(::readUnsignedByte).fromSignedVar()
|
fun RandomAccessFile.readSignedVarInt() = readVarInt(::readUnsignedByte).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readSignedVarLongInfo() = readVarLongInfo(::readUnsignedByte).fromSignedVar()
|
fun RandomAccessFile.readSignedVarLongInfo() = readVarLongInfo(::readUnsignedByte).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.readSignedVarIntInfo() = readVarIntInfo(::readUnsignedByte).fromSignedVar()
|
fun RandomAccessFile.readSignedVarIntInfo() = readVarIntInfo(::readUnsignedByte).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readSignedVarLong() = readVarLong(::read).fromSignedVar()
|
fun InputStream.readSignedVarLong() = readVarLong(::read).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readSignedVarInt() = readVarInt(::read).fromSignedVar()
|
fun InputStream.readSignedVarInt() = readVarInt(::read).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readSignedVarLongInfo() = readVarLongInfo(::read).fromSignedVar()
|
fun InputStream.readSignedVarLongInfo() = readVarLongInfo(::read).fromSignedVar()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun InputStream.readSignedVarIntInfo() = readVarIntInfo(::read).fromSignedVar()
|
fun InputStream.readSignedVarIntInfo() = readVarIntInfo(::read).fromSignedVar()
|
||||||
|
|
||||||
fun InputStream.readBinaryString(): String {
|
fun InputStream.readBinaryString(): String {
|
||||||
|
@ -83,22 +83,25 @@ fun OutputStream.writeFloat(value: Float) = writeInt(value.toBits())
|
|||||||
fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits())
|
fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits())
|
||||||
|
|
||||||
private fun writeVarLong(write: IntConsumer, value: Long): Int {
|
private fun writeVarLong(write: IntConsumer, value: Long): Int {
|
||||||
var value = value
|
var length = 9
|
||||||
var i = 0
|
|
||||||
|
|
||||||
do {
|
while (length > 0) {
|
||||||
val toWrite = (value and 0x7F).toInt()
|
val octetsPresent = (value ushr (length * 7)) and 0x7FL
|
||||||
value = value ushr 7
|
|
||||||
|
|
||||||
if (value == 0L)
|
if (octetsPresent != 0L) {
|
||||||
write.accept(toWrite)
|
break
|
||||||
else
|
} else {
|
||||||
write.accept(toWrite or 0x80)
|
length--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i++
|
for (octet in length downTo 1) {
|
||||||
} while (value != 0L)
|
write.accept(((value ushr (octet * 7)) and 0x7FL).toInt() or 0x80)
|
||||||
|
}
|
||||||
|
|
||||||
return i
|
write.accept((value and 0x7FL).toInt())
|
||||||
|
|
||||||
|
return length + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeVarInt(write: IntConsumer, value: Int): Int {
|
private fun writeVarInt(write: IntConsumer, value: Int): Int {
|
||||||
@ -119,14 +122,45 @@ private fun Long.toSignedVar(): Long {
|
|||||||
return ((-this - 1) shl 1) or 1L
|
return ((-this - 1) shl 1) or 1L
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.writeVarLong(value: Long) = writeVarLong(::write, value)
|
fun RandomAccessFile.writeVarLong(value: Long) = writeVarLong(::write, value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.writeVarInt(value: Int) = writeVarInt(::write, value)
|
fun RandomAccessFile.writeVarInt(value: Int) = writeVarInt(::write, value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun OutputStream.writeVarLong(value: Long) = writeVarLong(::write, value)
|
fun OutputStream.writeVarLong(value: Long) = writeVarLong(::write, value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes unsigned variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun OutputStream.writeVarInt(value: Int) = writeVarInt(::write, value)
|
fun OutputStream.writeVarInt(value: Int) = writeVarInt(::write, value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.writeSignedVarLong(value: Long) = writeVarLong(::write, value.toSignedVar())
|
fun RandomAccessFile.writeSignedVarLong(value: Long) = writeVarLong(::write, value.toSignedVar())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun RandomAccessFile.writeSignedVarInt(value: Int) = writeVarInt(::write, value.toSignedVar())
|
fun RandomAccessFile.writeSignedVarInt(value: Int) = writeVarInt(::write, value.toSignedVar())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun OutputStream.writeSignedVarLong(value: Long) = writeVarLong(::write, value.toSignedVar())
|
fun OutputStream.writeSignedVarLong(value: Long) = writeVarLong(::write, value.toSignedVar())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes signed variable length integer, with Big-endian byte order
|
||||||
|
*/
|
||||||
fun OutputStream.writeSignedVarInt(value: Int) = writeVarInt(::write, value.toSignedVar())
|
fun OutputStream.writeSignedVarInt(value: Int) = writeVarInt(::write, value.toSignedVar())
|
||||||
|
|
||||||
fun OutputStream.writeBinaryString(input: String) {
|
fun OutputStream.writeBinaryString(input: String) {
|
||||||
|
38
src/test/kotlin/ru/dbotthepony/kommons/test/StreamTests.kt
Normal file
38
src/test/kotlin/ru/dbotthepony/kommons/test/StreamTests.kt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package ru.dbotthepony.kommons.test
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||||
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import ru.dbotthepony.kommons.io.readVarInt
|
||||||
|
import ru.dbotthepony.kommons.io.readVarIntInfo
|
||||||
|
import ru.dbotthepony.kommons.io.writeVarInt
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
object StreamTests {
|
||||||
|
private fun readWrite(value: Int) {
|
||||||
|
val output = FastByteArrayOutputStream()
|
||||||
|
val input = FastByteArrayInputStream(output.array, 0, output.length)
|
||||||
|
val r = input.readVarIntInfo()
|
||||||
|
assertEquals(value, r.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun varInts() {
|
||||||
|
readWrite(0)
|
||||||
|
readWrite(1)
|
||||||
|
readWrite(2)
|
||||||
|
readWrite(3)
|
||||||
|
readWrite(63)
|
||||||
|
readWrite(64)
|
||||||
|
readWrite(65)
|
||||||
|
readWrite(120)
|
||||||
|
readWrite(121)
|
||||||
|
readWrite(126)
|
||||||
|
readWrite(127)
|
||||||
|
readWrite(128)
|
||||||
|
readWrite(129)
|
||||||
|
readWrite(254)
|
||||||
|
readWrite(255)
|
||||||
|
readWrite(256)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user