IO: eliminate byte-by-byte ByteBuffer copying
diff --git a/core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/ByteBufferChannel.kt b/core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/ByteBufferChannel.kt
index ab9ea23..202504e 100644
--- a/core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/ByteBufferChannel.kt
+++ b/core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/ByteBufferChannel.kt
@@ -248,17 +248,15 @@
var consumed = 0
val rc = reading {
- val part = it.tryReadAtMost(minOf(remaining(), dst.remaining()))
+ val position = position()
+ val remaining = limit() - position
+
+ val part = it.tryReadAtMost(minOf(remaining, dst.remaining()))
if (part > 0) {
consumed += part
- if (dst.remaining() >= remaining()) {
- dst.put(this)
- } else {
- repeat(part) {
- dst.put(get())
- }
- }
+ limit(position + part)
+ dst.put(this)
bytesRead(it, part)
true
@@ -861,25 +859,25 @@
private fun writeAsMuchAsPossible(src: ByteBuffer): Int {
writing {
var written = 0
+ val srcLimit = src.limit()
do {
- val possibleSize = it.tryWriteAtMost(minOf(src.remaining(), remaining()))
+ val srcRemaining = srcLimit - src.position()
+ if (srcRemaining == 0) break
+ val possibleSize = it.tryWriteAtMost(minOf(srcRemaining, remaining()))
if (possibleSize == 0) break
require(possibleSize > 0)
- if (remaining() >= src.remaining()) {
- put(src)
- } else {
- repeat(possibleSize) {
- put(src.get())
- }
- }
+ src.limit(src.position() + possibleSize)
+ put(src)
written += possibleSize
prepareBuffer(writeByteOrder, carryIndex(writePosition + written), it.availableForWrite)
} while (true)
+ src.limit(srcLimit)
+
bytesWritten(it, written)
return written