Fixed leaked byte packets in io
This commit is contained in:
parent
ade4eec96e
commit
33c8e7088e
@ -1,9 +1,6 @@
|
|||||||
package hep.dataforge.io
|
package hep.dataforge.io
|
||||||
|
|
||||||
import kotlinx.io.core.ByteReadPacket
|
import kotlinx.io.core.*
|
||||||
import kotlinx.io.core.Input
|
|
||||||
import kotlinx.io.core.buildPacket
|
|
||||||
import kotlinx.io.core.readBytes
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +42,7 @@ fun Binary.toBytes(): ByteArray = read {
|
|||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
fun RandomAccessBinary.readPacket(from: UInt, size: UInt): ByteReadPacket = read(from, size) {
|
fun RandomAccessBinary.readPacket(from: UInt, size: UInt): ByteReadPacket = read(from, size) {
|
||||||
ByteReadPacket(this.readBytes())
|
buildPacket { copyTo(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
@ -65,7 +62,9 @@ inline class ArrayBinary(val array: ByteArray) : RandomAccessBinary {
|
|||||||
|
|
||||||
override fun <R> read(from: UInt, size: UInt, block: Input.() -> R): R {
|
override fun <R> read(from: UInt, size: UInt, block: Input.() -> R): R {
|
||||||
val theSize = min(size, array.size.toUInt() - from)
|
val theSize = min(size, array.size.toUInt() - from)
|
||||||
return ByteReadPacket(array, from.toInt(), theSize.toInt()).block()
|
return buildPacket {
|
||||||
|
writeFully(array, from.toInt(), theSize.toInt())
|
||||||
|
}.block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ fun Meta.toBytes(format: MetaFormat = JsonMetaFormat.default): ByteReadPacket =
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun MetaFormat.parse(str: String): Meta {
|
fun MetaFormat.parse(str: String): Meta {
|
||||||
return ByteReadPacket(str.toByteArray()).readObject()
|
return buildPacket { writeText(str) }.readObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MetaFormatFactory.parse(str: String): Meta = invoke().parse(str)
|
fun MetaFormatFactory.parse(str: String): Meta = invoke().parse(str)
|
||||||
|
@ -7,6 +7,7 @@ import hep.dataforge.meta.string
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
import kotlinx.io.charsets.Charsets
|
||||||
import kotlinx.io.core.*
|
import kotlinx.io.core.*
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
@ -30,10 +31,12 @@ class TaggedEnvelopeFormat(
|
|||||||
|
|
||||||
override fun Output.writeObject(obj: Envelope) {
|
override fun Output.writeObject(obj: Envelope) {
|
||||||
val metaBytes = metaFormat.writeBytes(obj.meta)
|
val metaBytes = metaFormat.writeBytes(obj.meta)
|
||||||
val tag = Tag(metaFormatKey, metaBytes.size.toUInt(), obj.data?.size ?: 0.toULong())
|
val tag = Tag(metaFormatKey, metaBytes.size.toUInt() + 2u, obj.data?.size ?: 0.toULong())
|
||||||
writePacket(tag.toBytes())
|
writePacket(tag.toBytes())
|
||||||
writeFully(metaBytes)
|
writeFully(metaBytes)
|
||||||
|
writeText("\r\n")
|
||||||
obj.data?.read { copyTo(this@writeObject) }
|
obj.data?.read { copyTo(this@writeObject) }
|
||||||
|
flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,14 +95,14 @@ class TaggedEnvelopeFormat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Input.readTag(): Tag {
|
private fun Input.readTag(): Tag {
|
||||||
val start = readTextExactBytes(2)
|
val start = readTextExactBytes(2, charset = Charsets.ISO_8859_1)
|
||||||
if (start != START_SEQUENCE) error("The input is not an envelope")
|
if (start != START_SEQUENCE) error("The input is not an envelope")
|
||||||
val version = readTextExactBytes(4)
|
val version = readTextExactBytes(4, charset = Charsets.ISO_8859_1)
|
||||||
if (version != VERSION) error("Wrong version of DataForge: expected $VERSION but found $version")
|
if (version != VERSION) error("Wrong version of DataForge: expected $VERSION but found $version")
|
||||||
val metaFormatKey = readShort()
|
val metaFormatKey = readShort()
|
||||||
val metaLength = readUInt()
|
val metaLength = readUInt()
|
||||||
val dataLength = readULong()
|
val dataLength = readULong()
|
||||||
val end = readTextExactBytes(4)
|
val end = readTextExactBytes(4, charset = Charsets.ISO_8859_1)
|
||||||
if (end != END_SEQUENCE) error("The input is not an envelope")
|
if (end != END_SEQUENCE) error("The input is not an envelope")
|
||||||
return Tag(metaFormatKey, metaLength, dataLength)
|
return Tag(metaFormatKey, metaLength, dataLength)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,9 @@ class TaglessEnvelopeFormat(
|
|||||||
val metaFormat = properties[META_TYPE_PROPERTY]?.let { io.metaFormat(it) } ?: JsonMetaFormat.default
|
val metaFormat = properties[META_TYPE_PROPERTY]?.let { io.metaFormat(it) } ?: JsonMetaFormat.default
|
||||||
val metaSize = properties.get(META_LENGTH_PROPERTY)?.toInt()
|
val metaSize = properties.get(META_LENGTH_PROPERTY)?.toInt()
|
||||||
meta = if (metaSize != null) {
|
meta = if (metaSize != null) {
|
||||||
val metaPacket = ByteReadPacket(readBytes(metaSize))
|
val metaPacket = buildPacket {
|
||||||
|
writeFully(readBytes(metaSize))
|
||||||
|
}
|
||||||
metaFormat.run { metaPacket.readObject() }
|
metaFormat.run { metaPacket.readObject() }
|
||||||
} else {
|
} else {
|
||||||
metaFormat.run {
|
metaFormat.run {
|
||||||
@ -126,11 +128,13 @@ class TaglessEnvelopeFormat(
|
|||||||
|
|
||||||
val metaSize = properties.get(META_LENGTH_PROPERTY)?.toInt()
|
val metaSize = properties.get(META_LENGTH_PROPERTY)?.toInt()
|
||||||
meta = if (metaSize != null) {
|
meta = if (metaSize != null) {
|
||||||
val metaPacket = ByteReadPacket(readBytes(metaSize))
|
val metaPacket = buildPacket {
|
||||||
|
writeFully(readBytes(metaSize))
|
||||||
|
}
|
||||||
offset += metaSize.toUInt()
|
offset += metaSize.toUInt()
|
||||||
metaFormat.run { metaPacket.readObject() }
|
metaFormat.run { metaPacket.readObject() }
|
||||||
} else {
|
} else {
|
||||||
error("Can't partially read an envelope with undefined meta size")
|
error("Can't partially read an envelope with undefined meta size")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package hep.dataforge.io
|
package hep.dataforge.io
|
||||||
|
|
||||||
import kotlinx.io.core.ByteReadPacket
|
|
||||||
import kotlinx.io.core.Input
|
import kotlinx.io.core.Input
|
||||||
|
import kotlinx.io.core.buildPacket
|
||||||
import java.nio.channels.FileChannel
|
import java.nio.channels.FileChannel
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -17,7 +17,7 @@ class FileBinary(val path: Path, private val offset: UInt = 0u, size: ULong? = n
|
|||||||
FileChannel.open(path, StandardOpenOption.READ).use {
|
FileChannel.open(path, StandardOpenOption.READ).use {
|
||||||
val theSize: UInt = min(size, Files.size(path).toUInt() - offset)
|
val theSize: UInt = min(size, Files.size(path).toUInt() - offset)
|
||||||
val buffer = it.map(FileChannel.MapMode.READ_ONLY, (from + offset).toLong(), theSize.toLong())
|
val buffer = it.map(FileChannel.MapMode.READ_ONLY, (from + offset).toLong(), theSize.toLong())
|
||||||
return ByteReadPacket(buffer).block()
|
return buildPacket { writeFully(buffer) }.block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class FileEnvelope internal constructor(val path: Path, val format: EnvelopeForm
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
val input = Files.newByteChannel(path, StandardOpenOption.READ).asInput()
|
val input = Files.newByteChannel(path, StandardOpenOption.READ).asInput()
|
||||||
partialEnvelope = format.run { input.readPartial() }
|
partialEnvelope = format.run { input.use { it.readPartial()} }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val meta: Meta get() = partialEnvelope.meta
|
override val meta: Meta get() = partialEnvelope.meta
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package hep.dataforge.io
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import java.nio.file.Files
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class FileBinaryTest {
|
||||||
|
val envelope = Envelope {
|
||||||
|
meta {
|
||||||
|
"a" put "AAA"
|
||||||
|
"b" put 22.2
|
||||||
|
}
|
||||||
|
dataType = "hep.dataforge.test"
|
||||||
|
dataID = "myData" // добавил только что
|
||||||
|
data {
|
||||||
|
writeDouble(16.7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSize() {
|
||||||
|
val binary = envelope.data
|
||||||
|
assertEquals(binary?.size?.toInt(), binary?.toBytes()?.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFileData(){
|
||||||
|
val dataFile = Files.createTempFile("dataforge_test_bin", ".bin")
|
||||||
|
dataFile.toFile().writeText("This is my binary")
|
||||||
|
val envelopeFromFile = Envelope {
|
||||||
|
meta {
|
||||||
|
"a" put "AAA"
|
||||||
|
"b" put 22.2
|
||||||
|
}
|
||||||
|
dataType = "hep.dataforge.satellite"
|
||||||
|
dataID = "cellDepositTest" // добавил только что
|
||||||
|
data = dataFile.asBinary()
|
||||||
|
}
|
||||||
|
val binary = envelopeFromFile.data!!
|
||||||
|
println(binary.toBytes().size)
|
||||||
|
assertEquals(binary.size.toInt(), binary.toBytes().size)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFileDataSizeRewriting() {
|
||||||
|
println(System.getProperty("user.dir"))
|
||||||
|
val tmpPath = Files.createTempFile("dataforge_test", ".df")
|
||||||
|
Global.io.writeEnvelopeFile(tmpPath, envelope)
|
||||||
|
|
||||||
|
val binary = Global.io.readEnvelopeFile(tmpPath).data!!
|
||||||
|
assertEquals(binary.size.toInt(), binary.toBytes().size)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user