Skip to content

Commit 1bd0900

Browse files
committed
Change CommonCodePoints.toChars() to match the Java stdlib behavior
1 parent ec6c9a1 commit 1bd0900

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

src/commonImplementation/kotlin/CommonCodePoints.kt

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,24 @@ object CommonCodePoints {
5454
}
5555

5656
fun toChars(codePoint: Int, destination: CharArray, offset: Int): Int {
57-
val size = destination.size
58-
if (offset >= 0) {
59-
if (isBmpCodePoint(codePoint)) {
60-
if (offset < size) {
61-
destination[offset] = codePoint.toChar()
62-
return 1
63-
}
64-
} else if (offset < size - 1) {
65-
destination[offset] = highSurrogate(codePoint)
66-
destination[offset + 1] = lowSurrogate(codePoint)
67-
return 2
68-
}
57+
if (isBmpCodePoint(codePoint)) {
58+
destination.setSafe(offset, codePoint.toChar())
59+
return 1
60+
} else {
61+
// When writing the low surrogate succeeds but writing the high surrogate fails (offset = -1), the
62+
// destination will be modified even though the method throws. This feels wrong, but matches the behavior
63+
// of the Java stdlib implementation.
64+
destination.setSafe(offset + 1, lowSurrogate(codePoint))
65+
destination.setSafe(offset, highSurrogate(codePoint))
66+
return 2
6967
}
70-
throw IndexOutOfBoundsException("Size: $size, offset: $offset")
68+
}
69+
70+
private fun CharArray.setSafe(index: Int, value: Char) {
71+
if (index !in this.indices) {
72+
throw IndexOutOfBoundsException("Size: $size, offset: $index")
73+
}
74+
75+
this[index] = value
7176
}
7277
}

src/commonTest/kotlin/CodePointsTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ class CodePointsTest {
140140
assertFailsWith<IndexOutOfBoundsException> {
141141
CodePoints.toChars("\uD83E\uDD95".codePointAt(0), chars, -1)
142142
}
143-
assertContentEquals(charArrayOf('z', 'z'), chars)
143+
// We're bug-compatible with the Java stdlib implementation
144+
assertContentEquals(charArrayOf('\uDD95', 'z'), chars)
144145
}
145146

146147
@Test

0 commit comments

Comments
 (0)