Writing and reading maps, (k)optionals
This commit is contained in:
parent
31b1278cc2
commit
e150738f37
@ -4,7 +4,7 @@ kotlin.code.style=official
|
||||
specifyKotlinAsDependency=false
|
||||
|
||||
projectGroup=ru.dbotthepony.kommons
|
||||
projectVersion=2.1.1
|
||||
projectVersion=2.1.2
|
||||
|
||||
guavaDepVersion=33.0.0
|
||||
gsonDepVersion=2.8.9
|
||||
|
@ -1,7 +1,9 @@
|
||||
package ru.dbotthepony.kommons.io
|
||||
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||
import ru.dbotthepony.kommons.math.Decimal
|
||||
import ru.dbotthepony.kommons.util.KOptional
|
||||
import java.io.DataInput
|
||||
import java.io.EOFException
|
||||
import java.io.IOException
|
||||
@ -218,4 +220,36 @@ fun InputStream.readDecimal(): Decimal {
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return Decimal.fromByteArray(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : InputStream, M : MutableMap<K, V>, K, V> S.readMap(keyReader: S.() -> K, valueReader: S.() -> V, constructor: (Int) -> M): M {
|
||||
val size = readVarInt()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
val map = constructor(size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
map[keyReader(this)] = valueReader(this)
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
fun <S : InputStream, K, V> S.readMap(keyReader: S.() -> K, valueReader: S.() -> V): Object2ObjectOpenHashMap<K, V> {
|
||||
return readMap(keyReader, valueReader, ::Object2ObjectOpenHashMap)
|
||||
}
|
||||
|
||||
fun <S : InputStream, V> S.readKOptional(reader: S.() -> V): KOptional<V> {
|
||||
if (read() == 0) {
|
||||
return KOptional.empty()
|
||||
} else {
|
||||
return KOptional(reader(this))
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : InputStream, V : Any> S.readOptional(reader: S.() -> V): Optional<V> {
|
||||
if (read() == 0) {
|
||||
return Optional.empty()
|
||||
} else {
|
||||
return Optional.of(reader(this))
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import ru.dbotthepony.kommons.util.IStruct4f
|
||||
import ru.dbotthepony.kommons.util.IStruct4i
|
||||
import ru.dbotthepony.kommons.util.IStruct4l
|
||||
import ru.dbotthepony.kommons.util.IStruct4s
|
||||
import ru.dbotthepony.kommons.util.KOptional
|
||||
import java.io.DataOutput
|
||||
import java.io.OutputStream
|
||||
import java.io.RandomAccessFile
|
||||
@ -257,3 +258,28 @@ fun OutputStream.writeDecimal(value: Decimal) {
|
||||
writeVarInt(bytes.size)
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun <S : OutputStream, K, V> S.writeMap(map: Map<K, V>, keyWriter: S.(K) -> Unit, valueWriter: S.(V) -> Unit) {
|
||||
writeVarInt(map.size)
|
||||
|
||||
for ((k, v) in map.entries) {
|
||||
keyWriter(this, k)
|
||||
valueWriter(this, v)
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : OutputStream, V> S.writeKOptional(value: KOptional<V>, writer: S.(V) -> Unit) {
|
||||
write(if (value.isPresent) 1 else 0)
|
||||
|
||||
if (value.isPresent) {
|
||||
writer(this, value.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun <S : OutputStream, V : Any> S.writeOptional(value: Optional<V>, writer: S.(V) -> Unit) {
|
||||
write(if (value.isPresent) 1 else 0)
|
||||
|
||||
if (value.isPresent) {
|
||||
writer(this, value.get())
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +150,34 @@ interface StreamCodec<V> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KOptional<V>(val codec: StreamCodec<V>) : StreamCodec<ru.dbotthepony.kommons.util.KOptional<V>> {
|
||||
override fun read(stream: DataInputStream): ru.dbotthepony.kommons.util.KOptional<V> {
|
||||
return stream.readKOptional(codec::read)
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, value: ru.dbotthepony.kommons.util.KOptional<V>) {
|
||||
stream.writeKOptional(value, codec::write)
|
||||
}
|
||||
|
||||
override fun copy(value: ru.dbotthepony.kommons.util.KOptional<V>): ru.dbotthepony.kommons.util.KOptional<V> {
|
||||
return value.map(codec::copy)
|
||||
}
|
||||
}
|
||||
|
||||
class Optional<V : Any>(val codec: StreamCodec<V>) : StreamCodec<java.util.Optional<V>> {
|
||||
override fun read(stream: DataInputStream): java.util.Optional<V> {
|
||||
return stream.readOptional(codec::read)
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, value: java.util.Optional<V>) {
|
||||
stream.writeOptional(value, codec::write)
|
||||
}
|
||||
|
||||
override fun copy(value: java.util.Optional<V>): java.util.Optional<V> {
|
||||
return value.map(codec::copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val NullValueCodec = StreamCodec.Impl({ _ -> null }, { _, _ -> })
|
||||
@ -168,5 +196,35 @@ val VarLongValueCodec = StreamCodec.Impl(DataInputStream::readSignedVarLong, Dat
|
||||
val BinaryStringCodec = StreamCodec.Impl(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString)
|
||||
val DecimalValueCodec = StreamCodec.Impl(DataInputStream::readDecimal, DataOutputStream::writeDecimal)
|
||||
|
||||
val OptionalBooleanValueCodec = StreamCodec.Optional(BooleanValueCodec)
|
||||
val OptionalByteValueCodec = StreamCodec.Optional(ByteValueCodec)
|
||||
val OptionalShortValueCodec = StreamCodec.Optional(ShortValueCodec)
|
||||
val OptionalCharValueCodec = StreamCodec.Optional(CharValueCodec)
|
||||
val OptionalIntValueCodec = StreamCodec.Optional(IntValueCodec)
|
||||
val OptionalLongValueCodec = StreamCodec.Optional(LongValueCodec)
|
||||
val OptionalFloatValueCodec = StreamCodec.Optional(FloatValueCodec)
|
||||
val OptionalDoubleValueCodec = StreamCodec.Optional(DoubleValueCodec)
|
||||
val OptionalBigDecimalValueCodec = StreamCodec.Optional(BigDecimalValueCodec)
|
||||
val OptionalUUIDValueCodec = StreamCodec.Optional(UUIDValueCodec)
|
||||
val OptionalVarIntValueCodec = StreamCodec.Optional(VarIntValueCodec)
|
||||
val OptionalVarLongValueCodec = StreamCodec.Optional(VarLongValueCodec)
|
||||
val OptionalBinaryStringCodec = StreamCodec.Optional(BinaryStringCodec)
|
||||
val OptionalDecimalValueCodec = StreamCodec.Optional(DecimalValueCodec)
|
||||
|
||||
val KOptionalBooleanValueCodec = StreamCodec.KOptional(BooleanValueCodec)
|
||||
val KOptionalByteValueCodec = StreamCodec.KOptional(ByteValueCodec)
|
||||
val KOptionalShortValueCodec = StreamCodec.KOptional(ShortValueCodec)
|
||||
val KOptionalCharValueCodec = StreamCodec.KOptional(CharValueCodec)
|
||||
val KOptionalIntValueCodec = StreamCodec.KOptional(IntValueCodec)
|
||||
val KOptionalLongValueCodec = StreamCodec.KOptional(LongValueCodec)
|
||||
val KOptionalFloatValueCodec = StreamCodec.KOptional(FloatValueCodec)
|
||||
val KOptionalDoubleValueCodec = StreamCodec.KOptional(DoubleValueCodec)
|
||||
val KOptionalBigDecimalValueCodec = StreamCodec.KOptional(BigDecimalValueCodec)
|
||||
val KOptionalUUIDValueCodec = StreamCodec.KOptional(UUIDValueCodec)
|
||||
val KOptionalVarIntValueCodec = StreamCodec.KOptional(VarIntValueCodec)
|
||||
val KOptionalVarLongValueCodec = StreamCodec.KOptional(VarLongValueCodec)
|
||||
val KOptionalBinaryStringCodec = StreamCodec.KOptional(BinaryStringCodec)
|
||||
val KOptionalDecimalValueCodec = StreamCodec.KOptional(DecimalValueCodec)
|
||||
|
||||
fun <E : Enum<E>> Class<E>.codec() = StreamCodec.Enum(this)
|
||||
fun <E : Enum<E>> KClass<E>.codec() = StreamCodec.Enum(this.java)
|
||||
|
Loading…
Reference in New Issue
Block a user