Repository: JetBrains/compose-multiplatform
File: examples/codeviewer/common/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt (Kotlin)

Code before:
        // Find indexes where lines starts in background
        scope.launch(Dispatchers.IO) {
            readLinePositions(lineStartPositions)
            refreshJob.cancel()
            size = lineStartPositions.size
        }

        return object : TextLines {
            override val size get() = size

            override fun get(index: Int): String {
                val position = lineRange(index)
                val slice = byteBuffer.slice(position.first, position.last - position.first)
                return StandardCharsets.UTF_8.decode(slice).toString()
            }

            private fun lineRange(index: Int): IntRange {
                val startPosition = lineStartPositions[index]
                val nextLineIndex = index + 1
                var endPosition = if (nextLineIndex < size) {
                    // Remove \n itself from the range
                    lineStartPositions[nextLineIndex] - 1
                } else byteBufferSize

                // Clip windows style line ending from the range too
                if (byteBuffer[endPosition - 1].isChar('\r')) {
                    endPosition--
                }
                return startPosition..endPosition
            }
        }
    }
}

// Backport slice from JDK 13
private fun ByteBuffer.slice(index: Int, length: Int): ByteBuffer {
    position(index)
    return slice().limit(length)
}

private fun java.io.File.readLinePositions(starts: IntList) {
    require(length() <= Int.MAX_VALUE) {
        "Files with size over ${Int.MAX_VALUE} aren't supported"
    }

    val averageLineLength = 200
    starts.clear(length().toInt() / averageLineLength)

    try {
        for (i in readLinePositions()) {
            starts.add(i)

Review comment (suggestion):
```suggestion
                if (endPosition > 0 && byteBuffer[endPosition - 1].isChar('\r')) {
```

endPosition can be zero after the previous substraction (for a file with unix-like line endings)

Code after:
        // Find indexes where lines starts in background
        scope.launch(Dispatchers.IO) {
            readLinePositions(lineStartPositions)
            refreshJob.cancel()
            size = lineStartPositions.size
        }

        return object : TextLines {
            override val size get() = size

            override fun get(index: Int): String {
                val position = lineRange(index)
                val slice = byteBuffer.slice(position.first, position.last - position.first)
                return StandardCharsets.UTF_8.decode(slice).toString()
            }

            private fun lineRange(index: Int): IntRange {
                val startPosition = lineStartPositions[index]
                val nextLineIndex = index + 1
                var endPosition = if (nextLineIndex < size) lineStartPositions[nextLineIndex] else byteBufferSize

                // Remove line endings from the range
                while (endPosition > startPosition) {
                    val lastSymbol = byteBuffer[endPosition - 1]
                    when (lastSymbol.toInt().toChar()) {
                        '\n', '\r' -> endPosition--
                        else -> break
                    }
                }
                return startPosition..endPosition
            }
        }
    }
}

// Backport slice from JDK 13
private fun ByteBuffer.slice(index: Int, length: Int): ByteBuffer {
    position(index)
    return slice().limit(length)
}

private fun java.io.File.readLinePositions(starts: IntList) {
    require(length() <= Int.MAX_VALUE) {
        "Files with size over ${Int.MAX_VALUE} aren't supported"
    }

    val averageLineLength = 200
    starts.clear(length().toInt() / averageLineLength)

    try {
        for (i in readLinePositions()) {