diff options
Diffstat (limited to 'okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt')
-rw-r--r-- | okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt b/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt new file mode 100644 index 00000000..b9836202 --- /dev/null +++ b/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2019 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package okio + +interface BufferedSourceFactory { + class Pipe( + var sink: BufferedSink, + var source: BufferedSource + ) + + val isOneByteAtATime: Boolean + + fun pipe(): Pipe + + companion object { + val BUFFER: BufferedSourceFactory = object : BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = false + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + buffer, + buffer + ) + } + } + + val REAL_BUFFERED_SOURCE: BufferedSourceFactory = object : + BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = false + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + buffer, + (buffer as Source).buffer() + ) + } + } + + /** + * A factory deliberately written to create buffers whose internal segments are always 1 byte + * long. We like testing with these segments because are likely to trigger bugs! + */ + val ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE: BufferedSourceFactory = object : + BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = true + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + buffer, + object : Source by buffer { + override fun read(sink: Buffer, byteCount: Long): Long { + // Read one byte into a new buffer, then clone it so that the segment is shared. + // Shared segments cannot be compacted so we'll get a long chain of short segments. + val box = Buffer() + val result = buffer.read(box, minOf(byteCount, 1L)) + if (result > 0L) sink.write(box.copy(), result) + return result + } + }.buffer() + ) + } + } + + val ONE_BYTE_AT_A_TIME_BUFFER: BufferedSourceFactory = object : + BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = true + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + object : Sink by buffer { + override fun write(source: Buffer, byteCount: Long) { + // Write each byte into a new buffer, then clone it so that the segments are shared. + // Shared segments cannot be compacted so we'll get a long chain of short segments. + for (i in 0 until byteCount) { + val box = Buffer() + box.write(source, 1) + buffer.write(box.copy(), 1) + } + } + }.buffer(), + buffer + ) + } + } + + val PEEK_BUFFER: BufferedSourceFactory = object : BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = false + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + buffer, + buffer.peek() + ) + } + } + + val PEEK_BUFFERED_SOURCE: BufferedSourceFactory = object : + BufferedSourceFactory { + + override val isOneByteAtATime: Boolean + get() = false + + override fun pipe(): Pipe { + val buffer = Buffer() + return Pipe( + buffer, + (buffer as Source).buffer().peek() + ) + } + } + + val PARAMETERIZED_TEST_VALUES = mutableListOf<Array<Any>>( + arrayOf(BUFFER), + arrayOf(REAL_BUFFERED_SOURCE), + arrayOf(ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE), + arrayOf(ONE_BYTE_AT_A_TIME_BUFFER), + arrayOf(PEEK_BUFFER), + arrayOf(PEEK_BUFFERED_SOURCE) + ) + } +} |