Move stream extensions from stream codecs to friendly streams

This commit is contained in:
DBotThePony 2023-07-26 11:32:48 +07:00
parent b1eb99198a
commit 7c2d446563
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 169 additions and 168 deletions

View File

@ -14,6 +14,7 @@ import net.minecraftforge.registries.ForgeRegistry
import java.io.* import java.io.*
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
import kotlin.math.absoluteValue
// But seriously, Mojang, why would you need to derive from ByteBuf directly, when you can implement // But seriously, Mojang, why would you need to derive from ByteBuf directly, when you can implement
// your own InputStream and OutputStream, since ByteBuf is meant to be operated on most time like a stream anyway? // your own InputStream and OutputStream, since ByteBuf is meant to be operated on most time like a stream anyway?
@ -158,3 +159,171 @@ fun <S : InputStream, V, C : MutableCollection<V>> S.readCollection(reader: S.()
} }
fun <S : InputStream, V> S.readCollection(reader: S.() -> V) = readCollection(reader, ::ArrayList) fun <S : InputStream, V> S.readCollection(reader: S.() -> V) = readCollection(reader, ::ArrayList)
fun OutputStream.writeInt(value: Int) {
if (this is DataOutput) {
writeInt(value)
return
}
write(value ushr 24)
write(value ushr 16)
write(value ushr 8)
write(value)
}
fun InputStream.readInt(): Int {
if (this is DataInput) {
return readInt()
}
return (read() shl 24) or (read() shl 16) or (read() shl 8) or read()
}
fun OutputStream.writeLong(value: Long) {
if (this is DataOutput) {
writeLong(value)
return
}
write((value ushr 48).toInt())
write((value ushr 40).toInt())
write((value ushr 32).toInt())
write((value ushr 24).toInt())
write((value ushr 16).toInt())
write((value ushr 8).toInt())
write(value.toInt())
}
fun InputStream.readLong(): Long {
if (this is DataInput) {
return readLong()
}
return (read().toLong() shl 48) or
(read().toLong() shl 40) or
(read().toLong() shl 32) or
(read().toLong() shl 24) or
(read().toLong() shl 16) or
(read().toLong() shl 8) or
read().toLong()
}
fun OutputStream.writeFloat(value: Float) = writeInt(value.toBits())
fun InputStream.readFloat() = Float.fromBits(readInt())
fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits())
fun InputStream.readDouble() = Double.fromBits(readLong())
fun InputStream.readVarIntLE(sizeLimit: NbtAccounter? = null): Int {
sizeLimit?.accountBytes(1L)
val readFirst = read()
if (readFirst < 0) {
throw NoSuchElementException("Reached end of stream")
}
if (readFirst and 64 == 0) {
return if (readFirst and 128 != 0) -(readFirst and 63) else readFirst and 63
}
var result = 0
var nextBit = readFirst and 64
var read = readFirst and 63
var i = 0
while (nextBit != 0) {
result = result or (read shl i)
sizeLimit?.accountBytes(1L)
read = read()
if (read < 0) {
throw NoSuchElementException("Reached end of stream")
}
nextBit = read and 128
read = read and 127
if (i == 0)
i = 6
else
i += 7
}
result = result or (read shl i)
return if (readFirst and 128 != 0) -result else result
}
fun OutputStream.writeVarIntLE(value: Int) {
write((if (value < 0) 128 else 0) or (if (value in -63 .. 63) 0 else 64) or (value.absoluteValue and 63))
var written = value.absoluteValue ushr 6
while (written != 0) {
write((written and 127) or (if (written >= 128) 128 else 0))
written = written ushr 7
}
}
fun InputStream.readVarLongLE(sizeLimit: NbtAccounter? = null): Long {
sizeLimit?.accountBytes(1L)
val readFirst = read()
if (readFirst < 0) {
throw NoSuchElementException("Reached end of stream")
}
if (readFirst and 64 == 0) {
return if (readFirst and 128 != 0) -(readFirst and 63).toLong() else (readFirst and 63).toLong()
}
var result = 0L
var nextBit = readFirst and 64
var read = readFirst and 63
var i = 0
while (nextBit != 0) {
result = result or (read shl i).toLong()
sizeLimit?.accountBytes(1L)
read = read()
if (read < 0) {
throw NoSuchElementException("Reached end of stream")
}
nextBit = read and 128
read = read and 127
if (i == 0)
i = 6
else
i += 7
}
result = result or (read shl i).toLong()
return if (readFirst and 128 != 0) -result else result
}
fun OutputStream.writeVarLongLE(value: Long) {
write((if (value < 0L) 128 else 0) or (if (value in -63 .. 63) 0 else 64) or (value.absoluteValue and 63).toInt())
var written = value.absoluteValue ushr 6
while (written != 0L) {
write((written and 127).toInt() or (if (written >= 128) 128 else 0))
written = written ushr 7
}
}
fun InputStream.readBinaryString(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): String {
val size = readVarIntLE()
require(size >= 0) { "Negative payload size: $size" }
sizeLimit.accountBytes(size.toLong())
val bytes = ByteArray(size)
read(bytes)
return bytes.decodeToString()
}
fun OutputStream.writeBinaryString(input: String) {
val bytes = input.encodeToByteArray()
writeVarIntLE(bytes.size)
write(bytes)
}

View File

@ -197,171 +197,3 @@ class EnumValueCodec<V : Enum<V>>(clazz: Class<out V>) : IStreamCodec<V>, Codec<
fun <E : Enum<E>> Class<E>.codec() = EnumValueCodec(this) fun <E : Enum<E>> Class<E>.codec() = EnumValueCodec(this)
fun <E : Enum<E>> KClass<E>.codec() = EnumValueCodec(this.java) fun <E : Enum<E>> KClass<E>.codec() = EnumValueCodec(this.java)
fun OutputStream.writeInt(value: Int) {
if (this is DataOutput) {
writeInt(value)
return
}
write(value ushr 24)
write(value ushr 16)
write(value ushr 8)
write(value)
}
fun InputStream.readInt(): Int {
if (this is DataInput) {
return readInt()
}
return (read() shl 24) or (read() shl 16) or (read() shl 8) or read()
}
fun OutputStream.writeLong(value: Long) {
if (this is DataOutput) {
writeLong(value)
return
}
write((value ushr 48).toInt())
write((value ushr 40).toInt())
write((value ushr 32).toInt())
write((value ushr 24).toInt())
write((value ushr 16).toInt())
write((value ushr 8).toInt())
write(value.toInt())
}
fun InputStream.readLong(): Long {
if (this is DataInput) {
return readLong()
}
return (read().toLong() shl 48) or
(read().toLong() shl 40) or
(read().toLong() shl 32) or
(read().toLong() shl 24) or
(read().toLong() shl 16) or
(read().toLong() shl 8) or
read().toLong()
}
fun OutputStream.writeFloat(value: Float) = writeInt(value.toBits())
fun InputStream.readFloat() = Float.fromBits(readInt())
fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits())
fun InputStream.readDouble() = Double.fromBits(readLong())
fun InputStream.readVarIntLE(sizeLimit: NbtAccounter? = null): Int {
sizeLimit?.accountBytes(1L)
val readFirst = read()
if (readFirst < 0) {
throw NoSuchElementException("Reached end of stream")
}
if (readFirst and 64 == 0) {
return if (readFirst and 128 != 0) -(readFirst and 63) else readFirst and 63
}
var result = 0
var nextBit = readFirst and 64
var read = readFirst and 63
var i = 0
while (nextBit != 0) {
result = result or (read shl i)
sizeLimit?.accountBytes(1L)
read = read()
if (read < 0) {
throw NoSuchElementException("Reached end of stream")
}
nextBit = read and 128
read = read and 127
if (i == 0)
i = 6
else
i += 7
}
result = result or (read shl i)
return if (readFirst and 128 != 0) -result else result
}
fun OutputStream.writeVarIntLE(value: Int) {
write((if (value < 0) 128 else 0) or (if (value in -63 .. 63) 0 else 64) or (value.absoluteValue and 63))
var written = value.absoluteValue ushr 6
while (written != 0) {
write((written and 127) or (if (written >= 128) 128 else 0))
written = written ushr 7
}
}
fun InputStream.readVarLongLE(sizeLimit: NbtAccounter? = null): Long {
sizeLimit?.accountBytes(1L)
val readFirst = read()
if (readFirst < 0) {
throw NoSuchElementException("Reached end of stream")
}
if (readFirst and 64 == 0) {
return if (readFirst and 128 != 0) -(readFirst and 63).toLong() else (readFirst and 63).toLong()
}
var result = 0L
var nextBit = readFirst and 64
var read = readFirst and 63
var i = 0
while (nextBit != 0) {
result = result or (read shl i).toLong()
sizeLimit?.accountBytes(1L)
read = read()
if (read < 0) {
throw NoSuchElementException("Reached end of stream")
}
nextBit = read and 128
read = read and 127
if (i == 0)
i = 6
else
i += 7
}
result = result or (read shl i).toLong()
return if (readFirst and 128 != 0) -result else result
}
fun OutputStream.writeVarLongLE(value: Long) {
write((if (value < 0L) 128 else 0) or (if (value in -63 .. 63) 0 else 64) or (value.absoluteValue and 63).toInt())
var written = value.absoluteValue ushr 6
while (written != 0L) {
write((written and 127).toInt() or (if (written >= 128) 128 else 0))
written = written ushr 7
}
}
fun InputStream.readBinaryString(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): String {
val size = readVarIntLE()
require(size >= 0) { "Negative payload size: $size" }
sizeLimit.accountBytes(size.toLong())
val bytes = ByteArray(size)
read(bytes)
return bytes.decodeToString()
}
fun OutputStream.writeBinaryString(input: String) {
val bytes = input.encodeToByteArray()
writeVarIntLE(bytes.size)
write(bytes)
}