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) }