172 lines
2.9 KiB
Kotlin
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)
|
|
}
|