KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/io/Ext.kt
2022-07-28 21:44:04 +07:00

172 lines
2.9 KiB
Kotlin

package ru.dbotthepony.kstarbound.io
import it.unimi.dsi.fastutil.bytes.ByteArrayList
import java.io.DataInputStream
import java.io.IOException
import java.io.InputStream
import java.io.RandomAccessFile
/**
* Читает Variable Length Integer как Long
*/
fun RandomAccessFile.readVarLong(): Long {
var result = 0L
var read = read()
while (true) {
result = (result shl 7) or (read.toLong() and 0x7FL)
if (read and 0x80 == 0) {
break
}
read = read()
}
return result
}
data class VarIntReadResult(val value: Int, val cells: Int)
/**
* Читает Variable Length Integer как Int
*/
fun RandomAccessFile.readVarInt(): Int {
var result = 0
var read = read()
while (true) {
result = (result shl 7) or (read and 0x7F)
if (read and 0x80 == 0) {
break
}
read = read()
}
return result
}
/**
* Читает Variable Length Integer как Int
*/
fun RandomAccessFile.readVarIntInfo(): VarIntReadResult {
var result = 0
var read = read()
var i = 1
while (true) {
result = (result shl 7) or (read and 0x7F)
if (read and 0x80 == 0) {
break
}
read = read()
i++
}
return VarIntReadResult(result, i)
}
/**
* Читает Variable Length Integer как Long
*/
fun InputStream.readVarLong(): Long {
var result = 0L
var read = read()
while (true) {
result = (result shl 7) or (read.toLong() and 0x7FL)
if (read and 0x80 == 0) {
break
}
read = read()
}
return result
}
/**
* Читает Variable Length Integer как Int
*/
fun InputStream.readVarInt(): Int {
var result = 0
var read = read()
while (true) {
result = (result shl 7) or (read and 0x7F)
if (read and 0x80 == 0) {
break
}
read = read()
}
return result
}
fun RandomAccessFile.readASCIIString(length: Int): String {
require(length >= 0) { "Invalid length $length" }
val bytes = ByteArray(length)
try {
readFully(bytes)
} catch(err: Throwable) {
throw IOException("Tried to read string with length of $length", err)
}
return bytes.toString(Charsets.UTF_8)
}
fun InputStream.readASCIIString(length: Int): String {
require(length >= 0) { "Invalid length $length" }
val bytes = ByteArray(length)
try {
val read = read(bytes)
require(read == bytes.size) { "Read $read, expected ${bytes.size}" }
} catch(err: Throwable) {
throw IOException("Tried to read string with length of $length", err)
}
return bytes.toString(Charsets.UTF_8)
}
fun RandomAccessFile.readCString(): String {
val bytes = ByteArrayList()
var read = read()
while (read != 0) {
bytes.add(read.toByte())
read = read()
}
return ByteArray(bytes.size).also {
for (i in it.indices) {
it[i] = bytes.getByte(i)
}
}.toString(Charsets.UTF_8)
}
fun InputStream.readCString(): String {
val bytes = ByteArrayList()
var read = read()
while (read != 0) {
bytes.add(read.toByte())
read = read()
}
return ByteArray(bytes.size).also {
for (i in it.indices) {
it[i] = bytes.getByte(i)
}
}.toString(Charsets.UTF_8)
}