From e7cbe596a224320f7c1ab7ce48414103e63cb554 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 3 Feb 2024 20:48:00 +0700 Subject: [PATCH] More stream extensions --- gradle.properties | 2 +- .../kommons/io/InputStreamUtils.kt | 53 ++++++++++++++++++- .../kommons/io/OutputStreamUtils.kt | 11 ++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4f8a40c..261b2f1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official specifyKotlinAsDependency=false projectGroup=ru.dbotthepony.kommons -projectVersion=1.7.2 +projectVersion=1.7.3 guavaDepVersion=33.0.0 gsonDepVersion=2.8.9 diff --git a/src/main/kotlin/ru/dbotthepony/kommons/io/InputStreamUtils.kt b/src/main/kotlin/ru/dbotthepony/kommons/io/InputStreamUtils.kt index 3e6014f..9cb5708 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/io/InputStreamUtils.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/io/InputStreamUtils.kt @@ -1,11 +1,15 @@ package ru.dbotthepony.kommons.io +import it.unimi.dsi.fastutil.bytes.ByteArrayList import java.io.DataInput +import java.io.IOException import java.io.InputStream import java.io.RandomAccessFile import java.math.BigDecimal import java.math.BigInteger +import java.util.* import java.util.function.IntSupplier +import kotlin.collections.ArrayList fun InputStream.readBigDecimal(): BigDecimal { val scale = readInt() @@ -146,6 +150,53 @@ fun InputStream.readBinaryString(): String { val size = readVarInt() require(size >= 0) { "Negative payload size: $size" } val bytes = ByteArray(size) - read(bytes) + check(read(bytes) == size) { "Reached end of stream" } return bytes.decodeToString() } + +fun RandomAccessFile.readString(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.readString(length: Int, allowSmaller: Boolean = false): String { + require(length >= 0) { "Invalid length $length" } + + val bytes = ByteArray(length) + + try { + val read = read(bytes) + + if (!allowSmaller) + require(read == bytes.size) { "Read $read bytes, expected ${bytes.size}" } + } catch(err: Throwable) { + throw IOException("Tried to read string with length of $length", err) + } + + return bytes.toString(Charsets.UTF_8) +} + +fun InputStream.readUTF(): String { + val bytes = ByteArrayList() + var read = read() + + while (read != 0) { + bytes.add(read.toByte()) + read = read() + } + + return String(bytes.toByteArray()) +} + +fun InputStream.readUUID(): UUID { + return UUID(readLong(), readLong()) +} diff --git a/src/main/kotlin/ru/dbotthepony/kommons/io/OutputStreamUtils.kt b/src/main/kotlin/ru/dbotthepony/kommons/io/OutputStreamUtils.kt index 47dbb27..af14f2e 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/io/OutputStreamUtils.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/io/OutputStreamUtils.kt @@ -4,6 +4,7 @@ import java.io.DataOutput import java.io.OutputStream import java.io.RandomAccessFile import java.math.BigDecimal +import java.util.* import java.util.function.IntConsumer fun OutputStream.writeBigDecimal(value: BigDecimal) { @@ -103,3 +104,13 @@ fun OutputStream.writeBinaryString(input: String) { writeVarInt(bytes.size) write(bytes) } + +fun OutputStream.writeUTF(value: String) { + write(value.toByteArray().also { check(!it.any { it.toInt() == 0 }) { "Provided UTF string contains NUL" } }) + write(0) +} + +fun OutputStream.writeUUID(value: UUID) { + writeLong(value.mostSignificantBits) + writeLong(value.leastSignificantBits) +}