diff --git a/ROADMAP.md b/ROADMAP.md index 7b67586..ede052d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,7 +5,6 @@
Show -* Port tests. * Set up code coverage. * Port benchmarks. * Set up multiplatform benchmarks. diff --git a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/ByteBufferRadAccessor.kt b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/ByteBufferRadAccessor.kt index 473d168..8e76243 100644 --- a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/ByteBufferRadAccessor.kt +++ b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/ByteBufferRadAccessor.kt @@ -5,6 +5,7 @@ package fluxo.io.rad import fluxo.io.internal.Blocking +import fluxo.io.util.checkOffsetAndCount import fluxo.io.util.toIntChecked import java.io.File import java.io.FileDescriptor @@ -50,13 +51,15 @@ public fun RadByteBufferAccessor( ): RandomAccessData = ByteBufferRad(data, offset = offset, size = size) -private fun byteBufferRad0( +private fun byteBufferMmapRad0( channel: FileChannel, offset: Long, size: Int, vararg resources: AutoCloseable, ): RandomAccessData { - val size0 = if (size == -1) (channel.size() - offset).toIntChecked() else size + val dataLength = channel.size() + val size0 = if (size == -1) (dataLength - offset).toIntChecked() else size + checkOffsetAndCount(dataLength, offset, size0.toLong()) val byteBuffer = channel.map(MapMode.READ_ONLY, offset, size0.toLong()) return ByteBufferRad(byteBuffer, offset = 0, size = size0, resources = resources) } @@ -75,7 +78,7 @@ private fun byteBufferRad0( * * @param data the underlying [FileInputStream] * @param offset the optional offset of the section - * @param size the optional length of the section + * @param size the optional length of the section. -1 means the rest of the file. * * @see java.nio.channels.FileChannel.map */ @@ -88,7 +91,7 @@ public fun RadByteBufferAccessor( size: Int = -1, ): RandomAccessData { val channel = data.channel - return byteBufferRad0(channel, offset = offset, size = size, channel, data) + return byteBufferMmapRad0(channel, offset = offset, size = size, channel, data) } /** @@ -105,7 +108,7 @@ public fun RadByteBufferAccessor( * * @param data the underlying [FileChannel] * @param offset the offset of the section - * @param size the length of the section + * @param size the optional length of the section. -1 means the rest of the file. * * @see java.nio.channels.FileChannel.map */ @@ -116,7 +119,7 @@ public fun RadByteBufferAccessor( data: FileChannel, offset: Long = 0L, size: Int = -1, -): RandomAccessData = byteBufferRad0(data, offset = offset, size = size, data) +): RandomAccessData = byteBufferMmapRad0(data, offset = offset, size = size, data) /** * Creates a new memory-mapping [ByteBuffer]-based [RandomAccessData] instance @@ -132,9 +135,7 @@ public fun RadByteBufferAccessor( * * @param data the underlying [File] * @param offset the offset of the section - * @param size the length of the section - * - * @TODO: Would it be better to use [FileChannel.size] instead of [File.length]? + * @param size the optional length of the section. -1 means the rest of the file. * * @see java.nio.channels.FileChannel.map */ @@ -144,11 +145,11 @@ public fun RadByteBufferAccessor( public fun RadByteBufferAccessor( data: File, offset: Long = 0L, - size: Int = (data.length() - offset).toIntChecked(), + size: Int = -1, ): RandomAccessData { val stream = FileInputStream(data) val channel = stream.channel - return byteBufferRad0(channel, offset = offset, size = size, channel, stream) + return byteBufferMmapRad0(channel, offset = offset, size = size, channel, stream) } /** @@ -165,7 +166,7 @@ public fun RadByteBufferAccessor( * * @param data the underlying [FileDescriptor] * @param offset the offset of the section - * @param size the length of the section + * @param size the optional length of the section. -1 means the rest of the file. * * @see java.nio.channels.FileChannel.map */ @@ -179,7 +180,7 @@ public fun RadByteBufferAccessor( ): RandomAccessData { val stream = FileInputStream(data) val channel = stream.channel - return byteBufferRad0(channel, offset = offset, size = size, channel, stream) + return byteBufferMmapRad0(channel, offset = offset, size = size, channel, stream) } diff --git a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/FileChannelRadAccessor.kt b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/FileChannelRadAccessor.kt index b56615b..3bb3642 100644 --- a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/FileChannelRadAccessor.kt +++ b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/FileChannelRadAccessor.kt @@ -19,7 +19,7 @@ import java.nio.channels.FileChannel * * @param data the underlying [FileChannel] * @param offset the offset of the section - * @param size the length of the section + * @param size the optional length of the section. -1 means the rest of the file. * @param resources the optional resources to close when finished */ @Blocking @@ -44,7 +44,7 @@ public fun RadFileChannelAccessor( * * @param data the underlying [FileInputStream] * @param offset the optional offset of the section - * @param size the optional length of the section + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads @@ -67,9 +67,7 @@ public fun RadFileChannelAccessor( * * @param data the underlying [File] * @param offset the optional offset of the section - * @param size the optional length of the section - * - * @TODO: Would it be better to use [FileChannel.size] instead of [File.length]? + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads @@ -77,7 +75,7 @@ public fun RadFileChannelAccessor( public fun RadFileChannelAccessor( data: File, offset: Long = 0L, - size: Long = data.length() - offset, + size: Long = -1L, ): RandomAccessData = RadFileChannelAccessor(FileInputStream(data), offset = offset, size = size) /** @@ -89,7 +87,7 @@ public fun RadFileChannelAccessor( * * @param data the underlying [FileDescriptor] * @param offset the optional offset of the section - * @param size the optional length of the section + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads diff --git a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/RandomAccessFileRadAccessor.kt b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/RandomAccessFileRadAccessor.kt index b532002..6075b6c 100644 --- a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/RandomAccessFileRadAccessor.kt +++ b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/RandomAccessFileRadAccessor.kt @@ -5,6 +5,7 @@ package fluxo.io.rad import fluxo.io.internal.Blocking +import fluxo.io.util.checkOffsetAndCount import java.io.File import java.io.FileNotFoundException import java.io.RandomAccessFile @@ -21,7 +22,7 @@ import java.io.RandomAccessFile * * @param data the underlying [RandomAccessFile] * @param offset the offset of the section - * @param size the length of the section + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads @@ -31,7 +32,9 @@ public fun RandomAccessFileRadAccessor( offset: Long = 0L, size: Long = -1L, ): RandomAccessData { - val size0 = if (size == -1L) data.length() - offset else size + val dataLength = data.length() + val size0 = if (size == -1L) dataLength - offset else size + checkOffsetAndCount(dataLength, offset, size0) return RandomAccessFileRad(data, offset = offset, size = size0) } @@ -47,9 +50,7 @@ public fun RandomAccessFileRadAccessor( * * @param data the underlying [File] * @param offset the optional offset of the section - * @param size the optional length of the section - * - * @TODO: Would it be better to use [RandomAccessFile.length] instead of [File.length]? + * @param size the optional length of the section. -1 means the rest of the file. * * @throws IllegalArgumentException if the file doesn't exist */ @@ -60,6 +61,6 @@ public fun RandomAccessFileRadAccessor( public fun RandomAccessFileRadAccessor( data: File, offset: Long = 0L, - size: Long = data.length() - offset, + size: Long = -1L, ): RandomAccessData = RandomAccessFileRadAccessor(RandomAccessFile(data, "r"), offset = offset, size = size) diff --git a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/SeekableByteChannelRadAccessor.kt b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/SeekableByteChannelRadAccessor.kt index 63d40fa..537276c 100644 --- a/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/SeekableByteChannelRadAccessor.kt +++ b/fluxo-io-rad/src/commonJvmMain/kotlin/fluxo/io/rad/SeekableByteChannelRadAccessor.kt @@ -5,6 +5,7 @@ package fluxo.io.rad import fluxo.io.internal.Blocking +import fluxo.io.util.checkOffsetAndCount import java.io.File import java.io.FileDescriptor import java.io.FileInputStream @@ -22,7 +23,7 @@ import java.nio.channels.SeekableByteChannel * * @param data the underlying [SeekableByteChannel] * @param offset the offset of the section - * @param size the length of the section + * @param size the optional length of the section. -1 means the rest of the file. * @param resources the optional resources to close when finished * * @see java.nio.channels.FileChannel @@ -37,7 +38,9 @@ public fun RadSeekableByteChannelAccessor( size: Long = -1L, vararg resources: AutoCloseable = arrayOf(data), ): RandomAccessData { - val size0 = if (size == -1L) data.size() - offset else size + val dataLength = data.size() + val size0 = if (size == -1L) dataLength - offset else size + checkOffsetAndCount(dataLength, offset, size0) return SeekableByteChannelRad(data, offset = offset, size = size0, resources = resources) } @@ -53,7 +56,7 @@ public fun RadSeekableByteChannelAccessor( * * @param data the underlying [FileInputStream] * @param offset the optional offset of the section - * @param size the optional length of the section + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads @@ -79,9 +82,7 @@ public fun RadSeekableByteChannelAccessor( * * @param data the underlying [File] * @param offset the optional offset of the section - * @param size the optional length of the section - * - * @TODO: Would it be better to use [SeekableByteChannel.size] instead of [File.length]? + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads @@ -89,7 +90,7 @@ public fun RadSeekableByteChannelAccessor( public fun RadSeekableByteChannelAccessor( data: File, offset: Long = 0L, - size: Long = data.length() - offset, + size: Long = -1L, ): RandomAccessData = RadSeekableByteChannelAccessor(FileInputStream(data), offset = offset, size = size) @@ -105,7 +106,7 @@ public fun RadSeekableByteChannelAccessor( * * @param data the underlying [FileDescriptor] * @param offset the optional offset of the section - * @param size the optional length of the section + * @param size the optional length of the section. -1 means the rest of the file. */ @Blocking @JvmOverloads diff --git a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataByteBufferTest.kt b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataByteBufferTest.kt index 0961238..e88d8f5 100644 --- a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataByteBufferTest.kt +++ b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataByteBufferTest.kt @@ -58,8 +58,8 @@ internal class RadByteBufferAccessorTest( assertIOB { RadByteBufferAccessor(tempFile, -1, 0) } assertIOB { RadByteBufferAccessor(tempFile, -1, 1) } - assertIOB { RadByteBufferAccessor(tempFile, 0, -1) } - assertIOB { RadByteBufferAccessor(tempFile, 1, -1) } + assertIOB { RadByteBufferAccessor(tempFile, 0, -2) } + assertIOB { RadByteBufferAccessor(tempFile, 1, -2) } assertIOB { RadByteBufferAccessor(tempFile, BYTES.size + 1L) } assertIOB { RadByteBufferAccessor(tempFile, BYTES.size.toLong(), 1) } assertIOB { RadByteBufferAccessor(tempFile, BYTES.size + 1L, 1) } diff --git a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataFileChannelTest.kt b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataFileChannelTest.kt index 24afd3f..0b2393e 100644 --- a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataFileChannelTest.kt +++ b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataFileChannelTest.kt @@ -48,8 +48,8 @@ internal class RandomAccessDataFileChannelTest( assertIOB { RadFileChannelAccessor(tempFile, -1, 0) } assertIOB { RadFileChannelAccessor(tempFile, -1, 1) } - assertIOB { RadFileChannelAccessor(tempFile, 0, -1) } - assertIOB { RadFileChannelAccessor(tempFile, 1, -1) } + assertIOB { RadFileChannelAccessor(tempFile, 0, -2) } + assertIOB { RadFileChannelAccessor(tempFile, 1, -2) } assertIOB { RadFileChannelAccessor(tempFile, BYTES.size + 1L) } assertIOB { RadFileChannelAccessor(tempFile, BYTES.size.toLong(), 1L) } assertIOB { RadFileChannelAccessor(tempFile, BYTES.size + 1L, 1L) } diff --git a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataRafTest.kt b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataRafTest.kt index c5c7103..b64af80 100644 --- a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataRafTest.kt +++ b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataRafTest.kt @@ -44,8 +44,8 @@ internal class RandomAccessDataRafTest( assertIOB { RandomAccessFileRadAccessor(tempFile, -1, 0) } assertIOB { RandomAccessFileRadAccessor(tempFile, -1, 1) } - assertIOB { RandomAccessFileRadAccessor(tempFile, 0, -1) } - assertIOB { RandomAccessFileRadAccessor(tempFile, 1, -1) } + assertIOB { RandomAccessFileRadAccessor(tempFile, 0, -2) } + assertIOB { RandomAccessFileRadAccessor(tempFile, 1, -2) } assertIOB { RandomAccessFileRadAccessor(tempFile, BYTES.size + 1L) } assertIOB { RandomAccessFileRadAccessor(tempFile, BYTES.size.toLong(), 1L) } assertIOB { RandomAccessFileRadAccessor(tempFile, BYTES.size + 1L, 1L) } diff --git a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataSeekByteChannelTest.kt b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataSeekByteChannelTest.kt index d0a6351..a57a8b1 100644 --- a/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataSeekByteChannelTest.kt +++ b/fluxo-io-rad/src/jvmTest/kotlin/fluxo/io/rad/RandomAccessDataSeekByteChannelTest.kt @@ -51,8 +51,8 @@ internal class RadSeekableByteChannelAccessorTest( assertIOB { RadSeekableByteChannelAccessor(tempFile, -1, 0) } assertIOB { RadSeekableByteChannelAccessor(tempFile, -1, 1) } - assertIOB { RadSeekableByteChannelAccessor(tempFile, 0, -1) } - assertIOB { RadSeekableByteChannelAccessor(tempFile, 1, -1) } + assertIOB { RadSeekableByteChannelAccessor(tempFile, 0, -2) } + assertIOB { RadSeekableByteChannelAccessor(tempFile, 1, -2) } assertIOB { RadSeekableByteChannelAccessor(tempFile, BYTES.size + 1L) } assertIOB { RadSeekableByteChannelAccessor(tempFile, BYTES.size.toLong(), 1L) } assertIOB { RadSeekableByteChannelAccessor(tempFile, BYTES.size + 1L, 1L) }