RawSink 
    Receives a stream of bytes. RawSink is a base interface for kotlinx-io data receivers.
This interface should be implemented to write data wherever it's needed: to the network, storage, or a buffer in memory. Sinks may be layered to transform received data, such as to compress, encrypt, throttle, or add protocol framing.
Most application code shouldn't operate on a raw sink directly, but rather on a buffered Sink which is both more efficient and more convenient. Use buffered to wrap any raw sink with a buffer.
Implementors should abstain from throwing exceptions other than those that are documented for RawSink methods.
Thread-safety guarantees
RawSink implementations are not required to be thread safe. However, if an implementation provides some thread safety guarantees, it is recommended to explicitly document them.
Samples
import kotlinx.io.*
import kotlin.test.*
fun main() { 
   //sampleStart 
   /**
 * Sink calculating CRC-32 code for all the data written to it and sending this data to the upstream afterward.
 * The CRC-32 value could be obtained using [crc32] method.
 *
 * See https://en.wikipedia.org/wiki/Cyclic_redundancy_check for more information about CRC-32.
 */
class CRC32Sink(private val upstream: RawSink): RawSink {
    private val tempBuffer = Buffer()
    private val crc32Table = generateCrc32Table()
    private var crc32: UInt = 0xffffffffU
    private fun update(value: Byte) {
        val index = value.toUInt().xor(crc32).toUByte()
        crc32 = crc32Table[index.toInt()].xor(crc32.shr(8))
    }
    fun crc32(): UInt = crc32.xor(0xffffffffU)
    override fun write(source: Buffer, byteCount: Long) {
        source.copyTo(tempBuffer, 0, byteCount)
        while (!tempBuffer.exhausted()) {
            update(tempBuffer.readByte())
        }
        upstream.write(source, byteCount)
    }
    override fun flush() = upstream.flush()
    override fun close() = upstream.close()
    private fun generateCrc32Table(): UIntArray {
        val table = UIntArray(256)
        for (idx in table.indices) {
            table[idx] = idx.toUInt()
            for (bit in 8 downTo 1) {
                table[idx] = if (table[idx] % 2U == 0U) {
                    table[idx].shr(1)
                } else {
                    table[idx].shr(1).xor(0xEDB88320U)
                }
            }
        }
        return table
    }
}
val crc32Sink = CRC32Sink(discardingSink())
crc32Sink.buffered().use {
    it.writeString("hello crc32")
}
assertEquals(0x9896d398U, crc32Sink.crc32()) 
   //sampleEnd
}