2

I'm looking into the source code for Okio in order to understand efficient byte transferring better, and as a toy example made a little ForwardingSource which inverts individual bytes as they come along. For example, it transforms (unsigned) 0b1011 to (unsigned) 0b0100.

class ByteInvertingSource(source: Source) : ForwardingSource(source) {

  // temporarily stores incoming bytes
  private val sourceBuffer: Buffer = Buffer()

  override fun read(sink: Buffer, byteCount: Long): Long {
    // read incoming bytes
    val count = delegate.read(sourceBuffer, byteCount)

    // write inverted bytes to sink
    sink.write(
      sourceBuffer.readByteArray().apply {
        println("Converting: ${joinToString(",") { it.toString(2) }}")
        forEachIndexed { index, byte -> this[index] = byte.inv() }
        println("Converted : ${joinToString(",") { it.toString(2) }}")
      }
    )
    return count
  }
}

Is this optimal code?

Specifically:

  • Do I really need the sourceBuffer field, or could I use another trick to transform the bytes directly?
  • Is it more efficient to read the individual bytes from sourceBuffer and write the individual bytes into sink? (I can't find a write(Byte) method, so maybe that is a clue that it's not.)
Maarten
  • 6,894
  • 7
  • 55
  • 90

1 Answers1

2

It looks pretty close the this testing sample from OkHttp.

https://github.com/square/okhttp/blob/f8fd4d08decf697013008b05ad7d2be10a648358/okhttp-testing-support/src/main/kotlin/okhttp3/UppercaseResponseInterceptor.kt

      override fun read(
        sink: Buffer,
        byteCount: Long
      ): Long {
        val buffer = Buffer()
        val read = delegate.read(buffer, byteCount)
        if (read != -1L) {
          sink.write(buffer.readByteString().toAsciiUppercase())
        }
        return read
      }

It is definitely not more efficient to read individual bytes. I don't think you can improve your invert loop, as it's an operation on a single byte. But generally you don't want to be doing loops in your code, so definitely do the bulk reads.

Yuri Schimke
  • 12,435
  • 3
  • 35
  • 69