From 0f15c3fec7471ebe660962278a6b9d37a8192e73 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 8 Jan 2025 15:26:47 -0500 Subject: [PATCH 01/17] Buffer implementation --- runtime/runtime-core/api/runtime-core.api | 3 + .../aws/smithy/kotlin/runtime/io/SdkSource.kt | 39 ++++- .../kotlin/runtime/io/SdkBufferedSinkTest.kt | 19 +-- .../smithy/kotlin/runtime/io/SdkSourceJVM.kt | 42 ----- .../runtime/io/BufferedSinkAdapterNative.kt | 65 +------ .../runtime/io/BufferedSourceAdapterNative.kt | 85 +-------- .../kotlin/runtime/io/SdkBufferNative.kt | 161 ++++++------------ .../kotlin/runtime/io/SdkSourceNative.kt | 27 --- 8 files changed, 95 insertions(+), 346 deletions(-) delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index d89ff828fb..f33ae91e2f 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -1031,6 +1031,9 @@ public final class aws/smithy/kotlin/runtime/io/SdkSourceJVMKt { public final class aws/smithy/kotlin/runtime/io/SdkSourceKt { public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkSource;Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V + public static final fun readToByteArray (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun toSdkByteReadChannel (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; + public static synthetic fun toSdkByteReadChannel$default (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; } public final class aws/smithy/kotlin/runtime/io/internal/ConvertKt { diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt index dfb9534627..10876a48d4 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt @@ -6,7 +6,16 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.io.internal.JobChannel +import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.IO +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext /** * A source for reading a stream of bytes (e.g. from file, network, or in-memory buffer). Sources may @@ -43,7 +52,9 @@ public interface SdkSource : Closeable { * Consume the [SdkSource] and pull the entire contents into memory as a [ByteArray]. */ @InternalApi -public expect suspend fun SdkSource.readToByteArray(): ByteArray +public suspend fun SdkSource.readToByteArray(): ByteArray = withContext(Dispatchers.IO) { + use { it.buffer().readByteArray() } +} /** * Convert the [SdkSource] to an [SdkByteReadChannel]. Content is read from the source and forwarded @@ -51,8 +62,32 @@ public expect suspend fun SdkSource.readToByteArray(): ByteArray * @param coroutineScope the coroutine scope to use to launch a background reader channel responsible for propagating data * between source and the returned channel */ +@OptIn(DelicateCoroutinesApi::class) @InternalApi -public expect fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope? = null): SdkByteReadChannel +public fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope? = null): SdkByteReadChannel { + val source = this + val ch = JobChannel() + val scope = coroutineScope ?: GlobalScope + val job = scope.launch(Dispatchers.IO + CoroutineName("sdk-source-reader")) { + val buffer = SdkBuffer() + val result = runCatching { + source.use { + while (true) { + ensureActive() + val rc = source.read(buffer, DEFAULT_BYTE_CHANNEL_MAX_BUFFER_SIZE.toLong()) + if (rc == -1L) break + ch.write(buffer) + } + } + } + + ch.close(result.exceptionOrNull()) + } + + ch.attachJob(job) + + return ch +} /** * Remove exactly [byteCount] bytes from this source and appends them to [sink]. diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt index 3469c996fe..f1652e0d80 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt @@ -25,7 +25,6 @@ abstract class AbstractBufferedSinkTest( private val data = SdkBuffer() private val sink = factory(data) - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteByte() { sink.writeByte(0xDE.toByte()) @@ -36,7 +35,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteShort() { sink.writeShort(0xdead.toShort()) @@ -45,7 +43,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteShortLe() { sink.writeShortLe(0xdead.toShort()) @@ -54,7 +51,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=addeefbe]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteInt() { sink.writeInt(0xdeadbeef.toInt()) @@ -62,7 +58,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteLe() { sink.writeIntLe(0xdeadbeef.toInt()) @@ -70,7 +65,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=efbeadde]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteLong() { sink.writeLong(-2401053092341600192) @@ -78,7 +72,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef10203040]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteLongLe() { sink.writeLongLe(4625232074423315934) @@ -86,7 +79,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef10203040]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteString() { sink.writeUtf8("レップはボールです") @@ -94,7 +86,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[text=レップはボールです]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteSubstring() { sink.writeUtf8("a lep is a ball", start = 2, endExclusive = 10) @@ -102,7 +93,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("lep is a", data.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteAll() { val contents = "a tay is a hammer" @@ -113,7 +103,6 @@ abstract class AbstractBufferedSinkTest( assertEquals(contents.length.toLong(), rc) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadSourceFully() { val source = object : SdkSource by SdkBuffer() { @@ -128,7 +117,7 @@ abstract class AbstractBufferedSinkTest( assertEquals("12341234", data.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation + @IgnoreNative // FIXME "Expected an exception of aws.smithy.kotlin.runtime.io.EOFException to be thrown, but was okio.EOFException" @Test fun testWriteEof() { val source: SdkSource = SdkBuffer().apply { writeUtf8("1234") } @@ -137,7 +126,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("1234", data.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteExhausted() { val source: SdkSource = SdkBuffer() @@ -145,7 +133,6 @@ abstract class AbstractBufferedSinkTest( assertEquals(0, data.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteExplicitZero() { val source = object : SdkSource by SdkBuffer() { @@ -156,7 +143,6 @@ abstract class AbstractBufferedSinkTest( assertEquals(0, data.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testCloseFlushes() { sink.writeUtf8("a flix is a comb") @@ -164,7 +150,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("a flix is a comb", data.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteByteArray() { val expected = bytes(0xde, 0xad, 0xbe, 0xef) @@ -174,7 +159,6 @@ abstract class AbstractBufferedSinkTest( assertContentEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteByteArrayOffset() { val expected = bytes(0xde, 0xad, 0xbe, 0xef) @@ -184,7 +168,6 @@ abstract class AbstractBufferedSinkTest( assertContentEquals(expected.sliceArray(2..3), actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteByteArrayOffsetAndLimit() { val expected = bytes(0xde, 0xad, 0xbe, 0xef) diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt deleted file mode 100644 index 2eda1fd3f7..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkSourceJVM.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.io.internal.JobChannel -import kotlinx.coroutines.* - -@InternalApi -public actual suspend fun SdkSource.readToByteArray(): ByteArray = withContext(Dispatchers.IO) { - use { it.buffer().readByteArray() } -} - -@InternalApi -@OptIn(DelicateCoroutinesApi::class) -public actual fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope?): SdkByteReadChannel { - val source = this - val ch = JobChannel() - val scope = coroutineScope ?: GlobalScope - val job = scope.launch(Dispatchers.IO + CoroutineName("sdk-source-reader")) { - val buffer = SdkBuffer() - val result = runCatching { - source.use { - while (true) { - ensureActive() - val rc = source.read(buffer, DEFAULT_BYTE_CHANNEL_MAX_BUFFER_SIZE.toLong()) - if (rc == -1L) break - ch.write(buffer) - } - } - } - - ch.close(result.exceptionOrNull()) - } - - ch.attachJob(job) - - return ch -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt index 48f9badc3a..437c51a074 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt @@ -4,67 +4,4 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : SdkBufferedSink { - actual override val buffer: SdkBuffer - get() = TODO("Not yet implemented") - - actual override fun write(source: ByteArray, offset: Int, limit: Int) { - TODO("Not yet implemented") - } - - actual override fun writeAll(source: SdkSource): Long { - TODO("Not yet implemented") - } - - actual override fun write(source: SdkSource, byteCount: Long) { - TODO("Not yet implemented") - } - - actual override fun writeUtf8(string: String, start: Int, endExclusive: Int) { - TODO("Not yet implemented") - } - - actual override fun writeByte(x: Byte) { - TODO("Not yet implemented") - } - - actual override fun writeShort(x: Short) { - TODO("Not yet implemented") - } - - actual override fun writeShortLe(x: Short) { - TODO("Not yet implemented") - } - - actual override fun writeInt(x: Int) { - TODO("Not yet implemented") - } - - actual override fun writeIntLe(x: Int) { - TODO("Not yet implemented") - } - - actual override fun writeLong(x: Long) { - TODO("Not yet implemented") - } - - actual override fun writeLongLe(x: Long) { - TODO("Not yet implemented") - } - - actual override fun flush() { - TODO("Not yet implemented") - } - - actual override fun emit() { - TODO("Not yet implemented") - } - - actual override fun write(source: SdkBuffer, byteCount: Long) { - TODO("Not yet implemented") - } - - actual override fun close() { - TODO("Not yet implemented") - } -} +internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : SdkBufferedSink, AbstractBufferedSinkAdapter(sink) \ No newline at end of file diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt index cfa9d4c76f..215c9b7ccf 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt @@ -4,87 +4,4 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : SdkBufferedSource { - actual override val buffer: SdkBuffer - get() = TODO("Not yet implemented") - - actual override fun skip(byteCount: Long) { - TODO("Not yet implemented") - } - - actual override fun readByte(): Byte { - TODO("Not yet implemented") - } - - actual override fun readShort(): Short { - TODO("Not yet implemented") - } - - actual override fun readShortLe(): Short { - TODO("Not yet implemented") - } - - actual override fun readLong(): Long { - TODO("Not yet implemented") - } - - actual override fun readLongLe(): Long { - TODO("Not yet implemented") - } - - actual override fun readInt(): Int { - TODO("Not yet implemented") - } - - actual override fun readIntLe(): Int { - TODO("Not yet implemented") - } - - actual override fun readAll(sink: SdkSink): Long { - TODO("Not yet implemented") - } - - actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int { - TODO("Not yet implemented") - } - - actual override fun readByteArray(): ByteArray { - TODO("Not yet implemented") - } - - actual override fun readByteArray(byteCount: Long): ByteArray { - TODO("Not yet implemented") - } - - actual override fun readUtf8(): String { - TODO("Not yet implemented") - } - - actual override fun readUtf8(byteCount: Long): String { - TODO("Not yet implemented") - } - - actual override fun peek(): SdkBufferedSource { - TODO("Not yet implemented") - } - - actual override fun exhausted(): Boolean { - TODO("Not yet implemented") - } - - actual override fun request(byteCount: Long): Boolean { - TODO("Not yet implemented") - } - - actual override fun require(byteCount: Long) { - TODO("Not yet implemented") - } - - actual override fun read(sink: SdkBuffer, limit: Long): Long { - TODO("Not yet implemented") - } - - actual override fun close() { - TODO("Not yet implemented") - } -} +internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : SdkBufferedSource, AbstractBufferedSourceAdapter(source) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt index e8bee2b911..0e0db1d1d0 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt @@ -4,157 +4,100 @@ */ package aws.smithy.kotlin.runtime.io -import okio.Buffer +import aws.smithy.kotlin.runtime.io.internal.* public actual class SdkBuffer : SdkBufferedSource, SdkBufferedSink { - public actual val size: Long - get() = TODO("Not yet implemented") - - public actual constructor() + public actual constructor() : this(okio.Buffer()) internal actual val inner: okio.Buffer - get() = TODO("Not yet implemented") - internal actual constructor(buffer: okio.Buffer) + internal actual constructor(buffer: okio.Buffer) { + this.inner = buffer + } + + public actual val size: Long + get() = inner.size actual override val buffer: SdkBuffer - get() = TODO("Not yet implemented") + get() = this - actual override fun write(source: ByteArray, offset: Int, limit: Int) { - TODO("Not yet implemented") - } + override fun toString(): String = inner.toString() - actual override fun writeAll(source: SdkSource): Long { - TODO("Not yet implemented") - } + override fun hashCode(): Int = inner.hashCode() - actual override fun write(source: SdkSource, byteCount: Long) { - TODO("Not yet implemented") + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is SdkBuffer) return false + return inner == other.inner } - actual override fun writeUtf8(string: String, start: Int, endExclusive: Int) { - TODO("Not yet implemented") - } + actual override fun write(source: SdkBuffer, byteCount: Long): Unit = commonWrite(source, byteCount) - actual override fun writeByte(x: Byte) { - TODO("Not yet implemented") - } + actual override fun write(source: ByteArray, offset: Int, limit: Int): Unit = commonWrite(source, offset, limit) - actual override fun writeShort(x: Short) { - TODO("Not yet implemented") - } + actual override fun write(source: SdkSource, byteCount: Long): Unit = commonWrite(source, byteCount) - actual override fun writeShortLe(x: Short) { - TODO("Not yet implemented") - } + actual override fun writeAll(source: SdkSource): Long = commonWriteAll(source) - actual override fun writeInt(x: Int) { - TODO("Not yet implemented") - } + actual override fun writeUtf8(string: String, start: Int, endExclusive: Int): Unit = commonWriteUtf8(string, start, endExclusive) - actual override fun writeIntLe(x: Int) { - TODO("Not yet implemented") - } + actual override fun writeByte(x: Byte): Unit = commonWriteByte(x) - actual override fun writeLong(x: Long) { - TODO("Not yet implemented") - } + actual override fun writeShort(x: Short): Unit = commonWriteShort(x) - actual override fun writeLongLe(x: Long) { - TODO("Not yet implemented") - } + actual override fun writeShortLe(x: Short): Unit = commonWriteShortLe(x) - actual override fun flush() { - TODO("Not yet implemented") - } + actual override fun writeInt(x: Int): Unit = commonWriteInt(x) - actual override fun emit() { - TODO("Not yet implemented") - } + actual override fun writeIntLe(x: Int): Unit = commonWriteIntLe(x) - actual override fun skip(byteCount: Long) { - TODO("Not yet implemented") - } + actual override fun writeLong(x: Long): Unit = commonWriteLong(x) - actual override fun readByte(): Byte { - TODO("Not yet implemented") - } + actual override fun writeLongLe(x: Long): Unit = commonWriteLongLe(x) - actual override fun readShort(): Short { - TODO("Not yet implemented") - } + actual override fun flush(): Unit = commonFlush() - actual override fun readShortLe(): Short { - TODO("Not yet implemented") - } + actual override fun emit() { inner.emit() } - actual override fun readLong(): Long { - TODO("Not yet implemented") - } + actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount) - actual override fun readLongLe(): Long { - TODO("Not yet implemented") - } + actual override fun readByte(): Byte = commonReadByte() - actual override fun readInt(): Int { - TODO("Not yet implemented") - } + actual override fun readShort(): Short = commonReadShort() - actual override fun readIntLe(): Int { - TODO("Not yet implemented") - } + actual override fun readShortLe(): Short = commonReadShortLe() - actual override fun readAll(sink: SdkSink): Long { - TODO("Not yet implemented") - } + actual override fun readLong(): Long = commonReadLong() - actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int { - TODO("Not yet implemented") - } + actual override fun readLongLe(): Long = commonReadLongLe() - actual override fun readByteArray(): ByteArray { - TODO("Not yet implemented") - } + actual override fun readInt(): Int = commonReadInt() - actual override fun readByteArray(byteCount: Long): ByteArray { - TODO("Not yet implemented") - } + actual override fun readIntLe(): Int = commonReadIntLe() - actual override fun readUtf8(): String { - TODO("Not yet implemented") - } + actual override fun readAll(sink: SdkSink): Long = commonReadAll(sink) - actual override fun readUtf8(byteCount: Long): String { - TODO("Not yet implemented") - } + actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int = commonRead(sink, offset, limit) - actual override fun peek(): SdkBufferedSource { - TODO("Not yet implemented") - } + actual override fun readByteArray(): ByteArray = commonReadByteArray() - actual override fun exhausted(): Boolean { - TODO("Not yet implemented") - } + actual override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount) - actual override fun request(byteCount: Long): Boolean { - TODO("Not yet implemented") - } + actual override fun readUtf8(): String = commonReadUtf8() - actual override fun require(byteCount: Long) { - TODO("Not yet implemented") - } + actual override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount) - actual override fun write(source: SdkBuffer, byteCount: Long) { - TODO("Not yet implemented") - } + actual override fun peek(): SdkBufferedSource = commonPeek() - actual override fun read(sink: SdkBuffer, limit: Long): Long { - TODO("Not yet implemented") - } + actual override fun exhausted(): Boolean = commonExhausted() - actual override fun close() { - TODO("Not yet implemented") - } + actual override fun request(byteCount: Long): Boolean = commonRequest(byteCount) + + actual override fun require(byteCount: Long): Unit = commonRequire(byteCount) + + actual override fun read(sink: SdkBuffer, limit: Long): Long = commonRead(sink, limit) + + actual override fun close(): Unit = commonClose() } diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt deleted file mode 100644 index e7febda6d2..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkSourceNative.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.io - -import aws.smithy.kotlin.runtime.InternalApi -import kotlinx.coroutines.CoroutineScope - -/** - * Consume the [SdkSource] and pull the entire contents into memory as a [ByteArray]. - */ -@InternalApi -public actual suspend fun SdkSource.readToByteArray(): ByteArray { - TODO("Not yet implemented") -} - -/** - * Convert the [SdkSource] to an [SdkByteReadChannel]. Content is read from the source and forwarded - * to the channel. - * @param coroutineScope the coroutine scope to use to launch a background reader channel responsible for propagating data - * between source and the returned channel - */ -@InternalApi -public actual fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope?): SdkByteReadChannel { - TODO("Not yet implemented") -} From c8f0c6563669bd3cced52d19d6b1c5f28802e25a Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 8 Jan 2025 16:08:40 -0500 Subject: [PATCH 02/17] Buffer implementation --- .../runtime/auth/awssigning/Canonicalizer.kt | 5 +++-- .../runtime/http/engine/crt/CrtHttpEngine.kt | 3 +-- .../kotlin/runtime/content/ByteStream.kt | 5 +++-- .../kotlin/runtime/io/SdkByteReadChannel.kt | 7 ++++--- .../runtime/io/internal/SdkDispatchers.kt | 21 ------------------- .../runtime/io/internal/SdkDispatchersJVM.kt | 15 ------------- .../runtime/io/BufferedSinkAdapterNative.kt | 4 +++- .../runtime/io/BufferedSourceAdapterNative.kt | 4 +++- .../kotlin/runtime/io/SdkBufferNative.kt | 4 +++- .../io/internal/SdkDispatchersNative.kt | 17 --------------- 10 files changed, 20 insertions(+), 65 deletions(-) delete mode 100644 runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt delete mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt index 69d742de79..eb821ecfcd 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt @@ -12,7 +12,6 @@ import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.http.request.toBuilder import aws.smithy.kotlin.runtime.io.* -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import aws.smithy.kotlin.runtime.net.url.QueryParameters import aws.smithy.kotlin.runtime.net.url.Url import aws.smithy.kotlin.runtime.net.url.UrlPath @@ -20,6 +19,8 @@ import aws.smithy.kotlin.runtime.text.encoding.Encodable import aws.smithy.kotlin.runtime.text.encoding.PercentEncoding import aws.smithy.kotlin.runtime.text.encoding.encodeToHex import aws.smithy.kotlin.runtime.time.TimestampFormat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.withContext /** @@ -162,7 +163,7 @@ internal class DefaultCanonicalizer(private val sha256Supplier: HashSupplier = : } is HttpBody.SourceContent -> { val source = readFrom() - withContext(SdkDispatchers.IO) { + withContext(Dispatchers.IO) { source.sha256().encodeToHex() } } diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt index 40a38a9a90..545cfb271f 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt @@ -11,7 +11,6 @@ import aws.smithy.kotlin.runtime.http.engine.HttpClientEngine import aws.smithy.kotlin.runtime.http.engine.HttpClientEngineBase import aws.smithy.kotlin.runtime.http.engine.callContext import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import aws.smithy.kotlin.runtime.operation.ExecutionContext import aws.smithy.kotlin.runtime.telemetry.logging.logger import aws.smithy.kotlin.runtime.time.Instant @@ -84,7 +83,7 @@ public class CrtHttpEngine(public override val config: CrtHttpEngineConfig) : Ht } if (request.isChunked) { - withContext(SdkDispatchers.IO) { + withContext(Dispatchers.IO) { stream.sendChunkedBody(request.body) } } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt index 96bf20b25a..6d88fa5fae 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt @@ -5,8 +5,9 @@ package aws.smithy.kotlin.runtime.content import aws.smithy.kotlin.runtime.io.* -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch @@ -119,7 +120,7 @@ public fun ByteStream.cancel() { public fun ByteStream.toFlow(bufferSize: Long = 8192): Flow = when (this) { is ByteStream.Buffer -> flowOf(bytes()) is ByteStream.ChannelStream -> readFrom().toFlow(bufferSize) - is ByteStream.SourceStream -> readFrom().toFlow(bufferSize).flowOn(SdkDispatchers.IO) + is ByteStream.SourceStream -> readFrom().toFlow(bufferSize).flowOn(Dispatchers.IO) } /** diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index 87d5a531da..1dffecf5e8 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt @@ -4,7 +4,8 @@ */ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.withContext /** @@ -104,7 +105,7 @@ public suspend fun SdkByteReadChannel.readToBuffer(): SdkBuffer { /** * Read all bytes from this channel into [sink]. Returns the total number of bytes written. */ -public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext(SdkDispatchers.IO) { +public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext(Dispatchers.IO) { val bufferedSink = sink.buffer() var totalWritten = 0L while (true) { @@ -120,7 +121,7 @@ public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext /** * Removes all bytes from [source] and writes them to this channel. Returns the total number of bytes read. */ -public suspend fun SdkByteWriteChannel.writeAll(source: SdkSource): Long = withContext(SdkDispatchers.IO) { +public suspend fun SdkByteWriteChannel.writeAll(source: SdkSource): Long = withContext(Dispatchers.IO) { val buffer = SdkBuffer() var totalRead = 0L while (true) { diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt deleted file mode 100644 index 068f1b796a..0000000000 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io.internal - -import aws.smithy.kotlin.runtime.InternalApi -import kotlinx.coroutines.CoroutineDispatcher - -/** - * Internal coroutine dispatchers used by the SDK - */ -@InternalApi -public expect object SdkDispatchers { - /** - * The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads. - * On JVM this is guaranteed to be `Dispatchers.IO` - */ - public val IO: CoroutineDispatcher -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt deleted file mode 100644 index 2f0af6738c..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io.internal - -import aws.smithy.kotlin.runtime.InternalApi -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers - -@InternalApi -public actual object SdkDispatchers { - public actual val IO: CoroutineDispatcher = Dispatchers.IO -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt index 437c51a074..bf5767cf35 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt @@ -4,4 +4,6 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : SdkBufferedSink, AbstractBufferedSinkAdapter(sink) \ No newline at end of file +internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : + AbstractBufferedSinkAdapter(sink), + SdkBufferedSink diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt index 215c9b7ccf..437b018606 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt @@ -4,4 +4,6 @@ */ package aws.smithy.kotlin.runtime.io -internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : SdkBufferedSource, AbstractBufferedSourceAdapter(source) +internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : + AbstractBufferedSourceAdapter(source), + SdkBufferedSource diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt index 0e0db1d1d0..6e84610443 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt @@ -59,7 +59,9 @@ public actual class SdkBuffer : actual override fun flush(): Unit = commonFlush() - actual override fun emit() { inner.emit() } + actual override fun emit() { + inner.emit() + } actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt deleted file mode 100644 index e5b1309c5a..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.smithy.kotlin.runtime.io.internal - -import aws.smithy.kotlin.runtime.InternalApi -import kotlinx.coroutines.CoroutineDispatcher - -@InternalApi -public actual object SdkDispatchers { - /** - * The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads. - */ - public actual val IO: CoroutineDispatcher - get() = TODO("Not yet implemented") -} From 9d1ab9a20ea2bf19618197a9b26b9b3d96cf861d Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 8 Jan 2025 17:14:41 -0500 Subject: [PATCH 03/17] Enable more tests --- .../kotlin/runtime/io/ByteArraySourceTest.kt | 2 -- .../runtime/io/HashingByteReadChannelTest.kt | 6 ---- .../kotlin/runtime/io/HashingSinkTest.kt | 3 -- .../kotlin/runtime/io/HashingSourceTest.kt | 2 -- .../smithy/kotlin/runtime/io/ObserversTest.kt | 2 -- .../kotlin/runtime/io/SdkBufferedSinkTest.kt | 3 +- .../runtime/io/SdkBufferedSourceTest.kt | 32 ++----------------- .../runtime/io/SdkByteChannelSuspendTest.kt | 22 ------------- .../kotlin/runtime/io/SdkByteChannelTest.kt | 9 ------ 9 files changed, 3 insertions(+), 78 deletions(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ByteArraySourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ByteArraySourceTest.kt index de56a3b713..dea0585f3e 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ByteArraySourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ByteArraySourceTest.kt @@ -5,12 +5,10 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertEquals class ByteArraySourceTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testByteArraySource() { val contents = "12345678".encodeToByteArray() diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingByteReadChannelTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingByteReadChannelTest.kt index 1ac4c8794c..5d9b3eb74f 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingByteReadChannelTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingByteReadChannelTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.hashing.toHashFunction import kotlinx.coroutines.test.runTest import kotlin.random.Random @@ -16,7 +15,6 @@ class HashingByteReadChannelTest { private val hashFunctionNames = listOf("crc32", "crc32c", "md5", "sha1", "sha256") - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAll() = runTest { hashFunctionNames.forEach { hashFunctionName -> @@ -37,7 +35,6 @@ class HashingByteReadChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToBuffer() = runTest { hashFunctionNames.forEach { hashFunctionName -> @@ -56,7 +53,6 @@ class HashingByteReadChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFully() = runTest { hashFunctionNames.forEach { hashFunctionName -> @@ -76,7 +72,6 @@ class HashingByteReadChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadRemaining() = runTest { hashFunctionNames.forEach { hashFunctionName -> @@ -96,7 +91,6 @@ class HashingByteReadChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRead() = runTest { hashFunctionNames.forEach { hashFunctionName -> diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSinkTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSinkTest.kt index 8d0121c375..c4070116bc 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSinkTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSinkTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.hashing.toHashFunction import kotlin.test.Test import kotlin.test.assertEquals @@ -14,7 +13,6 @@ class HashingSinkTest { private val hashFunctionNames = listOf("crc32", "crc32c", "md5", "sha1", "sha256") - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testHashingSinkDigest() = run { hashFunctionNames.forEach { hashFunctionName -> @@ -33,7 +31,6 @@ class HashingSinkTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testHashingSinkPartialWrite() = run { hashFunctionNames.forEach { hashFunctionName -> diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt index 70cfaef8e2..0184a07dbf 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt @@ -14,7 +14,6 @@ class HashingSourceTest { private val hashFunctionNames = listOf("crc32", "crc32c", "md5", "sha1", "sha256") - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testHashingSourceDigest() = run { hashFunctionNames.forEach { hashFunctionName -> @@ -34,7 +33,6 @@ class HashingSourceTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testHashingSourcePartialRead() = run { hashFunctionNames.forEach { hashFunctionName -> diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt index 19a845039e..ff036c3a00 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt @@ -12,7 +12,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class ObserversTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkSourceObserver() { val source = SdkBuffer() @@ -35,7 +34,6 @@ class ObserversTest { assertEquals(sink.readUtf8(), observer.content.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkSinkObserver() { val sink = SdkSink.blackhole() diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt index f1652e0d80..3117aa2a82 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt @@ -5,11 +5,11 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import okio.EOFException // FIXME Leaking abstraction. Should we be catching okio.EOFException and throwing aws.smithy.kotlin.runtime.io.EOFException in our I/O implementations? // Test SdkBuffer implementation of SdkBufferedSink interface class SdkBufferSinkTest : AbstractBufferedSinkTest({ buffer -> buffer }) @@ -117,7 +117,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("12341234", data.readUtf8()) } - @IgnoreNative // FIXME "Expected an exception of aws.smithy.kotlin.runtime.io.EOFException to be thrown, but was okio.EOFException" @Test fun testWriteEof() { val source: SdkSource = SdkBuffer().apply { writeUtf8("1234") } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt index ed5430c8f2..3c01432500 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt @@ -5,8 +5,8 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.* +import okio.EOFException /** * A (source, sink) connected pair. Writes to [sink] are read from [source] @@ -57,7 +57,6 @@ abstract class BufferedSourceTest( source = pipe.source } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadBytes() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef)) @@ -70,7 +69,6 @@ abstract class BufferedSourceTest( assertTrue(source.exhausted()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadEmpty() { assertFailsWith { @@ -78,7 +76,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadShort() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef)) @@ -87,7 +84,6 @@ abstract class BufferedSourceTest( assertEquals(0xbeef.toShort(), source.readShort()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadShortLe() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef)) @@ -96,7 +92,6 @@ abstract class BufferedSourceTest( assertEquals(0xefbe.toShort(), source.readShortLe()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadInt() { sink.write(bytes(0x0b, 0xad, 0xca, 0xfe)) @@ -104,7 +99,6 @@ abstract class BufferedSourceTest( assertEquals(0x0badcafe, source.readInt()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadIntLe() { sink.write(bytes(0x0b, 0xad, 0xca, 0xfe)) @@ -112,7 +106,6 @@ abstract class BufferedSourceTest( assertEquals(-20271861, source.readIntLe()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadLong() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef, 0x10, 0x20, 0x30, 0x40)) @@ -120,7 +113,6 @@ abstract class BufferedSourceTest( assertEquals(-2401053092341600192, source.readLong()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadLongLe() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef, 0x10, 0x20, 0x30, 0x40)) @@ -128,7 +120,6 @@ abstract class BufferedSourceTest( assertEquals(4625232074423315934, source.readLongLe()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAll() { val content = "a lep is a ball" @@ -140,14 +131,12 @@ abstract class BufferedSourceTest( assertEquals(content, testSink.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAllExhaustedSource() { val testSink: SdkSink = SdkBuffer() assertEquals(0, source.readAll(testSink)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadExhausted() { val testSink = SdkBuffer() @@ -157,7 +146,6 @@ abstract class BufferedSourceTest( assertEquals(sizeBefore, testSink.size) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArray() { val expected = bytes(0xde, 0xad, 0xbe, 0xef) @@ -166,7 +154,6 @@ abstract class BufferedSourceTest( assertContentEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArrayLimit() { val expected = bytes(0xde, 0xad, 0xbe, 0xef) @@ -175,7 +162,6 @@ abstract class BufferedSourceTest( assertContentEquals(expected.sliceArray(0..1), actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArrayOffset() { val content = bytes(0xde, 0xad, 0xbe, 0xef) @@ -187,7 +173,6 @@ abstract class BufferedSourceTest( assertContentEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArrayOffsetAndLimit() { val content = bytes(0xde, 0xad, 0xbe, 0xef) @@ -199,7 +184,6 @@ abstract class BufferedSourceTest( assertContentEquals(expected, actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArrayTooSmall() { // read into a byte array that is smaller than the available data which should result in a "short" read @@ -210,7 +194,6 @@ abstract class BufferedSourceTest( assertContentEquals(expected.sliceArray(0..2), testSink) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadByteArrayEOF() { // read into a byte array that is smaller than the available data which should result in a "short" read @@ -220,7 +203,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkip() { val content = ByteArray(16 * 1024) { it.toByte() } @@ -232,7 +214,6 @@ abstract class BufferedSourceTest( assertContentEquals(content.sliceArray(8192 until content.size), actual) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkipNotEnoughData() { val content = ByteArray(1024) { it.toByte() } @@ -244,7 +225,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testPeek() { sink.writeUtf8("a flix is a comb") @@ -258,7 +238,6 @@ abstract class BufferedSourceTest( assertEquals(" is a comb", source.readUtf8(10)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testMultiplePeek() { sink.writeUtf8("a flix is a comb") @@ -276,7 +255,6 @@ abstract class BufferedSourceTest( assertEquals(" is a comb", source.readUtf8(10)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testLargePeek() { sink.writeUtf8("123456") @@ -297,7 +275,6 @@ abstract class BufferedSourceTest( assertTrue(source.exhausted()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testInvalidatedPeek() { // peek is invalid after first call to source @@ -316,7 +293,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRequest() { sink.writeUtf8("123456789".repeat(1024)) @@ -327,7 +303,6 @@ abstract class BufferedSourceTest( assertFalse(source.request(1024 * 9 + 1)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRequire() { sink.writeUtf8("123456789".repeat(1024)) @@ -339,7 +314,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFully() { val data = "123456789".repeat(1024) @@ -351,7 +325,6 @@ abstract class BufferedSourceTest( assertEquals(data, dest.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyIllegalArgumentException() { val dest = SdkBuffer() @@ -360,7 +333,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyEOFException() { val data = "123456789".repeat(1024) @@ -368,7 +340,7 @@ abstract class BufferedSourceTest( sink.flush() val dest = SdkBuffer() - assertFailsWith { + assertFailsWith { source.readFully(dest, data.length.toLong() + 1) } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt index 1ad0543151..5dfe1108c4 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt @@ -30,7 +30,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { ch.cancel(CancellationException("Test finished")) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadBeforeAvailable() = runTest { // test readAvailable() suspends when no data is available @@ -61,7 +60,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(6) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterAvailable() = runTest { // test readAvailable() does NOT suspend when data is available @@ -89,7 +87,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(6) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullySuspends() = runTest { // test readFully() suspends when not enough data is available to satisfy the request @@ -119,7 +116,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(7) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAfterAvailableFully() = runTest { // test readFully() does NOT suspend when data is available to satisfy the request @@ -144,7 +140,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToEmpty() = runTest { // test read() does not suspend when length is zero @@ -158,7 +153,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(3) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToEmptyFromFailedChannel() = runTest { expect(1) @@ -170,7 +164,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToEmptyFromClosedChannel() = runTest { expect(1) @@ -182,7 +175,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(3) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromFailedChannel() = runTest { expect(1) @@ -194,7 +186,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromClosedChannelNoSuspend() = runTest { expect(1) @@ -204,7 +195,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromClosedChannelSuspend() = runTest { expect(1) @@ -224,7 +214,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyFromFailedChannel() = runTest { expect(1) @@ -236,7 +225,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyFromClosedChannel() = runTest { expect(1) @@ -248,7 +236,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadState() = runTest { assertFalse(ch.isClosedForWrite) @@ -268,7 +255,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { assertTrue(ch.isClosedForRead) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadRemaining() = runTest { expect(1) @@ -289,7 +275,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(6) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadInProgress() = runTest { expect(1) @@ -311,7 +296,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteInProgress() = runTest { val chan = SdkByteChannel(true, 8) @@ -338,7 +322,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyEof() = runTest { expect(1) @@ -358,7 +341,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testResumeReadFromFailedChannel() = runTest { expect(1) @@ -377,7 +359,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(4) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testResumeReadFromClosedChannelNoContent() = runTest { expect(1) @@ -394,7 +375,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(4) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testLargeTransfer() = runTest { val data = "a".repeat(262144) + "b".repeat(512) @@ -409,7 +389,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { assertEquals(data.length.toLong(), ch.totalBytesWritten) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteNoSuspend() = runTest { val chan = SdkByteChannel(false, 8) @@ -420,7 +399,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteSuspend() = runTest { val chan = SdkByteChannel(false, 8) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt index e129614f59..6a489a145e 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt @@ -12,14 +12,12 @@ import kotlinx.coroutines.yield import kotlin.test.* class SdkByteChannelTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testCreateAndClose() { val chan = SdkByteChannel(false) chan.close() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testAutoFlush() = runTest { SdkByteChannel(false).use { chan -> @@ -44,7 +42,6 @@ class SdkByteChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClose() = runTest { val chan = SdkByteChannel(false) @@ -89,7 +86,6 @@ class SdkByteChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromClosedChannel() = runTest { val chan = SdkByteReadChannel(byteArrayOf(1, 2, 3, 4, 5)) @@ -103,7 +99,6 @@ class SdkByteChannelTest { assertTrue { chan.isClosedForRead } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAvailableNoSuspend() = runTest { val chan = SdkByteReadChannel("world!".encodeToByteArray()) @@ -116,7 +111,6 @@ class SdkByteChannelTest { assertEquals("hello, world!", buffer.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadAvailableSuspend() = runTest { val chan = SdkByteChannel() @@ -139,7 +133,6 @@ class SdkByteChannelTest { job.join() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testCloseableUse() = runTest { val chan = SdkByteChannel(true) @@ -161,7 +154,6 @@ class SdkByteChannelTest { assertTrue(chan.isClosedForRead) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyFromFailedChannel() = runTest { // ensure that we attempt reading such that failures are propagate to caller @@ -174,7 +166,6 @@ class SdkByteChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadRemainingFromFailedChannel() = runTest { // ensure that we attempt reading such that failures are propagate to caller From be417dc249e69726e134a827afc44d6d07e2481e Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 11:57:53 -0500 Subject: [PATCH 04/17] Remove okio.EOFException --- .../test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt | 1 - .../test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt index 3117aa2a82..b3a76321c0 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSinkTest.kt @@ -9,7 +9,6 @@ import kotlin.test.Test import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertFailsWith -import okio.EOFException // FIXME Leaking abstraction. Should we be catching okio.EOFException and throwing aws.smithy.kotlin.runtime.io.EOFException in our I/O implementations? // Test SdkBuffer implementation of SdkBufferedSink interface class SdkBufferSinkTest : AbstractBufferedSinkTest({ buffer -> buffer }) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt index 3c01432500..dc9df7ad7d 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt @@ -6,7 +6,6 @@ package aws.smithy.kotlin.runtime.io import kotlin.test.* -import okio.EOFException /** * A (source, sink) connected pair. Writes to [sink] are read from [source] From 51f39b5803a3c076e6be868f42a1d6e731e6a43b Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 11:59:57 -0500 Subject: [PATCH 05/17] Unnecessary qualification --- .../test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt index dc9df7ad7d..284f72808e 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt @@ -339,7 +339,7 @@ abstract class BufferedSourceTest( sink.flush() val dest = SdkBuffer() - assertFailsWith { + assertFailsWith { source.readFully(dest, data.length.toLong() + 1) } } From d8df6326fc8b3e87110c53e00eab65e1e90e5e82 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 15:10:07 -0500 Subject: [PATCH 06/17] Throw the correct exception type --- runtime/runtime-core/api/runtime-core.api | 6 ++ .../runtime/io/BuffereredSourceAdapter.kt | 63 ++++++++++----- .../smithy/kotlin/runtime/io/Exceptions.kt | 3 +- .../runtime/io/internal/BufferOperations.kt | 81 +++++++++++-------- .../smithy/kotlin/runtime/io/ExceptionsJVM.kt | 12 ++- .../kotlin/runtime/io/ExceptionsNative.kt | 5 +- 6 files changed, 112 insertions(+), 58 deletions(-) diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index f33ae91e2f..9248eb7f13 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -760,6 +760,12 @@ public final class aws/smithy/kotlin/runtime/io/ClosedWriteChannelException : ja public synthetic fun (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V } +public class aws/smithy/kotlin/runtime/io/EOFException : java/io/EOFException { + public fun ()V + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/Throwable;)V +} + public final class aws/smithy/kotlin/runtime/io/GzipByteReadChannel : aws/smithy/kotlin/runtime/io/SdkByteReadChannel { public fun (Laws/smithy/kotlin/runtime/io/SdkByteReadChannel;)V public fun cancel (Ljava/lang/Throwable;)Z diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt index 8b92fbbe64..ba618359de 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt @@ -32,6 +32,17 @@ internal expect class BufferedSourceAdapter(source: okio.BufferedSource) : SdkBu override fun close() } +/** + * Used to wrap calls to Okio, catching Okio exceptions (e.g. okio.EOFException) and throwing our own (e.g. aws.smithy.kotlin.runtime.io.EOFException). + */ +internal inline fun SdkBufferedSource.wrapOkio(block: SdkBufferedSource.() -> T): T = try { + block() +} catch (e: okio.EOFException) { + throw EOFException("Okio operation failed", e) +} catch (e: okio.IOException) { + throw IOException("Okio operation failed", e) +} + // base class that fills in most of the common implementation, platforms just need to implement the platform specific // part of the interface internal abstract class AbstractBufferedSourceAdapter( @@ -40,45 +51,57 @@ internal abstract class AbstractBufferedSourceAdapter( override val buffer: SdkBuffer get() = delegate.buffer.toSdk() - override fun skip(byteCount: Long): Unit = delegate.skip(byteCount) + override fun skip(byteCount: Long): Unit = wrapOkio { delegate.skip(byteCount) } - override fun readByte(): Byte = delegate.readByte() + override fun readByte(): Byte = wrapOkio { delegate.readByte() } - override fun readShort(): Short = delegate.readShort() + override fun readShort(): Short = wrapOkio { delegate.readShort() } - override fun readShortLe(): Short = delegate.readShortLe() + override fun readShortLe(): Short = wrapOkio { delegate.readShortLe() } - override fun readLong(): Long = delegate.readLong() + override fun readLong(): Long = wrapOkio { delegate.readLong() } - override fun readLongLe(): Long = delegate.readLongLe() + override fun readLongLe(): Long = wrapOkio { delegate.readLongLe() } - override fun readInt(): Int = delegate.readInt() + override fun readInt(): Int = wrapOkio { delegate.readInt() } - override fun readIntLe(): Int = delegate.readIntLe() + override fun readIntLe(): Int = wrapOkio { delegate.readIntLe() } - override fun readAll(sink: SdkSink): Long = + override fun readAll(sink: SdkSink): Long = wrapOkio { delegate.readAll(sink.toOkio()) + } - override fun read(sink: ByteArray, offset: Int, limit: Int): Int = + override fun read(sink: ByteArray, offset: Int, limit: Int): Int = wrapOkio { delegate.read(sink, offset, limit) + } - override fun read(sink: SdkBuffer, limit: Long): Long = + override fun read(sink: SdkBuffer, limit: Long): Long = wrapOkio { delegate.read(sink.toOkio(), limit) + } - override fun readByteArray(): ByteArray = delegate.readByteArray() + override fun readByteArray(): ByteArray = wrapOkio { delegate.readByteArray() } - override fun readByteArray(byteCount: Long): ByteArray = delegate.readByteArray(byteCount) + override fun readByteArray(byteCount: Long): ByteArray = wrapOkio { + delegate.readByteArray(byteCount) + } - override fun readUtf8(): String = delegate.readUtf8() + override fun readUtf8(): String = wrapOkio { delegate.readUtf8() } - override fun readUtf8(byteCount: Long): String = delegate.readUtf8(byteCount) + override fun readUtf8(byteCount: Long): String = wrapOkio { + delegate.readUtf8(byteCount) + } - override fun peek(): SdkBufferedSource = + override fun peek(): SdkBufferedSource = wrapOkio { delegate.peek().toSdk().buffer() - override fun exhausted(): Boolean = delegate.exhausted() - override fun request(byteCount: Long): Boolean = delegate.request(byteCount) + } + + override fun exhausted(): Boolean = wrapOkio { delegate.exhausted() } + + override fun request(byteCount: Long): Boolean = wrapOkio { + delegate.request(byteCount) + } - override fun require(byteCount: Long): Unit = delegate.require(byteCount) + override fun require(byteCount: Long): Unit = wrapOkio { delegate.require(byteCount) } - override fun close() = delegate.close() + override fun close() = wrapOkio { delegate.close() } } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt index b0dfa89c5f..96d6685ff8 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/Exceptions.kt @@ -10,8 +10,9 @@ public expect open class IOException(message: String?, cause: Throwable?) : Exce public constructor(message: String?) } -public expect open class EOFException(message: String?) : IOException { +public expect open class EOFException(message: String?, cause: Throwable?) : IOException { public constructor() + public constructor(message: String?) } /** diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt index 1657f933ce..0dbafcbba0 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt @@ -9,95 +9,108 @@ package aws.smithy.kotlin.runtime.io.internal import aws.smithy.kotlin.runtime.io.* -internal inline fun SdkBuffer.commonSkip(byteCount: Long) = inner.skip(byteCount) +/** + * Used to wrap calls to Okio, catching Okio exceptions (e.g. okio.EOFException) and throwing our own (e.g. aws.smithy.kotlin.runtime.io.EOFException). + */ +internal inline fun SdkBuffer.wrapOkio(block: SdkBuffer.() -> T): T = try { + block() +} catch (e: okio.EOFException) { + throw EOFException("Okio operation failed", e) +} catch (e: okio.IOException) { + throw IOException("Okio operation failed", e) +} + +internal inline fun SdkBuffer.commonSkip(byteCount: Long) = wrapOkio { inner.skip(byteCount) } -internal inline fun SdkBuffer.commonReadByte(): Byte = inner.readByte() +internal inline fun SdkBuffer.commonReadByte(): Byte = wrapOkio { inner.readByte() } -internal inline fun SdkBuffer.commonReadShort(): Short = inner.readShort() +internal inline fun SdkBuffer.commonReadShort(): Short = wrapOkio { inner.readShort() } -internal inline fun SdkBuffer.commonReadShortLe(): Short = inner.readShortLe() +internal inline fun SdkBuffer.commonReadShortLe(): Short = wrapOkio { inner.readShortLe() } -internal inline fun SdkBuffer.commonReadLong(): Long = inner.readLong() +internal inline fun SdkBuffer.commonReadLong(): Long = wrapOkio { inner.readLong() } -internal inline fun SdkBuffer.commonReadLongLe(): Long = inner.readLongLe() +internal inline fun SdkBuffer.commonReadLongLe(): Long = wrapOkio { inner.readLongLe() } -internal inline fun SdkBuffer.commonReadInt(): Int = inner.readInt() +internal inline fun SdkBuffer.commonReadInt(): Int = wrapOkio { inner.readInt() } -internal inline fun SdkBuffer.commonReadIntLe(): Int = inner.readIntLe() +internal inline fun SdkBuffer.commonReadIntLe(): Int = wrapOkio { inner.readIntLe() } -internal inline fun SdkBuffer.commonReadAll(sink: SdkSink): Long = - inner.readAll(sink.toOkio()) +internal inline fun SdkBuffer.commonReadAll(sink: SdkSink): Long = wrapOkio { inner.readAll(sink.toOkio()) } internal inline fun SdkBuffer.commonRead(sink: ByteArray, offset: Int, limit: Int): Int = - inner.read(sink, offset, limit) + wrapOkio { inner.read(sink, offset, limit) } internal inline fun SdkBuffer.commonRead(sink: SdkBuffer, limit: Long): Long = - inner.read(sink.inner, limit) + wrapOkio { inner.read(sink.inner, limit) } -internal inline fun SdkBuffer.commonReadByteArray(): ByteArray = inner.readByteArray() +internal inline fun SdkBuffer.commonReadByteArray(): ByteArray = wrapOkio { inner.readByteArray() } -internal inline fun SdkBuffer.commonReadByteArray(byteCount: Long): ByteArray = inner.readByteArray(byteCount) +internal inline fun SdkBuffer.commonReadByteArray(byteCount: Long): ByteArray = wrapOkio { inner.readByteArray(byteCount) } -internal inline fun SdkBuffer.commonReadUtf8(): String = inner.readUtf8() +internal inline fun SdkBuffer.commonReadUtf8(): String = wrapOkio { inner.readUtf8() } -internal inline fun SdkBuffer.commonReadUtf8(byteCount: Long): String = inner.readUtf8(byteCount) +internal inline fun SdkBuffer.commonReadUtf8(byteCount: Long): String = wrapOkio { inner.readUtf8(byteCount) } -internal inline fun SdkBuffer.commonPeek(): SdkBufferedSource = inner.peek().toSdk().buffer() -internal inline fun SdkBuffer.commonExhausted(): Boolean = inner.exhausted() -internal inline fun SdkBuffer.commonRequest(byteCount: Long): Boolean = inner.request(byteCount) +internal inline fun SdkBuffer.commonPeek(): SdkBufferedSource = wrapOkio { inner.peek().toSdk().buffer() } -internal inline fun SdkBuffer.commonRequire(byteCount: Long): Unit = inner.require(byteCount) +internal inline fun SdkBuffer.commonExhausted(): Boolean = wrapOkio { inner.exhausted() } + +internal inline fun SdkBuffer.commonRequest(byteCount: Long): Boolean = wrapOkio { inner.request(byteCount) } + +internal inline fun SdkBuffer.commonRequire(byteCount: Long) = wrapOkio { inner.require(byteCount) } internal inline fun SdkBuffer.commonWrite(source: ByteArray, offset: Int, limit: Int) { - inner.write(source, offset, limit) + wrapOkio { inner.write(source, offset, limit) } } internal inline fun SdkBuffer.commonWrite(source: SdkSource, byteCount: Long) { - inner.write(source.toOkio(), byteCount) + wrapOkio { inner.write(source.toOkio(), byteCount) } } + internal inline fun SdkBuffer.commonWrite(source: SdkBuffer, byteCount: Long) { - inner.write(source.toOkio(), byteCount) + wrapOkio { inner.write(source.toOkio(), byteCount) } } internal inline fun SdkBuffer.commonWriteAll(source: SdkSource): Long = - inner.writeAll(source.toOkio()) + wrapOkio { inner.writeAll(source.toOkio()) } internal inline fun SdkBuffer.commonWriteUtf8(string: String, start: Int, endExclusive: Int) { - inner.writeUtf8(string, start, endExclusive) + wrapOkio { inner.writeUtf8(string, start, endExclusive) } } internal inline fun SdkBuffer.commonWriteByte(x: Byte) { - inner.writeByte(x.toInt()) + wrapOkio { inner.writeByte(x.toInt()) } } internal inline fun SdkBuffer.commonWriteShort(x: Short) { - inner.writeShort(x.toInt()) + wrapOkio { inner.writeShort(x.toInt()) } } internal inline fun SdkBuffer.commonWriteShortLe(x: Short) { - inner.writeShortLe(x.toInt()) + wrapOkio { inner.writeShortLe(x.toInt()) } } internal inline fun SdkBuffer.commonWriteInt(x: Int) { - inner.writeInt(x) + wrapOkio { inner.writeInt(x) } } internal inline fun SdkBuffer.commonWriteIntLe(x: Int) { - inner.writeIntLe(x) + wrapOkio { inner.writeIntLe(x) } } internal inline fun SdkBuffer.commonWriteLong(x: Long) { - inner.writeLong(x) + wrapOkio { inner.writeLong(x) } } internal inline fun SdkBuffer.commonWriteLongLe(x: Long) { - inner.writeLongLe(x) + wrapOkio { inner.writeLongLe(x) } } internal inline fun SdkBuffer.commonFlush() { - inner.flush() + wrapOkio { inner.flush() } } internal inline fun SdkBuffer.commonClose() { - inner.close() + wrapOkio { inner.close() } } diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt index 82d28aaac0..42f9fb4721 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt @@ -7,4 +7,14 @@ package aws.smithy.kotlin.runtime.io public actual typealias IOException = java.io.IOException -public actual typealias EOFException = java.io.EOFException +public actual open class EOFException actual constructor( + message: String?, + cause: Throwable? +) : java.io.EOFException(message) { + init { + initCause(cause) + } + + public actual constructor() : this(null, null) + public actual constructor(message: String?) : this(message, null) +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt index a5265fbb64..d754493c2d 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt @@ -12,6 +12,7 @@ public actual open class IOException actual constructor( public actual constructor(message: String?) : this(message, null) } -public actual open class EOFException actual constructor(message: String?) : IOException(message) { - public actual constructor() : this(null) +public actual open class EOFException actual constructor(message: String?, cause: Throwable?) : IOException(message) { + public actual constructor() : this(null, null) + public actual constructor(message: String?) : this(message, null) } From 53deb9f5971c856963e703194ec7f5af3cfbc1e1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 15:11:39 -0500 Subject: [PATCH 07/17] Wrap some functions I missed --- .../jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt | 6 +++--- .../src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt index 3fc01858e4..c318fcaeba 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt @@ -61,7 +61,7 @@ public actual class SdkBuffer : actual override fun read(sink: SdkBuffer, limit: Long): Long = commonRead(sink, limit) - override fun read(dst: ByteBuffer): Int = inner.read(dst) + override fun read(dst: ByteBuffer): Int = wrapOkio { inner.read(dst) } actual override fun readByteArray(): ByteArray = commonReadByteArray() @@ -87,7 +87,7 @@ public actual class SdkBuffer : actual override fun write(source: SdkBuffer, byteCount: Long): Unit = commonWrite(source, byteCount) - override fun write(src: ByteBuffer): Int = inner.write(src) + override fun write(src: ByteBuffer): Int = wrapOkio { inner.write(src) } actual override fun writeAll(source: SdkSource): Long = commonWriteAll(source) @@ -111,7 +111,7 @@ public actual class SdkBuffer : actual override fun flush(): Unit = commonFlush() actual override fun emit() { - inner.emit() + wrapOkio { inner.emit() } } actual override fun close(): Unit = commonClose() override fun isOpen(): Boolean = inner.isOpen diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt index 6e84610443..c0472cd857 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt @@ -60,7 +60,7 @@ public actual class SdkBuffer : actual override fun flush(): Unit = commonFlush() actual override fun emit() { - inner.emit() + wrapOkio { inner.emit() } } actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount) From f7550a4227648f3a954d8a5c9cb0ff61cc1a02b7 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 15:16:05 -0500 Subject: [PATCH 08/17] ktlint --- .../test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt | 1 - .../common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt | 1 - .../aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt | 1 - .../test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt | 1 - .../jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt | 2 +- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt index 0184a07dbf..33e86615ec 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/HashingSourceTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.hashing.* import kotlin.test.Test import kotlin.test.assertEquals diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt index ff036c3a00..4c6de56398 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/ObserversTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.internal.SdkSinkObserver import aws.smithy.kotlin.runtime.io.internal.SdkSourceObserver import kotlin.test.Test diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt index 5dfe1108c4..aad017ced9 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelSuspendTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.testing.ManualDispatchTestBase import io.kotest.matchers.string.shouldContain import kotlinx.coroutines.* diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt index 6a489a145e..d2d1435683 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkByteChannelTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import kotlinx.coroutines.yield diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt index 42f9fb4721..6d01916a93 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt @@ -9,7 +9,7 @@ public actual typealias IOException = java.io.IOException public actual open class EOFException actual constructor( message: String?, - cause: Throwable? + cause: Throwable?, ) : java.io.EOFException(message) { init { initCause(cause) From b58aaa73253ca780c57fc7c09f3debf889f022ed Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 15:50:40 -0500 Subject: [PATCH 09/17] apiDump --- runtime/runtime-core/api/runtime-core.api | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 9248eb7f13..182279b591 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -1029,12 +1029,6 @@ public abstract interface class aws/smithy/kotlin/runtime/io/SdkSource : java/io public abstract fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;J)J } -public final class aws/smithy/kotlin/runtime/io/SdkSourceJVMKt { - public static final fun readToByteArray (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun toSdkByteReadChannel (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; - public static synthetic fun toSdkByteReadChannel$default (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlinx/coroutines/CoroutineScope;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/io/SdkByteReadChannel; -} - public final class aws/smithy/kotlin/runtime/io/SdkSourceKt { public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkSource;Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V public static final fun readToByteArray (Laws/smithy/kotlin/runtime/io/SdkSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -1071,11 +1065,6 @@ public final class aws/smithy/kotlin/runtime/io/internal/JobChannel : aws/smithy public fun write (Laws/smithy/kotlin/runtime/io/SdkBuffer;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class aws/smithy/kotlin/runtime/io/internal/SdkDispatchers { - public static final field INSTANCE Laws/smithy/kotlin/runtime/io/internal/SdkDispatchers; - public final fun getIO ()Lkotlinx/coroutines/CoroutineDispatcher; -} - public abstract class aws/smithy/kotlin/runtime/io/internal/SdkSinkObserver : aws/smithy/kotlin/runtime/io/SdkSink { public fun (Laws/smithy/kotlin/runtime/io/SdkSink;)V public fun close ()V From 7a5cbed076253db24e4853e67d4ad557990ba2b1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 16:04:41 -0500 Subject: [PATCH 10/17] Restore SdkDispatchers --- .../runtime/auth/awssigning/Canonicalizer.kt | 3 ++- .../runtime/http/engine/crt/CrtHttpEngine.kt | 3 ++- .../kotlin/runtime/content/ByteStream.kt | 3 ++- .../kotlin/runtime/io/SdkByteReadChannel.kt | 5 +++-- .../runtime/io/internal/SdkDispatchers.kt | 21 +++++++++++++++++++ .../runtime/io/internal/SdkDispatchersJVM.kt | 15 +++++++++++++ .../io/internal/SdkDispatchersNative.kt | 19 +++++++++++++++++ 7 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt create mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt create mode 100644 runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt index eb821ecfcd..f5a954adc4 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt @@ -12,6 +12,7 @@ import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.http.request.toBuilder import aws.smithy.kotlin.runtime.io.* +import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import aws.smithy.kotlin.runtime.net.url.QueryParameters import aws.smithy.kotlin.runtime.net.url.Url import aws.smithy.kotlin.runtime.net.url.UrlPath @@ -163,7 +164,7 @@ internal class DefaultCanonicalizer(private val sha256Supplier: HashSupplier = : } is HttpBody.SourceContent -> { val source = readFrom() - withContext(Dispatchers.IO) { + withContext(SdkDispatchers.IO) { source.sha256().encodeToHex() } } diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt index 545cfb271f..40a38a9a90 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt @@ -11,6 +11,7 @@ import aws.smithy.kotlin.runtime.http.engine.HttpClientEngine import aws.smithy.kotlin.runtime.http.engine.HttpClientEngineBase import aws.smithy.kotlin.runtime.http.engine.callContext import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import aws.smithy.kotlin.runtime.operation.ExecutionContext import aws.smithy.kotlin.runtime.telemetry.logging.logger import aws.smithy.kotlin.runtime.time.Instant @@ -83,7 +84,7 @@ public class CrtHttpEngine(public override val config: CrtHttpEngineConfig) : Ht } if (request.isChunked) { - withContext(Dispatchers.IO) { + withContext(SdkDispatchers.IO) { stream.sendChunkedBody(request.body) } } diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt index 6d88fa5fae..e9a52b4c36 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.content import aws.smithy.kotlin.runtime.io.* +import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -120,7 +121,7 @@ public fun ByteStream.cancel() { public fun ByteStream.toFlow(bufferSize: Long = 8192): Flow = when (this) { is ByteStream.Buffer -> flowOf(bytes()) is ByteStream.ChannelStream -> readFrom().toFlow(bufferSize) - is ByteStream.SourceStream -> readFrom().toFlow(bufferSize).flowOn(Dispatchers.IO) + is ByteStream.SourceStream -> readFrom().toFlow(bufferSize).flowOn(SdkDispatchers.IO) } /** diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index 1dffecf5e8..fc9db5ff02 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.io +import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.withContext @@ -105,7 +106,7 @@ public suspend fun SdkByteReadChannel.readToBuffer(): SdkBuffer { /** * Read all bytes from this channel into [sink]. Returns the total number of bytes written. */ -public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext(Dispatchers.IO) { +public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext(SdkDispatchers.IO) { val bufferedSink = sink.buffer() var totalWritten = 0L while (true) { @@ -121,7 +122,7 @@ public suspend fun SdkByteReadChannel.readAll(sink: SdkSink): Long = withContext /** * Removes all bytes from [source] and writes them to this channel. Returns the total number of bytes read. */ -public suspend fun SdkByteWriteChannel.writeAll(source: SdkSource): Long = withContext(Dispatchers.IO) { +public suspend fun SdkByteWriteChannel.writeAll(source: SdkSource): Long = withContext(SdkDispatchers.IO) { val buffer = SdkBuffer() var totalRead = 0L while (true) { diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt new file mode 100644 index 0000000000..068f1b796a --- /dev/null +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchers.kt @@ -0,0 +1,21 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.smithy.kotlin.runtime.io.internal + +import aws.smithy.kotlin.runtime.InternalApi +import kotlinx.coroutines.CoroutineDispatcher + +/** + * Internal coroutine dispatchers used by the SDK + */ +@InternalApi +public expect object SdkDispatchers { + /** + * The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads. + * On JVM this is guaranteed to be `Dispatchers.IO` + */ + public val IO: CoroutineDispatcher +} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt new file mode 100644 index 0000000000..2f0af6738c --- /dev/null +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersJVM.kt @@ -0,0 +1,15 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package aws.smithy.kotlin.runtime.io.internal + +import aws.smithy.kotlin.runtime.InternalApi +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +@InternalApi +public actual object SdkDispatchers { + public actual val IO: CoroutineDispatcher = Dispatchers.IO +} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt new file mode 100644 index 0000000000..de34d71300 --- /dev/null +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/internal/SdkDispatchersNative.kt @@ -0,0 +1,19 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io.internal + +import aws.smithy.kotlin.runtime.InternalApi +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO + +@InternalApi +public actual object SdkDispatchers { + /** + * The CoroutineDispatcher that is designed for offloading blocking IO tasks to a shared pool of threads. + */ + public actual val IO: CoroutineDispatcher + get() = Dispatchers.IO +} From bc91650ce84a516a3710dc9caa62834575f4470b Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 16:06:14 -0500 Subject: [PATCH 11/17] ktlint, apiDump --- .../smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt | 1 - runtime/runtime-core/api/runtime-core.api | 5 +++++ .../src/aws/smithy/kotlin/runtime/content/ByteStream.kt | 1 - .../src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt index f5a954adc4..7b3c4c1301 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt @@ -20,7 +20,6 @@ import aws.smithy.kotlin.runtime.text.encoding.Encodable import aws.smithy.kotlin.runtime.text.encoding.PercentEncoding import aws.smithy.kotlin.runtime.text.encoding.encodeToHex import aws.smithy.kotlin.runtime.time.TimestampFormat -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.withContext diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index 182279b591..a94307b9d4 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -1065,6 +1065,11 @@ public final class aws/smithy/kotlin/runtime/io/internal/JobChannel : aws/smithy public fun write (Laws/smithy/kotlin/runtime/io/SdkBuffer;JLkotlin/coroutines/Continuation;)Ljava/lang/Object; } +public final class aws/smithy/kotlin/runtime/io/internal/SdkDispatchers { + public static final field INSTANCE Laws/smithy/kotlin/runtime/io/internal/SdkDispatchers; + public final fun getIO ()Lkotlinx/coroutines/CoroutineDispatcher; +} + public abstract class aws/smithy/kotlin/runtime/io/internal/SdkSinkObserver : aws/smithy/kotlin/runtime/io/SdkSink { public fun (Laws/smithy/kotlin/runtime/io/SdkSink;)V public fun close ()V diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt index e9a52b4c36..58f0fa1b4c 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/content/ByteStream.kt @@ -7,7 +7,6 @@ package aws.smithy.kotlin.runtime.content import aws.smithy.kotlin.runtime.io.* import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index fc9db5ff02..b205976a06 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.withContext From a992b338bc646b0e83d61e4db69e093544b133fc Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 16:08:52 -0500 Subject: [PATCH 12/17] SdkDispatchers --- .../common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt index 10876a48d4..aefb75dc08 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkSource.kt @@ -7,12 +7,11 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.InternalApi import aws.smithy.kotlin.runtime.io.internal.JobChannel +import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.IO import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -52,7 +51,7 @@ public interface SdkSource : Closeable { * Consume the [SdkSource] and pull the entire contents into memory as a [ByteArray]. */ @InternalApi -public suspend fun SdkSource.readToByteArray(): ByteArray = withContext(Dispatchers.IO) { +public suspend fun SdkSource.readToByteArray(): ByteArray = withContext(SdkDispatchers.IO) { use { it.buffer().readByteArray() } } @@ -68,7 +67,7 @@ public fun SdkSource.toSdkByteReadChannel(coroutineScope: CoroutineScope? = null val source = this val ch = JobChannel() val scope = coroutineScope ?: GlobalScope - val job = scope.launch(Dispatchers.IO + CoroutineName("sdk-source-reader")) { + val job = scope.launch(SdkDispatchers.IO + CoroutineName("sdk-source-reader")) { val buffer = SdkBuffer() val result = runCatching { source.use { From 2fed4c32646b9d69601b3e809b6a7eceb32a2186 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 17:24:53 -0500 Subject: [PATCH 13/17] Remove unused import --- .../aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt index 7b3c4c1301..69d742de79 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/Canonicalizer.kt @@ -20,7 +20,6 @@ import aws.smithy.kotlin.runtime.text.encoding.Encodable import aws.smithy.kotlin.runtime.text.encoding.PercentEncoding import aws.smithy.kotlin.runtime.text.encoding.encodeToHex import aws.smithy.kotlin.runtime.time.TimestampFormat -import kotlinx.coroutines.IO import kotlinx.coroutines.withContext /** From 52d3c96d40a77edfc52a7ebfc4602942595a39fd Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 17:26:09 -0500 Subject: [PATCH 14/17] Add Okio exception message --- .../aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt | 4 ++-- .../aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt index ba618359de..00534f98d7 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt @@ -38,9 +38,9 @@ internal expect class BufferedSourceAdapter(source: okio.BufferedSource) : SdkBu internal inline fun SdkBufferedSource.wrapOkio(block: SdkBufferedSource.() -> T): T = try { block() } catch (e: okio.EOFException) { - throw EOFException("Okio operation failed", e) + throw EOFException("Okio operation failed: ${e.message}", e) } catch (e: okio.IOException) { - throw IOException("Okio operation failed", e) + throw IOException("Okio operation failed: ${e.message}", e) } // base class that fills in most of the common implementation, platforms just need to implement the platform specific diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt index 0dbafcbba0..e5cd2a8f70 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/internal/BufferOperations.kt @@ -15,9 +15,9 @@ import aws.smithy.kotlin.runtime.io.* internal inline fun SdkBuffer.wrapOkio(block: SdkBuffer.() -> T): T = try { block() } catch (e: okio.EOFException) { - throw EOFException("Okio operation failed", e) + throw EOFException("Okio operation failed: ${e.message}", e) } catch (e: okio.IOException) { - throw IOException("Okio operation failed", e) + throw IOException("Okio operation failed: ${e.message}", e) } internal inline fun SdkBuffer.commonSkip(byteCount: Long) = wrapOkio { inner.skip(byteCount) } From fd21fa09407d852dfb753d16d32050441b3dce88 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 9 Jan 2025 17:26:31 -0500 Subject: [PATCH 15/17] Pass `cause` to super class --- .../native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt index d754493c2d..631e84c1bf 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/ExceptionsNative.kt @@ -12,7 +12,7 @@ public actual open class IOException actual constructor( public actual constructor(message: String?) : this(message, null) } -public actual open class EOFException actual constructor(message: String?, cause: Throwable?) : IOException(message) { +public actual open class EOFException actual constructor(message: String?, cause: Throwable?) : IOException(message, cause) { public actual constructor() : this(null, null) public actual constructor(message: String?) : this(message, null) } From 00249346d3f3ab734a363e86b4176f81b8f861ab Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Fri, 10 Jan 2025 11:36:23 -0500 Subject: [PATCH 16/17] SdkBuffer -> jvmAndNative --- .../runtime/crt/ReadChannelBodyStreamJvm.kt | 1 + runtime/runtime-core/api/runtime-core.api | 17 +-- .../kotlin/runtime/io/BufferedSinkAdapter.kt | 2 +- .../runtime/io/BuffereredSourceAdapter.kt | 2 +- .../kotlin/runtime/content/ByteStreamJVM.kt | 9 +- .../runtime/io/BufferedSinkAdapterJVM.kt | 20 --- .../runtime/io/BufferedSourceAdapterJVM.kt | 21 --- .../aws/smithy/kotlin/runtime/io/JavaIO.kt | 18 +++ .../smithy/kotlin/runtime/io/SdkBufferJVM.kt | 121 --------------- .../kotlin/runtime/io/SdkBufferedSinkJVM.kt | 109 ------------- .../kotlin/runtime/io/SdkBufferedSourceJVM.kt | 144 ------------------ .../io/BufferedSinkAdapterJvmAndNative.kt} | 3 + .../io/BufferedSourceAdapterJvmAndNative.kt} | 0 .../runtime/io/SdkBufferJvmAndNative.kt} | 0 .../io/SdkBufferedSinkJvmAndNative.kt} | 0 .../io/SdkBufferedSourceJvmAndNative.kt} | 0 16 files changed, 39 insertions(+), 428 deletions(-) delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJVM.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJVM.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJVM.kt delete mode 100644 runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJVM.kt rename runtime/runtime-core/{native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt => jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt} (83%) rename runtime/runtime-core/{native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt => jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt} (100%) rename runtime/runtime-core/{native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt => jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt} (100%) rename runtime/runtime-core/{native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkNative.kt => jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJvmAndNative.kt} (100%) rename runtime/runtime-core/{native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceNative.kt => jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJvmAndNative.kt} (100%) diff --git a/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt index 7703ef5895..cb2e691167 100644 --- a/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt +++ b/runtime/crt-util/jvm/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamJvm.kt @@ -7,5 +7,6 @@ package aws.smithy.kotlin.runtime.crt import aws.sdk.kotlin.crt.io.MutableBuffer import aws.smithy.kotlin.runtime.io.SdkBuffer +import aws.smithy.kotlin.runtime.io.read internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer) = outgoing.read(dest.buffer) diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index a94307b9d4..b3b4e230b7 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -811,6 +811,10 @@ public final class aws/smithy/kotlin/runtime/io/HashingSource : aws/smithy/kotli } public final class aws/smithy/kotlin/runtime/io/JavaIOKt { + public static final fun inputStream (Laws/smithy/kotlin/runtime/io/SdkBuffer;)Ljava/io/InputStream; + public static final fun isOpen (Laws/smithy/kotlin/runtime/io/SdkBuffer;)Z + public static final fun outputStream (Laws/smithy/kotlin/runtime/io/SdkBuffer;)Ljava/io/OutputStream; + public static final fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;Ljava/nio/ByteBuffer;)I public static final fun sink (Ljava/io/File;)Laws/smithy/kotlin/runtime/io/SdkSink; public static final fun sink (Ljava/io/OutputStream;)Laws/smithy/kotlin/runtime/io/SdkSink; public static final fun sink (Ljava/nio/file/Path;)Laws/smithy/kotlin/runtime/io/SdkSink; @@ -821,6 +825,7 @@ public final class aws/smithy/kotlin/runtime/io/JavaIOKt { public static final fun source (Ljava/nio/file/Path;Lkotlin/ranges/LongRange;)Laws/smithy/kotlin/runtime/io/SdkSource; public static synthetic fun source$default (Ljava/io/File;JJILjava/lang/Object;)Laws/smithy/kotlin/runtime/io/SdkSource; public static synthetic fun source$default (Ljava/nio/file/Path;JJILjava/lang/Object;)Laws/smithy/kotlin/runtime/io/SdkSource; + public static final fun write (Laws/smithy/kotlin/runtime/io/SdkBuffer;Ljava/nio/ByteBuffer;)I } public final class aws/smithy/kotlin/runtime/io/SdkBuffer : aws/smithy/kotlin/runtime/io/SdkBufferedSink, aws/smithy/kotlin/runtime/io/SdkBufferedSource { @@ -833,12 +838,8 @@ public final class aws/smithy/kotlin/runtime/io/SdkBuffer : aws/smithy/kotlin/ru public fun getBuffer ()Laws/smithy/kotlin/runtime/io/SdkBuffer; public final fun getSize ()J public fun hashCode ()I - public fun inputStream ()Ljava/io/InputStream; - public fun isOpen ()Z - public fun outputStream ()Ljava/io/OutputStream; public fun peek ()Laws/smithy/kotlin/runtime/io/SdkBufferedSource; public fun read (Laws/smithy/kotlin/runtime/io/SdkBuffer;J)J - public fun read (Ljava/nio/ByteBuffer;)I public fun read ([BII)I public fun readAll (Laws/smithy/kotlin/runtime/io/SdkSink;)J public fun readByte ()B @@ -858,7 +859,6 @@ public final class aws/smithy/kotlin/runtime/io/SdkBuffer : aws/smithy/kotlin/ru public fun toString ()Ljava/lang/String; public fun write (Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V public fun write (Laws/smithy/kotlin/runtime/io/SdkSource;J)V - public fun write (Ljava/nio/ByteBuffer;)I public fun write ([BII)V public fun writeAll (Laws/smithy/kotlin/runtime/io/SdkSource;)J public fun writeByte (B)V @@ -871,11 +871,9 @@ public final class aws/smithy/kotlin/runtime/io/SdkBuffer : aws/smithy/kotlin/ru public fun writeUtf8 (Ljava/lang/String;II)V } -public abstract interface class aws/smithy/kotlin/runtime/io/SdkBufferedSink : aws/smithy/kotlin/runtime/io/SdkSink, java/nio/channels/WritableByteChannel { +public abstract interface class aws/smithy/kotlin/runtime/io/SdkBufferedSink : aws/smithy/kotlin/runtime/io/SdkSink { public abstract fun emit ()V - public abstract fun flush ()V public abstract fun getBuffer ()Laws/smithy/kotlin/runtime/io/SdkBuffer; - public abstract fun outputStream ()Ljava/io/OutputStream; public abstract fun write (Laws/smithy/kotlin/runtime/io/SdkSource;J)V public abstract fun write ([BII)V public abstract fun writeAll (Laws/smithy/kotlin/runtime/io/SdkSource;)J @@ -894,10 +892,9 @@ public final class aws/smithy/kotlin/runtime/io/SdkBufferedSink$DefaultImpls { public static synthetic fun writeUtf8$default (Laws/smithy/kotlin/runtime/io/SdkBufferedSink;Ljava/lang/String;IIILjava/lang/Object;)V } -public abstract interface class aws/smithy/kotlin/runtime/io/SdkBufferedSource : aws/smithy/kotlin/runtime/io/SdkSource, java/nio/channels/ReadableByteChannel { +public abstract interface class aws/smithy/kotlin/runtime/io/SdkBufferedSource : aws/smithy/kotlin/runtime/io/SdkSource { public abstract fun exhausted ()Z public abstract fun getBuffer ()Laws/smithy/kotlin/runtime/io/SdkBuffer; - public abstract fun inputStream ()Ljava/io/InputStream; public abstract fun peek ()Laws/smithy/kotlin/runtime/io/SdkBufferedSource; public abstract fun read ([BII)I public abstract fun readAll (Laws/smithy/kotlin/runtime/io/SdkSink;)J diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt index 178e210a02..eaa85b35b1 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapter.kt @@ -30,7 +30,7 @@ internal expect class BufferedSinkAdapter(sink: okio.BufferedSink) : SdkBuffered // base class that fills in most of the common implementation, platforms just need to implement the platform specific // part of the interface internal abstract class AbstractBufferedSinkAdapter( - protected val delegate: okio.BufferedSink, + internal val delegate: okio.BufferedSink, ) : SdkBufferedSink { override fun toString(): String = delegate.toString() diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt index 00534f98d7..e1842e26dc 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/BuffereredSourceAdapter.kt @@ -46,7 +46,7 @@ internal inline fun SdkBufferedSource.wrapOkio(block: SdkBufferedSource.() - // base class that fills in most of the common implementation, platforms just need to implement the platform specific // part of the interface internal abstract class AbstractBufferedSourceAdapter( - protected val delegate: okio.BufferedSource, + internal val delegate: okio.BufferedSource, ) : SdkBufferedSource { override val buffer: SdkBuffer get() = delegate.buffer.toSdk() diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt index 5647ac15af..9d1a03d49a 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/content/ByteStreamJVM.kt @@ -96,7 +96,14 @@ public suspend fun ByteStream.writeToFile(path: Path): Long = writeToFile(path.t public fun ByteStream.toInputStream(): InputStream = when (this) { is ByteStream.Buffer -> ByteArrayInputStream(bytes()) is ByteStream.ChannelStream -> readFrom().toInputStream() - is ByteStream.SourceStream -> readFrom().buffer().inputStream() + is ByteStream.SourceStream -> { + val buffer = (readFrom().buffer()) + when (buffer) { + is SdkBuffer -> buffer.inputStream() + is BufferedSourceAdapter -> buffer.inputStream() + else -> throw IllegalStateException("Buffer class ${buffer::class.simpleName} could not be converted to an InputStream") + } + } } /** diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJVM.kt deleted file mode 100644 index 404dd6d078..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJVM.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import java.io.OutputStream -import java.nio.ByteBuffer - -internal actual class BufferedSinkAdapter actual constructor( - sink: okio.BufferedSink, -) : AbstractBufferedSinkAdapter(sink), - SdkBufferedSink { - override fun write(src: ByteBuffer): Int = delegate.write(src) - - override fun isOpen(): Boolean = delegate.isOpen - - override fun outputStream(): OutputStream = delegate.outputStream() -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJVM.kt deleted file mode 100644 index e7b1c3d759..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJVM.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import java.io.InputStream -import java.nio.ByteBuffer - -internal actual class BufferedSourceAdapter actual constructor( - source: okio.BufferedSource, -) : AbstractBufferedSourceAdapter(source), - SdkBufferedSource { - - override fun read(dst: ByteBuffer): Int = delegate.read(dst) - - override fun isOpen(): Boolean = delegate.isOpen - - override fun inputStream(): InputStream = delegate.inputStream() -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt index e7578bfea4..c0ea0a6bf6 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt @@ -9,6 +9,7 @@ import aws.smithy.kotlin.runtime.io.internal.toSdk import java.io.File import java.io.InputStream import java.io.OutputStream +import java.nio.ByteBuffer import java.nio.file.Path import okio.sink as okioSink import okio.source as okioSource @@ -59,3 +60,20 @@ public fun InputStream.source(): SdkSource = okioSource().toSdk() * Create a new [SdkSource] that reads from this [InputStream] */ public fun OutputStream.sink(): SdkSink = okioSink().toSdk() + +// BufferedSinkAdapter +internal fun BufferedSinkAdapter.outputStream(): OutputStream = delegate.outputStream() +internal fun BufferedSinkAdapter.write(src: ByteBuffer): Int = delegate.write(src) +internal fun BufferedSinkAdapter.isOpen(): Boolean = delegate.isOpen + +// BufferedSourceAdapter +internal fun BufferedSourceAdapter.read(dst: ByteBuffer): Int = delegate.read(dst) +internal fun BufferedSourceAdapter.isOpen(): Boolean = delegate.isOpen +internal fun BufferedSourceAdapter.inputStream(): InputStream = delegate.inputStream() + +// SdkBuffer +public fun SdkBuffer.read(dst: ByteBuffer): Int = wrapOkio { inner.read(dst) } +public fun SdkBuffer.write(src: ByteBuffer): Int = wrapOkio { inner.write(src) } +public fun SdkBuffer.isOpen(): Boolean = inner.isOpen +public fun SdkBuffer.inputStream(): InputStream = inner.inputStream() +public fun SdkBuffer.outputStream(): OutputStream = inner.outputStream() \ No newline at end of file diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt deleted file mode 100644 index c318fcaeba..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import aws.smithy.kotlin.runtime.io.internal.* -import java.io.InputStream -import java.io.OutputStream -import java.nio.ByteBuffer - -public actual class SdkBuffer : - SdkBufferedSource, - SdkBufferedSink { - public actual constructor() : this(okio.Buffer()) - - internal actual val inner: okio.Buffer - - internal actual constructor(buffer: okio.Buffer) { - this.inner = buffer - } - - public actual val size: Long - get() = inner.size - - actual override val buffer: SdkBuffer - get() = this - - override fun toString(): String = inner.toString() - - override fun hashCode(): Int = inner.hashCode() - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is SdkBuffer) return false - return inner == other.inner - } - - actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount) - - actual override fun readByte(): Byte = commonReadByte() - - actual override fun readShort(): Short = commonReadShort() - - actual override fun readShortLe(): Short = commonReadShortLe() - - actual override fun readLong(): Long = commonReadLong() - - actual override fun readLongLe(): Long = commonReadLongLe() - - actual override fun readInt(): Int = commonReadInt() - - actual override fun readIntLe(): Int = commonReadIntLe() - - actual override fun readAll(sink: SdkSink): Long = commonReadAll(sink) - - actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int = - commonRead(sink, offset, limit) - - actual override fun read(sink: SdkBuffer, limit: Long): Long = - commonRead(sink, limit) - - override fun read(dst: ByteBuffer): Int = wrapOkio { inner.read(dst) } - - actual override fun readByteArray(): ByteArray = commonReadByteArray() - - actual override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount) - - actual override fun readUtf8(): String = commonReadUtf8() - - actual override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount) - - actual override fun peek(): SdkBufferedSource = commonPeek() - - actual override fun exhausted(): Boolean = commonExhausted() - actual override fun request(byteCount: Long): Boolean = commonRequest(byteCount) - - actual override fun require(byteCount: Long): Unit = commonRequire(byteCount) - - actual override fun write(source: ByteArray, offset: Int, limit: Int): Unit = - commonWrite(source, offset, limit) - - actual override fun write(source: SdkSource, byteCount: Long): Unit = - commonWrite(source, byteCount) - - actual override fun write(source: SdkBuffer, byteCount: Long): Unit = - commonWrite(source, byteCount) - - override fun write(src: ByteBuffer): Int = wrapOkio { inner.write(src) } - - actual override fun writeAll(source: SdkSource): Long = commonWriteAll(source) - - actual override fun writeUtf8(string: String, start: Int, endExclusive: Int): Unit = - commonWriteUtf8(string, start, endExclusive) - - actual override fun writeByte(x: Byte): Unit = commonWriteByte(x) - - actual override fun writeShort(x: Short): Unit = commonWriteShort(x) - - actual override fun writeShortLe(x: Short): Unit = commonWriteShortLe(x) - - actual override fun writeInt(x: Int): Unit = commonWriteInt(x) - - actual override fun writeIntLe(x: Int): Unit = commonWriteIntLe(x) - - actual override fun writeLong(x: Long): Unit = commonWriteLong(x) - - actual override fun writeLongLe(x: Long): Unit = commonWriteLongLe(x) - - actual override fun flush(): Unit = commonFlush() - - actual override fun emit() { - wrapOkio { inner.emit() } - } - actual override fun close(): Unit = commonClose() - override fun isOpen(): Boolean = inner.isOpen - - override fun inputStream(): InputStream = inner.inputStream() - override fun outputStream(): OutputStream = inner.outputStream() -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJVM.kt deleted file mode 100644 index 6a44c557a3..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJVM.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import java.io.OutputStream -import java.nio.channels.WritableByteChannel -import kotlin.jvm.Throws - -/** - * A sink that keeps a buffer internally so that callers can do small writes without - * a performance penalty. - */ -public actual sealed interface SdkBufferedSink : - SdkSink, - WritableByteChannel { - /** - * The underlying buffer for this sink - */ - public actual val buffer: SdkBuffer - - /** - * Write [limit] bytes from [source] starting at [offset] - */ - @Throws(IOException::class) - public actual fun write(source: ByteArray, offset: Int, limit: Int): Unit - - /** - * Write all bytes from [source] to this sink. - * @return the number of bytes read which will be 0 if [source] is exhausted - */ - @Throws(IOException::class) - public actual fun writeAll(source: SdkSource): Long - - /** - * Removes [byteCount] bytes from [source] and writes them to this sink. - */ - @Throws(IOException::class) - public actual fun write(source: SdkSource, byteCount: Long): Unit - - /** - * Write UTF8-bytes of [string] to this sink starting at [start] index up to [endExclusive] index. - */ - @Throws(IOException::class) - public actual fun writeUtf8(string: String, start: Int, endExclusive: Int): Unit - - /** - * Writes byte [x] to this sink - */ - @Throws(IOException::class) - public actual fun writeByte(x: Byte): Unit - - /** - * Writes short [x] as a big-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeShort(x: Short): Unit - - /** - * Writes short [x] as a little-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeShortLe(x: Short): Unit - - /** - * Writes int [x] as a big-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeInt(x: Int): Unit - - /** - * Writes int [x] as a little-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeIntLe(x: Int): Unit - - /** - * Writes long [x] as a big-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeLong(x: Long): Unit - - /** - * Writes long [x] as a little-endian bytes to this sink - */ - @Throws(IOException::class) - public actual fun writeLongLe(x: Long): Unit - - /** - * Return an output stream that writes to this sink - */ - public fun outputStream(): OutputStream - - /** - * Writes all buffered data to the underlying sink. - */ - @Throws(IOException::class) - actual override fun flush(): Unit - - /** - * Writes all buffered data to the underlying sink. Like flush, but weaker (ensures data is pushed to the - * underlying sink but not necessarily all the way down the chain like [flush] does). Call before this sink - * goes out of scope to ensure any buffered data eventually gets to its final destination - */ - @Throws(IOException::class) - public actual fun emit(): Unit -} diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJVM.kt deleted file mode 100644 index 076502f7c5..0000000000 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJVM.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -package aws.smithy.kotlin.runtime.io - -import java.io.InputStream -import java.nio.channels.ReadableByteChannel - -public actual sealed interface SdkBufferedSource : - SdkSource, - ReadableByteChannel { - - /** - * The underlying buffer for this source - */ - public actual val buffer: SdkBuffer - - /** - * Discards [byteCount] bytes from this source. Throws [IOException] if source is exhausted before [byteCount] - * bytes can be discarded. - */ - @Throws(IOException::class) - public actual fun skip(byteCount: Long) - - /** - * Read a single byte from this source and return it - */ - @Throws(IOException::class) - public actual fun readByte(): Byte - - /** - * Read two bytes in big-endian order from this source and returns them as a short. - */ - @Throws(IOException::class) - public actual fun readShort(): Short - - /** - * Read two bytes in little-endian order from this source and returns them as a short. - */ - @Throws(IOException::class) - public actual fun readShortLe(): Short - - /** - * Read eight bytes in big-endian order from this source and returns them as a long. - */ - @Throws(IOException::class) - public actual fun readLong(): Long - - /** - * Read eight bytes in little-endian order from this source and returns them as a long. - */ - @Throws(IOException::class) - public actual fun readLongLe(): Long - - /** - * Read four bytes in big-endian order from this source and returns them as an int. - */ - @Throws(IOException::class) - public actual fun readInt(): Int - - /** - * Read four bytes in little-endian order from this source and returns them as an int. - */ - @Throws(IOException::class) - public actual fun readIntLe(): Int - - /** - * Reads all bytes from this and appends them to [sink]. Returns - * the total number of bytes written which will be 0 if this source - * is exhausted. - */ - @Throws(IOException::class) - public actual fun readAll(sink: SdkSink): Long - - /** - * Read up to [limit] bytes and write them to [sink] starting at [offset] - */ - @Throws(IOException::class) - public actual fun read(sink: ByteArray, offset: Int, limit: Int): Int - - /** - * Reads all bytes from this source and returns them as a byte array - * - * **Caution** This may pull a large amount of data into memory, only do this if you are sure - * the contents fit into memory. Throws [IllegalArgumentException] if the buffer size exceeds [Int.MAX_VALUE]. - */ - @Throws(IOException::class) - public actual fun readByteArray(): ByteArray - - /** - * Reads [byteCount] bytes from this source and returns them as a byte array - */ - @Throws(IOException::class) - public actual fun readByteArray(byteCount: Long): ByteArray - - /** - * Reads all bytes from this source, decodes them as UTF-8, and returns the string. - * - * **Caution** This may pull a large amount of data into memory, only do this if you are sure - * the contents fit into memory. Throws [IllegalArgumentException] if the buffer size exceeds [Int.MAX_VALUE]. - */ - @Throws(IOException::class) - public actual fun readUtf8(): String - - /** - * Reads [byteCount] bytes from this source, decodes them as UTF-8, and returns the string. - */ - @Throws(IOException::class) - public actual fun readUtf8(byteCount: Long): String - - /** - * Get an input stream that reads from this source - */ - public fun inputStream(): InputStream - - /** - * Returns a new [SdkBufferedSource] that can read data from this source - * without consuming it. The returned source becomes invalid once this source is next - * read or closed. - */ - public actual fun peek(): SdkBufferedSource - - /** - * Returns true if there are no more bytes in this source. This will block until there are bytes - * to read or the source is definitely exhausted. - */ - public actual fun exhausted(): Boolean - - /** - * Returns true when the buffer contains at least [byteCount] bytes. False if the source - * is exhausted before the requested number of bytes could be read - */ - @Throws(IOException::class) - public actual fun request(byteCount: Long): Boolean - - /** - * Returns when the buffer contains at least [byteCount] bytes or throws [EOFException] - * if the source is exhausted before the requested number of bytes could be read - */ - @Throws(IOException::class) - public actual fun require(byteCount: Long): Unit -} diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt similarity index 83% rename from runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt index bf5767cf35..7205c8d6a1 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt +++ b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt @@ -4,6 +4,9 @@ */ package aws.smithy.kotlin.runtime.io +import aws.smithy.kotlin.runtime.InternalApi + +@InternalApi internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : AbstractBufferedSinkAdapter(sink), SdkBufferedSink diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt similarity index 100% rename from runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt similarity index 100% rename from runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJvmAndNative.kt similarity index 100% rename from runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkNative.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSinkJvmAndNative.kt diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJvmAndNative.kt similarity index 100% rename from runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceNative.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferedSourceJvmAndNative.kt From 4dd47dc5b44138a07c0eadbd6c73074ba5f385a1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Fri, 10 Jan 2025 11:36:53 -0500 Subject: [PATCH 17/17] ktlint --- .../runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt index c0ea0a6bf6..c035aa9a4c 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt +++ b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt @@ -76,4 +76,4 @@ public fun SdkBuffer.read(dst: ByteBuffer): Int = wrapOkio { inner.read(dst) } public fun SdkBuffer.write(src: ByteBuffer): Int = wrapOkio { inner.write(src) } public fun SdkBuffer.isOpen(): Boolean = inner.isOpen public fun SdkBuffer.inputStream(): InputStream = inner.inputStream() -public fun SdkBuffer.outputStream(): OutputStream = inner.outputStream() \ No newline at end of file +public fun SdkBuffer.outputStream(): OutputStream = inner.outputStream()