Skip to content

Commit

Permalink
Update Buffer implementation (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
e5l authored Jul 7, 2022
1 parent 9272fcf commit 0182c3d
Show file tree
Hide file tree
Showing 27 changed files with 1,180 additions and 636 deletions.
441 changes: 411 additions & 30 deletions src/commonMain/kotlin/io/ktor/io/Buffer.kt

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions src/commonMain/kotlin/io/ktor/io/BufferOperations.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.ktor.io

public val Buffer.isEmpty: Boolean get() = availableForRead == 0
public val Buffer.isNotEmpty: Boolean get() = !isEmpty

public val Buffer.isFull: Boolean get() = availableForWrite == 0
public val Buffer.isNotFull: Boolean get() = !isFull

public val Buffer.availableForRead: Int get() = writeIndex - readIndex
public val Buffer.availableForWrite: Int get() = capacity - writeIndex

internal fun Buffer.reset() {
readIndex = 0
writeIndex = 0
}

public operator fun Buffer.get(index: Int): Byte = getByteAt(index)

public operator fun Buffer.set(index: Int, value: Byte) {
setByteAt(index, value)
}

/**
* Check if the Buffer has [count] bytes to read.
*
* @throws IndexOutOfBoundsException if the [count] is greater [availableForRead].
*/
public fun Buffer.ensureCanRead(count: Int) {
if (availableForRead < count) {
throw IndexOutOfBoundsException("Can't read $count bytes. Available: $availableForRead.")
}
}

internal fun Buffer.ensureCanRead(index: Int, count: Int) {
if (index + count > capacity) {
throw IndexOutOfBoundsException("Can't read $count bytes at index $index. Capacity: $capacity.")
}
}


/**
* Check if the Buffer has space to write [count] bytes.
*
* @throws IndexOutOfBoundsException if the [count] is greater [availableForWrite].
*/
public fun Buffer.ensureCanWrite(count: Int) {
if (availableForWrite < count) {
throw IndexOutOfBoundsException("Can't write $count bytes. Available space: $availableForWrite.")
}
}

internal fun Buffer.ensureCanWrite(index: Int, count: Int) {
if (index + count > capacity) {
throw IndexOutOfBoundsException("Can't write $count bytes at index $index. Capacity: $capacity.")
}
}
20 changes: 10 additions & 10 deletions src/commonMain/kotlin/io/ktor/io/BufferedBytesDestination.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ public class BufferedBytesDestination(

override fun canWrite(): Boolean = delegate.canWrite()

override fun write(buffer: Buffer) {
override fun write(buffer: Buffer): Int {
closedCause?.let { throw it }

this.buffer.write(buffer)
return this.buffer.copyFromBuffer(buffer)
}

override suspend fun flush() {
closedCause?.let { throw it }

while (buffer.canRead()) {
while (buffer.isNotEmpty) {
delegate.write(buffer)
delegate.awaitFreeSpace()
}
Expand All @@ -41,15 +41,15 @@ public class BufferedBytesDestination(
override suspend fun awaitFreeSpace() {
closedCause?.let { throw it }

while (!buffer.canWrite()) {
while (buffer.isFull) {
delegate.awaitFreeSpace()
delegate.write(buffer)
buffer.compact()
}
}

override fun close(cause: Throwable?) {
buffer.release()
buffer.close()
delegate.close(cause)
}

Expand All @@ -60,7 +60,7 @@ public class BufferedBytesDestination(
public suspend fun writeByte(value: Byte) {
closedCause?.let { throw it }

if (buffer.canWrite()) {
if (buffer.isNotFull) {
buffer.writeByte(value)
} else {
awaitFreeSpace()
Expand All @@ -73,7 +73,7 @@ public class BufferedBytesDestination(
public suspend fun writeShort(value: Short) {
closedCause?.let { throw it }

if (buffer.writeCapacity() >= 2) {
if (buffer.availableForWrite >= 2) {
buffer.writeShort(value)
} else {
writeByte(value.highByte)
Expand All @@ -86,7 +86,7 @@ public class BufferedBytesDestination(
public suspend fun writeInt(value: Int) {
closedCause?.let { throw it }

if (buffer.writeCapacity() >= 4) {
if (buffer.availableForWrite >= 4) {
buffer.writeInt(value)
} else {
writeShort(value.highShort)
Expand All @@ -99,7 +99,7 @@ public class BufferedBytesDestination(
public suspend fun writeLong(value: Long) {
closedCause?.let { throw it }

if (buffer.writeCapacity() >= 8) {
if (buffer.availableForWrite >= 8) {
buffer.writeLong(value)
} else {
writeInt(value.highInt)
Expand All @@ -110,7 +110,7 @@ public class BufferedBytesDestination(
}

private suspend fun flushIfFull() {
if (!buffer.canWrite()) {
if (buffer.isFull) {
flush()
}
}
Expand Down
17 changes: 8 additions & 9 deletions src/commonMain/kotlin/io/ktor/io/BufferedBytesSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,25 @@ public class BufferedBytesSource(
get() = delegate.closedCause

override fun canRead(): Boolean {
return delegate.canRead() || buffer.canRead()
return delegate.canRead() || buffer.isNotEmpty
}

override fun read(): Buffer {
closedCause?.let { throw it }

if (buffer.canRead()) {
if (buffer.isNotEmpty) {
return buffer
}

buffer.release()
buffer.close()
buffer = delegate.read()
return buffer
}

override suspend fun awaitContent() {
closedCause?.let { throw it }

if (buffer.canRead()) return

if (buffer.isNotEmpty) return
delegate.awaitContent()
}

Expand All @@ -44,7 +43,7 @@ public class BufferedBytesSource(
public suspend fun readByte(): Byte {
closedCause?.let { throw it }

while (!buffer.canRead()) {
while (buffer.isEmpty) {
awaitContent()
read()
}
Expand All @@ -54,7 +53,7 @@ public class BufferedBytesSource(
public suspend fun readShort(): Short {
closedCause?.let { throw it }

if (buffer.readCapacity() >= 2) {
if (buffer.availableForRead >= 2) {
return buffer.readShort()
}
return Short(readByte(), readByte())
Expand All @@ -63,7 +62,7 @@ public class BufferedBytesSource(
public suspend fun readInt(): Int {
closedCause?.let { throw it }

if (buffer.readCapacity() >= 4) {
if (buffer.availableForRead >= 4) {
return buffer.readInt()
}
return Int(readShort(), readShort())
Expand All @@ -72,7 +71,7 @@ public class BufferedBytesSource(
public suspend fun readLong(): Long {
closedCause?.let { throw it }

if (buffer.readCapacity() >= 8) {
if (buffer.availableForRead >= 8) {
return buffer.readLong()
}
return Long(readInt(), readInt())
Expand Down
Loading

0 comments on commit 0182c3d

Please sign in to comment.