blob: 6d7e214107f3436e05ca160111028dd292237ff4 [file]
/*
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.wasm.internal
// Based on the AssemblyScript implementation [https://github.com/AssemblyScript/assemblyscript/blob/1e0466ef94fa5cacd0984e4f31a0087de51538a8/std/assembly/util/number.ts]
internal actual fun itoa32(inputValue: Int): String {
if (inputValue == 0) return "0"
val isNegative = inputValue < 0
val absValue = if (isNegative) -inputValue else inputValue
val absValueString = utoa32(absValue.toUInt())
return if (isNegative) "-$absValueString" else absValueString
}
internal actual fun utoa32(inputValue: UInt): String {
if (inputValue == 0U) return "0"
val decimals = decimalCount32(inputValue)
val buf = WasmCharArray(decimals)
utoaDecSimple(buf, inputValue, decimals)
return buf.createString()
}
private fun utoaDecSimple(buffer: WasmCharArray, numInput: UInt, offsetInput: Int) {
assert(numInput != 0U)
assert(buffer.len() > 0)
assert(offsetInput > 0 && offsetInput <= buffer.len())
var num = numInput
var offset = offsetInput
do {
val t = num / 10U
val r = num % 10U
num = t
offset--
buffer.set(offset, digitToChar(r.toInt()))
} while (num > 0U)
}
private fun utoaDecSimple64(buffer: WasmCharArray, numInput: ULong, offsetInput: Int) {
assert(numInput != 0UL)
assert(buffer.len() > 0)
assert(offsetInput > 0 && offsetInput <= buffer.len())
var num = numInput
var offset = offsetInput
do {
val t = num / 10U
val r = num % 10U
num = t
offset--
buffer.set(offset, digitToChar(r.toInt()))
} while (num > 0U)
}
internal actual fun itoa64(inputValue: Long): String {
if (inputValue in Int.MIN_VALUE..Int.MAX_VALUE)
return itoa32(inputValue.toInt())
val isNegative = inputValue < 0
val absValue = if (isNegative) -inputValue else inputValue
val absValueString = utoa64(absValue.toULong())
return if (isNegative) "-$absValueString" else absValueString
}
internal actual fun utoa64(inputValue: ULong): String {
if (inputValue <= UInt.MAX_VALUE) return utoa32(inputValue.toUInt())
val decimals = decimalCount64High(inputValue)
val buf = WasmCharArray(decimals)
utoaDecSimple64(buf, inputValue, decimals)
return buf.createString()
}
// Count number of decimals for u64 values
// In our case input value always greater than 2^32-1 so we can skip some parts
private fun decimalCount64High(value: ULong): Int {
if (value < 1000000000000000UL) {
if (value < 1000000000000UL) {
return 10 + (value >= 100000000000UL).toInt() + (value >= 10000000000UL).toInt()
} else {
return 13 + (value >= 100000000000000UL).toInt() + (value >= 10000000000000UL).toInt()
}
} else {
if (value < 100000000000000000UL) {
return 16 + (value >= 10000000000000000UL).toInt()
} else {
return 18 + (value >= 10000000000000000000UL).toInt() + (value >= 1000000000000000000UL).toInt()
}
}
}