diff --git a/coil-network-ktor2/src/nonJvmCommonMain/kotlin/coil3/network/ktor2/internal/utils.kt b/coil-network-ktor2/src/nonJvmCommonMain/kotlin/coil3/network/ktor2/internal/utils.nonJvmCommon.kt similarity index 100% rename from coil-network-ktor2/src/nonJvmCommonMain/kotlin/coil3/network/ktor2/internal/utils.kt rename to coil-network-ktor2/src/nonJvmCommonMain/kotlin/coil3/network/ktor2/internal/utils.nonJvmCommon.kt diff --git a/coil-network-ktor3/src/jvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt b/coil-network-ktor3/src/jvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt index 6c3c1a7474..4c1406256b 100644 --- a/coil-network-ktor3/src/jvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt +++ b/coil-network-ktor3/src/jvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.jvmCommon.kt @@ -1,37 +1,26 @@ package coil3.network.ktor3.internal import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.core.readFully -import io.ktor.utils.io.core.remaining -import io.ktor.utils.io.readRemaining +import io.ktor.utils.io.copyTo +import java.io.RandomAccessFile import okio.BufferedSink import okio.FileSystem import okio.Path -// TODO: Use JVM-optimized implementations from Ktor 2 once -// https://youtrack.jetbrains.com/issue/KTOR-7220 is fixed. - internal actual suspend fun ByteReadChannel.writeTo(sink: BufferedSink) { - val buffer = ByteArray(OKIO_BUFFER_SIZE) - - while (!isClosedForRead) { - val packet = readRemaining(buffer.size.toLong()) - if (packet.exhausted()) break - - // TODO: Figure out how to remove 'buffer' and read directly into 'sink'. - val bytesRead = packet.remaining.toInt() - packet.readFully(buffer, 0, bytesRead) - sink.write(buffer, 0, bytesRead) - } - - closedCause?.let { throw it } + copyTo(sink) } internal actual suspend fun ByteReadChannel.writeTo(fileSystem: FileSystem, path: Path) { - fileSystem.write(path) { - writeTo(this) + if (fileSystem === FileSystem.SYSTEM) { + // Fast path: normal jvm File, write to FileChannel directly. + RandomAccessFile(path.toFile(), "rw").use { + copyTo(it.channel) + } + } else { + // Slow path: cannot guarantee a "real" file. + fileSystem.write(path) { + copyTo(this) + } } } - -// Okio uses 8 KB internally. -private const val OKIO_BUFFER_SIZE = 8 * 1024 diff --git a/coil-network-ktor3/src/nonJvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.kt b/coil-network-ktor3/src/nonJvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.nonJvmCommon.kt similarity index 100% rename from coil-network-ktor3/src/nonJvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.kt rename to coil-network-ktor3/src/nonJvmCommonMain/kotlin/coil3/network/ktor3/internal/utils.nonJvmCommon.kt