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
|
specifyKotlinAsDependency=false
|
||||||
|
|
||||||
projectGroup=ru.dbotthepony.kommons
|
projectGroup=ru.dbotthepony.kommons
|
||||||
projectVersion=2.1.1
|
projectVersion=2.1.2
|
||||||
|
|
||||||
guavaDepVersion=33.0.0
|
guavaDepVersion=33.0.0
|
||||||
gsonDepVersion=2.8.9
|
gsonDepVersion=2.8.9
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package ru.dbotthepony.kommons.io
|
package ru.dbotthepony.kommons.io
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||||
import ru.dbotthepony.kommons.math.Decimal
|
import ru.dbotthepony.kommons.math.Decimal
|
||||||
|
import ru.dbotthepony.kommons.util.KOptional
|
||||||
import java.io.DataInput
|
import java.io.DataInput
|
||||||
import java.io.EOFException
|
import java.io.EOFException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -218,4 +220,36 @@ fun InputStream.readDecimal(): Decimal {
|
|||||||
val bytes = ByteArray(size)
|
val bytes = ByteArray(size)
|
||||||
read(bytes)
|
read(bytes)
|
||||||
return Decimal.fromByteArray(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.IStruct4i
|
||||||
import ru.dbotthepony.kommons.util.IStruct4l
|
import ru.dbotthepony.kommons.util.IStruct4l
|
||||||
import ru.dbotthepony.kommons.util.IStruct4s
|
import ru.dbotthepony.kommons.util.IStruct4s
|
||||||
|
import ru.dbotthepony.kommons.util.KOptional
|
||||||
import java.io.DataOutput
|
import java.io.DataOutput
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
@ -257,3 +258,28 @@ fun OutputStream.writeDecimal(value: Decimal) {
|
|||||||
writeVarInt(bytes.size)
|
writeVarInt(bytes.size)
|
||||||
write(bytes)
|
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 }, { _, _ -> })
|
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 BinaryStringCodec = StreamCodec.Impl(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString)
|
||||||
val DecimalValueCodec = StreamCodec.Impl(DataInputStream::readDecimal, DataOutputStream::writeDecimal)
|
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>> Class<E>.codec() = StreamCodec.Enum(this)
|
||||||
fun <E : Enum<E>> KClass<E>.codec() = StreamCodec.Enum(this.java)
|
fun <E : Enum<E>> KClass<E>.codec() = StreamCodec.Enum(this.java)
|
||||||
|
Loading…
Reference in New Issue
Block a user