Roman Elizarov | 1f74a2d | 2018-06-29 19:19:45 +0300 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. |
| 3 | */ |
| 4 | |
Sergey Mashkov | e86eb08 | 2017-12-04 18:45:05 +0300 | [diff] [blame] | 5 | package kotlinx.coroutines.experimental.io.jvm.javaio |
| 6 | |
| 7 | import kotlinx.coroutines.experimental.io.* |
| 8 | import java.io.* |
| 9 | |
| 10 | /** |
| 11 | * Copies up to [limit] bytes from [this] byte channel to [out] stream suspending on read channel |
| 12 | * and blocking on output |
| 13 | * |
| 14 | * @return number of bytes copied |
| 15 | */ |
| 16 | suspend fun ByteReadChannel.copyTo(out: OutputStream, limit: Long = Long.MAX_VALUE): Long { |
| 17 | require(limit >= 0) { "Limit shouldn't be negative: $limit" } |
| 18 | |
| 19 | val buffer = ByteArrayPool.borrow() |
| 20 | try { |
| 21 | var copied = 0L |
| 22 | val bufferSize = buffer.size.toLong() |
| 23 | |
| 24 | while (copied < limit) { |
| 25 | val rc = readAvailable(buffer, 0, minOf(limit - copied, bufferSize).toInt()) |
| 26 | if (rc == -1) break |
| 27 | if (rc > 0) { |
| 28 | out.write(buffer, 0, rc) |
| 29 | copied += rc |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | return copied |
| 34 | } finally { |
| 35 | ByteArrayPool.recycle(buffer) |
| 36 | } |
| 37 | } |