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 d89ff828fb..b3b4e230b7 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 @@ -805,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; @@ -815,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 { @@ -827,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 @@ -852,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 @@ -865,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 @@ -888,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 @@ -1023,16 +1026,13 @@ 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 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/SdkSourceKt { - public static final fun readFully (Laws/smithy/kotlin/runtime/io/SdkSource;Laws/smithy/kotlin/runtime/io/SdkBuffer;J)V -} - public final class aws/smithy/kotlin/runtime/io/internal/ConvertKt { public static final fun toOkio (Laws/smithy/kotlin/runtime/io/SdkBuffer;)Lokio/Buffer; public static final fun toOkio (Laws/smithy/kotlin/runtime/io/SdkSink;)Lokio/Sink; 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..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,6 +7,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.IO import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch 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 8b92fbbe64..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 @@ -32,53 +32,76 @@ 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.message}", e) +} catch (e: okio.IOException) { + 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 // 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() - 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/SdkByteReadChannel.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/io/SdkByteReadChannel.kt index 87d5a531da..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,6 +5,7 @@ package aws.smithy.kotlin.runtime.io import aws.smithy.kotlin.runtime.io.internal.SdkDispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.withContext /** 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..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 @@ -6,7 +6,15 @@ 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.GlobalScope +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 +51,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(SdkDispatchers.IO) { + use { it.buffer().readByteArray() } +} /** * Convert the [SdkSource] to an [SdkByteReadChannel]. Content is read from the source and forwarded @@ -51,8 +61,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(SdkDispatchers.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/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..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 @@ -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.message}", e) +} catch (e: okio.IOException) { + throw IOException("Okio operation failed: ${e.message}", 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/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..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 @@ -14,7 +13,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 +32,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..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,14 +5,12 @@ 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 import kotlin.test.assertEquals class ObserversTest { - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSdkSourceObserver() { val source = SdkBuffer() @@ -35,7 +33,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 3469c996fe..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 @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.Test import kotlin.test.assertContentEquals import kotlin.test.assertEquals @@ -25,7 +24,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 +34,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 +42,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 +50,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 +57,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 +64,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 +71,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 +78,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("[hex=deadbeef10203040]", data.toString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteString() { sink.writeUtf8("レップはボールです") @@ -94,7 +85,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 +92,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 +102,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 +116,6 @@ abstract class AbstractBufferedSinkTest( assertEquals("12341234", data.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testWriteEof() { val source: SdkSource = SdkBuffer().apply { writeUtf8("1234") } @@ -137,7 +124,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 +131,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 +141,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 +148,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 +157,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 +166,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/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/io/SdkBufferedSourceTest.kt index ed5430c8f2..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 @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.io -import aws.smithy.kotlin.runtime.IgnoreNative import kotlin.test.* /** @@ -57,7 +56,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 +68,6 @@ abstract class BufferedSourceTest( assertTrue(source.exhausted()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadEmpty() { assertFailsWith { @@ -78,7 +75,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadShort() { sink.write(bytes(0xde, 0xad, 0xbe, 0xef)) @@ -87,7 +83,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 +91,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 +98,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 +105,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 +112,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 +119,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 +130,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 +145,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 +153,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 +161,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 +172,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 +183,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 +193,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 +202,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testSkip() { val content = ByteArray(16 * 1024) { it.toByte() } @@ -232,7 +213,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 +224,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testPeek() { sink.writeUtf8("a flix is a comb") @@ -258,7 +237,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 +254,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 +274,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 +292,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testRequest() { sink.writeUtf8("123456789".repeat(1024)) @@ -327,7 +302,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 +313,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFully() { val data = "123456789".repeat(1024) @@ -351,7 +324,6 @@ abstract class BufferedSourceTest( assertEquals(data, dest.readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyIllegalArgumentException() { val dest = SdkBuffer() @@ -360,7 +332,6 @@ abstract class BufferedSourceTest( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyEOFException() { val data = "123456789".repeat(1024) 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..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.* @@ -30,7 +29,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 +59,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 +86,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 +115,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 +139,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 +152,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(3) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToEmptyFromFailedChannel() = runTest { expect(1) @@ -170,7 +163,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadToEmptyFromClosedChannel() = runTest { expect(1) @@ -182,7 +174,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(3) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromFailedChannel() = runTest { expect(1) @@ -194,7 +185,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromClosedChannelNoSuspend() = runTest { expect(1) @@ -204,7 +194,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFromClosedChannelSuspend() = runTest { expect(1) @@ -224,7 +213,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyFromFailedChannel() = runTest { expect(1) @@ -236,7 +224,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyFromClosedChannel() = runTest { expect(1) @@ -248,7 +235,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(2) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadState() = runTest { assertFalse(ch.isClosedForWrite) @@ -268,7 +254,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { assertTrue(ch.isClosedForRead) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadRemaining() = runTest { expect(1) @@ -289,7 +274,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(6) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadInProgress() = runTest { expect(1) @@ -311,7 +295,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 +321,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadFullyEof() = runTest { expect(1) @@ -358,7 +340,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(5) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testResumeReadFromFailedChannel() = runTest { expect(1) @@ -377,7 +358,6 @@ class SdkByteChannelSuspendTest : ManualDispatchTestBase() { finish(4) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testResumeReadFromClosedChannelNoContent() = runTest { expect(1) @@ -394,7 +374,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 +388,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 +398,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..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,21 +5,18 @@ 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 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 +41,6 @@ class SdkByteChannelTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testClose() = runTest { val chan = SdkByteChannel(false) @@ -89,7 +85,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 +98,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 +110,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 +132,6 @@ class SdkByteChannelTest { job.join() } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testCloseableUse() = runTest { val chan = SdkByteChannel(true) @@ -161,7 +153,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 +165,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 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/ExceptionsJVM.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/ExceptionsJVM.kt index 82d28aaac0..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 @@ -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/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt b/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/JavaIO.kt index e7578bfea4..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 @@ -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() 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/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/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt new file mode 100644 index 0000000000..7205c8d6a1 --- /dev/null +++ b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterJvmAndNative.kt @@ -0,0 +1,12 @@ +/* + * 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 + +@InternalApi +internal actual class BufferedSinkAdapter actual constructor(sink: okio.BufferedSink) : + AbstractBufferedSinkAdapter(sink), + SdkBufferedSink diff --git a/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt new file mode 100644 index 0000000000..437b018606 --- /dev/null +++ b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterJvmAndNative.kt @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.io + +internal actual class BufferedSourceAdapter actual constructor(source: okio.BufferedSource) : + AbstractBufferedSourceAdapter(source), + SdkBufferedSource diff --git a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt similarity index 81% rename from runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt rename to runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt index 3fc01858e4..c0472cd857 100644 --- a/runtime/runtime-core/jvm/src/aws/smithy/kotlin/runtime/io/SdkBufferJVM.kt +++ b/runtime/runtime-core/jvmAndNative/src/aws/smithy/kotlin/runtime/io/SdkBufferJvmAndNative.kt @@ -2,13 +2,9 @@ * 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, @@ -37,6 +33,36 @@ public actual class SdkBuffer : return inner == other.inner } + actual override fun write(source: SdkBuffer, byteCount: Long): Unit = commonWrite(source, 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 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 skip(byteCount: Long): Unit = commonSkip(byteCount) actual override fun readByte(): Byte = commonReadByte() @@ -55,13 +81,7 @@ public actual class SdkBuffer : 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 = inner.read(dst) + actual override fun read(sink: ByteArray, offset: Int, limit: Int): Int = commonRead(sink, offset, limit) actual override fun readByteArray(): ByteArray = commonReadByteArray() @@ -74,48 +94,12 @@ public actual class SdkBuffer : 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 = 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 read(sink: SdkBuffer, limit: Long): Long = commonRead(sink, limit) - 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() { - 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/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 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 deleted file mode 100644 index 48f9badc3a..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSinkAdapterNative.kt +++ /dev/null @@ -1,70 +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 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") - } -} 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 deleted file mode 100644 index cfa9d4c76f..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/BufferedSourceAdapterNative.kt +++ /dev/null @@ -1,90 +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 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") - } -} 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..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,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, 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/SdkBufferNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt deleted file mode 100644 index e8bee2b911..0000000000 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/io/SdkBufferNative.kt +++ /dev/null @@ -1,160 +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 okio.Buffer - -public actual class SdkBuffer : - SdkBufferedSource, - SdkBufferedSink { - public actual val size: Long - get() = TODO("Not yet implemented") - - public actual constructor() - - internal actual val inner: okio.Buffer - get() = TODO("Not yet implemented") - - internal actual constructor(buffer: okio.Buffer) - - 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 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 write(source: SdkBuffer, 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") - } -} 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") -} 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 index e5b1309c5a..de34d71300 100644 --- 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 @@ -6,6 +6,8 @@ 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 { @@ -13,5 +15,5 @@ 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") + get() = Dispatchers.IO }