Skip to content

Commit f34175e

Browse files
author
Sergey Mashkov
committed
IO: add byte packet readBytes and readText utility functions + tests
1 parent 5feaf69 commit f34175e

File tree

6 files changed

+97
-8
lines changed

6 files changed

+97
-8
lines changed

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/packet/ByteReadPacket.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ interface ByteReadPacket {
3838

3939
fun inputStream(): InputStream
4040
fun readerUTF8(): Reader
41+
42+
fun readText(): CharSequence
4143
}

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/packet/ByteReadPacketEmpty.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ object ByteReadPacketEmpty : ByteReadPacket {
5353
override fun inputStream(): InputStream = EmptyInputStream
5454
override fun readerUTF8(): Reader = EmptyReader
5555

56+
override fun readText() = ""
57+
5658
private object EmptyInputStream : InputStream() {
5759
override fun available() = 0
5860

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/packet/ByteReadPacketImpl.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
package kotlinx.coroutines.experimental.io.packet
44

5-
import kotlinx.coroutines.experimental.io.internal.ObjectPool
6-
import kotlinx.coroutines.experimental.io.internal.decodeUTF8
5+
import kotlinx.coroutines.experimental.io.internal.*
76
import java.io.*
8-
import java.nio.BufferOverflowException
9-
import java.nio.ByteBuffer
7+
import java.nio.*
108
import java.nio.charset.*
119
import java.util.*
1210

@@ -145,6 +143,25 @@ internal class ByteReadPacketImpl(private val packets: ArrayDeque<ByteBuffer>, i
145143
return rc
146144
}
147145

146+
override fun readText(): CharSequence {
147+
val sb = StringBuilder(remaining)
148+
149+
var size = 0
150+
151+
reading(1) { bb ->
152+
size = bb.decodeUTF8 { ch ->
153+
sb.append(ch)
154+
true
155+
}
156+
157+
size == 0
158+
}
159+
160+
if (size > 0) throw CharacterCodingException()
161+
162+
return sb
163+
}
164+
148165
override fun skip(n: Int): Int {
149166
var skipped = 0
150167

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/packet/ByteReadPacketSingle.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import kotlinx.coroutines.experimental.io.internal.decodeUTF8
55
import java.io.*
66
import java.nio.BufferOverflowException
77
import java.nio.ByteBuffer
8-
import java.nio.charset.MalformedInputException
8+
import java.nio.charset.*
99

1010
internal class ByteReadPacketSingle(private var buffer: ByteBuffer?, internal val pool: ObjectPool<ByteBuffer>) : ByteReadPacket {
1111
override val remaining: Int
@@ -138,6 +138,25 @@ internal class ByteReadPacketSingle(private var buffer: ByteBuffer?, internal va
138138
}
139139
}
140140

141+
override fun readText(): CharSequence {
142+
val sb = StringBuilder(remaining)
143+
144+
var size = 0
145+
146+
reading { bb ->
147+
size = bb.decodeUTF8 { ch ->
148+
sb.append(ch)
149+
true
150+
}
151+
152+
size == 0
153+
}
154+
155+
if (size > 0) throw CharacterCodingException()
156+
157+
return sb
158+
}
159+
141160
override fun skip(n: Int): Int {
142161
var skipped = 0
143162

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/packet/Packets.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package kotlinx.coroutines.experimental.io.packet
22

3-
import kotlinx.coroutines.experimental.io.internal.ObjectPool
4-
import kotlinx.coroutines.experimental.io.internal.ObjectPoolImpl
5-
import kotlinx.coroutines.experimental.io.internal.getIOIntProperty
3+
import kotlinx.coroutines.experimental.io.internal.*
64
import java.nio.ByteBuffer
75

86
internal val PACKET_BUFFER_SIZE = getIOIntProperty("PacketBufferSize", 4096)
@@ -22,3 +20,5 @@ fun ByteReadPacket.readUTF8Line(estimate: Int = 16, limit: Int = Int.MAX_VALUE):
2220
val sb = StringBuilder(estimate)
2321
return if (readUTF8LineTo(sb, limit)) sb.toString() else null
2422
}
23+
24+
fun ByteReadPacket.readBytes() = inputStream().readBytes(remaining)

core/kotlinx-coroutines-io/src/test/kotlin/kotlinx/coroutines/experimental/io/BytePacketReaderWriterTest.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package kotlinx.coroutines.experimental.io
22

33
import kotlinx.coroutines.experimental.io.packet.*
44
import org.junit.*
5+
import java.util.*
56
import kotlin.test.*
67

78
class BytePacketReaderWriterTest {
@@ -225,4 +226,52 @@ class BytePacketReaderWriterTest {
225226

226227
assertNull(p.readUTF8Line())
227228
}
229+
230+
@Test
231+
fun testSingleBufferReadText() {
232+
val p = buildPacket {
233+
append("ABC")
234+
}
235+
236+
assertEquals("ABC", p.readText().toString())
237+
}
238+
239+
@Test
240+
fun testMultiBufferReadText() {
241+
val s = buildString {
242+
repeat(100000) {
243+
append("x")
244+
}
245+
}
246+
247+
val packet = buildPacket {
248+
writeFully(s.toByteArray())
249+
}
250+
251+
assertEquals(s, packet.readText().toString())
252+
}
253+
254+
@Test
255+
fun testSingleBufferReadAll() {
256+
val bb = ByteArray(100)
257+
Random().nextBytes(bb)
258+
259+
val p = buildPacket {
260+
writeFully(bb)
261+
}
262+
263+
assertTrue { bb.contentEquals(p.readBytes()) }
264+
}
265+
266+
@Test
267+
fun testMultiBufferReadAll() {
268+
val bb = ByteArray(100000)
269+
Random().nextBytes(bb)
270+
271+
val p = buildPacket {
272+
writeFully(bb)
273+
}
274+
275+
assertTrue { bb.contentEquals(p.readBytes()) }
276+
}
228277
}

0 commit comments

Comments
 (0)