-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Read/write ByteString from/to ByteBuffer (#387)
* Read/write ByteString from/to ByteBuffer Closes #269 --------- Co-authored-by: Jake Wharton <[email protected]>
- Loading branch information
1 parent
796a458
commit 9db9bd6
Showing
4 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file. | ||
*/ | ||
|
||
package kotlinx.io.bytestring | ||
|
||
import org.junit.jupiter.api.Test | ||
import java.nio.BufferOverflowException | ||
import java.nio.ByteBuffer | ||
import java.nio.ReadOnlyBufferException | ||
import kotlin.test.assertContentEquals | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertFailsWith | ||
import kotlin.test.assertTrue | ||
|
||
public class ByteStringByteBufferExtensionsTest { | ||
@Test | ||
fun asReadOnlyByteBuffer() { | ||
val buffer = ByteString(1, 2, 3, 4).asReadOnlyByteBuffer() | ||
|
||
assertTrue(buffer.isReadOnly) | ||
assertEquals(4, buffer.remaining()) | ||
|
||
ByteArray(4).let { | ||
buffer.get(it) | ||
assertContentEquals(byteArrayOf(1, 2, 3, 4), it) | ||
} | ||
} | ||
|
||
@Test | ||
fun getByteString() { | ||
val bb = ByteBuffer.allocate(8) | ||
bb.put(byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8)) | ||
bb.flip() | ||
|
||
assertEquals(ByteString(1, 2, 3, 4, 5, 6, 7, 8), bb.getByteString()) | ||
bb.flip() | ||
|
||
assertEquals(ByteString(1, 2, 3, 4), bb.getByteString(length = 4)) | ||
assertEquals(ByteString(), bb.getByteString(length = 0)) | ||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(length = -1) } | ||
val p = bb.position() | ||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(length = 5) } | ||
assertEquals(p, bb.position()) | ||
bb.clear() | ||
|
||
assertEquals(ByteString(1, 2, 3, 4, 5, 6, 7, 8), bb.getByteString(at = 0, length = 8)) | ||
assertEquals(0, bb.position()) | ||
|
||
assertEquals(ByteString(2, 3, 4, 5), bb.getByteString(at = 1, length = 4)) | ||
assertEquals(0, bb.position()) | ||
|
||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(at = -1, length = 8) } | ||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(at = 9, length = 1) } | ||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(at = 7, length = 2) } | ||
assertFailsWith<IndexOutOfBoundsException> { bb.getByteString(at = 0, length = -1) } | ||
} | ||
|
||
@Test | ||
fun putString() { | ||
val bb = ByteBuffer.allocate(8) | ||
val string = ByteString(1, 2, 3, 4, 5, 6, 7, 8) | ||
val shortString = ByteString(-1, -2, -3) | ||
|
||
bb.putByteString(string) | ||
assertEquals(8, bb.position()) | ||
bb.flip() | ||
ByteArray(8).let { | ||
bb.get(it) | ||
assertContentEquals(byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8), it) | ||
} | ||
|
||
bb.clear() | ||
bb.position(1) | ||
assertFailsWith<BufferOverflowException> { bb.putByteString(string) } | ||
assertEquals(1, bb.position()) | ||
|
||
bb.putByteString(at = 0, string = shortString) | ||
bb.putByteString(at = 5, string = shortString) | ||
assertEquals(1, bb.position()) | ||
bb.clear() | ||
ByteArray(8).let { | ||
bb.get(it) | ||
assertContentEquals(byteArrayOf(-1, -2, -3, 4, 5, -1, -2, -3), it) | ||
} | ||
|
||
assertFailsWith<IndexOutOfBoundsException> { bb.putByteString(at = 7, string = shortString) } | ||
assertFailsWith<IndexOutOfBoundsException> { bb.putByteString(at = -1, string = string) } | ||
assertFailsWith<IndexOutOfBoundsException> { bb.putByteString(at = 8, string = string) } | ||
assertFailsWith<ReadOnlyBufferException> { | ||
bb.asReadOnlyBuffer().putByteString(string) | ||
} | ||
assertFailsWith<ReadOnlyBufferException> { | ||
bb.asReadOnlyBuffer().putByteString(at = 0, string = string) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file. | ||
*/ | ||
|
||
package kotlinx.io.bytestring.samples | ||
|
||
import kotlinx.io.bytestring.* | ||
import java.nio.ByteBuffer | ||
import java.nio.ReadOnlyBufferException | ||
import kotlin.test.* | ||
|
||
public class ByteStringSamplesJvm { | ||
@Test | ||
fun toReadOnlyByteBuffer() { | ||
val str = "Hello World".encodeToByteString() | ||
val buffer = str.asReadOnlyByteBuffer() | ||
|
||
assertEquals(11, buffer.remaining()) | ||
assertEquals(0x48656c6c, buffer.getInt()) | ||
|
||
buffer.flip() | ||
assertFailsWith<ReadOnlyBufferException> { buffer.put(42) } | ||
} | ||
|
||
@Test | ||
fun getByteStringFromBuffer() { | ||
val buffer = ByteBuffer.wrap("Hello World".encodeToByteArray()) | ||
|
||
// Consume the whole buffer | ||
val byteString = buffer.getByteString() | ||
assertEquals(0, buffer.remaining()) | ||
assertEquals("Hello World".encodeToByteString(), byteString) | ||
|
||
// Reset the buffer | ||
buffer.flip() | ||
// Consume only first 5 bytes from the buffer | ||
assertEquals("Hello".encodeToByteString(), buffer.getByteString(length = 5)) | ||
} | ||
|
||
@Test | ||
fun getByteStringFromBufferAbsolute() { | ||
val buffer = ByteBuffer.wrap("Hello World".encodeToByteArray()) | ||
|
||
// Read 2 bytes starting from offset 6 | ||
val byteString = buffer.getByteString(at = 6, length = 2) | ||
// Buffer's position is not affected | ||
assertEquals(11, buffer.remaining()) | ||
assertEquals(byteString, "Wo".encodeToByteString()) | ||
} | ||
|
||
@Test | ||
fun putByteStringToBuffer() { | ||
val buffer = ByteBuffer.allocate(32) | ||
val byteString = ByteString(0x66, 0xdb.toByte(), 0x11, 0x50) | ||
|
||
// Putting a ByteString into a buffer will advance its position | ||
buffer.putByteString(byteString) | ||
assertEquals(4, buffer.position()) | ||
|
||
buffer.flip() | ||
assertEquals(1725632848, buffer.getInt()) | ||
} | ||
|
||
@Test | ||
fun putByteStringToBufferAbsolute() { | ||
val buffer = ByteBuffer.allocate(8) | ||
val byteString = ByteString(0x78, 0x5e) | ||
|
||
// Putting a ByteString into a buffer using an absolute offset | ||
// won't change buffer's position. | ||
buffer.putByteString(at = 3, string = byteString) | ||
assertEquals(0, buffer.position()) | ||
assertEquals(8, buffer.remaining()) | ||
|
||
assertEquals(0x000000785e000000L, buffer.getLong()) | ||
} | ||
} |