Skip to content

Commit

Permalink
Add a multiplatform okio.Closeable interface
Browse files Browse the repository at this point in the history
Not having it made interacting with Okio particularly annoying
on non-JVM platforms.

Note that we use our own use {} function on all platforms and do
not delegate to Kotlin's use {} function on the JVM. I couldn't
find a way to call Kotlin's use function from our own use function
since they both extend Closeable.
  • Loading branch information
squarejesse committed Jan 5, 2021
1 parent adf7a85 commit cc815b8
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 101 deletions.
9 changes: 9 additions & 0 deletions okio/src/commonMain/kotlin/okio/-Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ expect open class IOException(message: String?, cause: Throwable?) : Exception {
expect open class EOFException(message: String? = null) : IOException

expect class FileNotFoundException(message: String? = null) : IOException

expect interface Closeable {
/**
* Closes this object and releases the resources it holds. It is an error to use an object after
* it has been closed. It is safe to close an object more than once.
*/
@Throws(IOException::class)
fun close()
}
42 changes: 0 additions & 42 deletions okio/src/commonMain/kotlin/okio/-Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -161,45 +161,3 @@ internal fun Long.toHexString(): String {

return String(result, i, result.size - i)
}

internal inline fun <S : Source, T> S.use(block: (S) -> T): T {
var result: T? = null
var thrown: Throwable? = null

try {
result = block(this)
} catch (t: Throwable) {
thrown = t
}

try {
close()
} catch (t: Throwable) {
if (thrown == null) thrown = t
else thrown.addSuppressed(t)
}

if (thrown != null) throw thrown
return result!!
}

internal inline fun <S : Sink, T> S.use(block: (S) -> T): T {
var result: T? = null
var thrown: Throwable? = null

try {
result = block(this)
} catch (t: Throwable) {
thrown = t
}

try {
close()
} catch (t: Throwable) {
if (thrown == null) thrown = t
else thrown.addSuppressed(t)
}

if (thrown != null) throw thrown
return result!!
}
22 changes: 22 additions & 0 deletions okio/src/commonMain/kotlin/okio/Okio.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,25 @@ private class BlackholeSink : Sink {
override fun timeout() = Timeout.NONE
override fun close() {}
}

/** Execute [block] then close this. This will be closed even if [block] throws. */
inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var result: R? = null
var thrown: Throwable? = null

try {
result = block(this)
} catch (t: Throwable) {
thrown = t
}

try {
this?.close()
} catch (t: Throwable) {
if (thrown == null) thrown = t
else thrown.addSuppressed(t)
}

if (thrown != null) throw thrown
return result!!
}
7 changes: 5 additions & 2 deletions okio/src/commonMain/kotlin/okio/Sink.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ package okio
* Use [sink] to adapt an `OutputStream` to a sink. Use [outputStream()][BufferedSink.outputStream]
* to adapt a sink to an `OutputStream`.
*/
expect interface Sink {
expect interface Sink : Closeable {
/** Removes `byteCount` bytes from `source` and appends them to this. */
@Throws(IOException::class)
fun write(source: Buffer, byteCount: Long)

/** Pushes all buffered bytes to their final destination. */
@Throws(IOException::class)
fun flush()

/** Returns the timeout for this sink. */
Expand All @@ -56,5 +58,6 @@ expect interface Sink {
* Pushes all buffered bytes to their final destination and releases the resources held by this
* sink. It is an error to write a closed sink. It is safe to close a sink more than once.
*/
fun close()
@Throws(IOException::class)
override fun close()
}
6 changes: 4 additions & 2 deletions okio/src/commonMain/kotlin/okio/Source.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ package okio
* Use [source] to adapt an `InputStream` to a source. Use [BufferedSource.inputStream] to adapt a
* source to an `InputStream`.
*/
expect interface Source {
interface Source : Closeable {
/**
* Removes at least 1, and up to `byteCount` bytes from this and appends them to `sink`. Returns
* the number of bytes read, or -1 if this source is exhausted.
*/
@Throws(IOException::class)
fun read(sink: Buffer, byteCount: Long): Long

/** Returns the timeout for this source. */
Expand All @@ -64,5 +65,6 @@ expect interface Source {
* Closes this source and releases the resources held by this source. It is an error to read a
* closed source. It is safe to close a source more than once.
*/
fun close()
@Throws(IOException::class)
override fun close()
}
2 changes: 2 additions & 0 deletions okio/src/jvmMain/kotlin/okio/-Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ actual typealias IOException = java.io.IOException
actual typealias EOFException = java.io.EOFException

actual typealias FileNotFoundException = java.io.FileNotFoundException

actual typealias Closeable = java.io.Closeable
29 changes: 0 additions & 29 deletions okio/src/jvmMain/kotlin/okio/Source.kt

This file was deleted.

5 changes: 5 additions & 0 deletions okio/src/nonJvmMain/kotlin/okio/-Platform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ actual open class IOException actual constructor(
actual open class EOFException actual constructor(message: String?) : IOException(message)

actual open class FileNotFoundException actual constructor(message: String?) : IOException(message)

actual interface Closeable {
@Throws(IOException::class)
actual fun close()
}
7 changes: 5 additions & 2 deletions okio/src/nonJvmMain/kotlin/okio/Sink.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
*/
package okio

actual interface Sink {
actual interface Sink : Closeable {
@Throws(IOException::class)
actual fun write(source: Buffer, byteCount: Long)

@Throws(IOException::class)
actual fun flush()

actual fun timeout(): Timeout

actual fun close()
@Throws(IOException::class)
actual override fun close()
}
24 changes: 0 additions & 24 deletions okio/src/nonJvmMain/kotlin/okio/Source.kt

This file was deleted.

0 comments on commit cc815b8

Please sign in to comment.