Hi how do we get <Charsets.US>_ASCII in comminMain...
# multiplatform
s
Hi how do we get Charsets.US_ASCII in comminMain?? like we used to do in android
Copy code
val deviceNameArray = deviceName.toByteArray(Charsets.US_ASCII).copyOf(20)
in common main if we try to import charsets we encounter the ktor charset which is different i guess
for now I am using
Copy code
expect fun encodeToAsciiByteArray(data: String, length: Int? = null): ByteArray
Copy code
package org.zynetic.projectble.ble.client.utils

import kotlinx.cinterop.BetaInteropApi
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
import kotlinx.cinterop.usePinned
import platform.Foundation.*
import platform.posix.memcpy

@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
actual fun encodeToAsciiByteArray(data: String, length: Int?): ByteArray {
    val nsString = NSString.create(string = data)
    val nsData = nsString.dataUsingEncoding(NSASCIIStringEncoding)

    val encoded: ByteArray = nsData?.toByteArray()
        ?: // Fallback for non-ASCII characters
        data.map { ch ->
            if (ch.code in 0..0x7F) ch.code.toByte() else '?'.code.toByte()
        }.toByteArray()

    if (length == null) return encoded

    // Pad or truncate
    val result = ByteArray(length)
    encoded.copyInto(result, endIndex = minOf(encoded.size, length))

    return result
}

@OptIn(ExperimentalForeignApi::class)
private fun NSData.toByteArray(): ByteArray {
    val size = this.length.toInt()
    val output = ByteArray(size)

    output.usePinned { pinned ->
        val src = this.bytes
        if (src != null) {
            memcpy(pinned.addressOf(0), src, size.convert())
        }
    }

    return output
}
Copy code
package org.zynetic.projectble.ble.client.utils

actual fun encodeToAsciiByteArray(data: String, length: Int?): ByteArray {
    val encoded = data.toByteArray(Charsets.US_ASCII)

    // 2. Check if padding is required
    if (length == null) {
        return encoded // Return raw byte array if no length is specified
    }

    // 3. Handle padding/truncation
    val requiredLength = length
    val result = ByteArray(requiredLength)

    // Copy the encoded data into the result array
    encoded.copyInto(
        destination = result,
        startIndex = 0,
        endIndex = minOf(encoded.size, requiredLength)
    )

    // Remaining bytes in 'result' will be 0 (padding)
    return result
}
👌 1
j
Seems like String.toByteArray is JVM only, I'm surprised you're not running into an error there first 🤔 https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/to-byte-array.html
🥹 1
There is an
encodeToByteArray()
, but you don't get to choose the charset https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/encode-to-byte-array.html
👍 1
s
@Jack Boswell In android its form this file the Charsets.kt file containing
Copy code
@file:JvmName("CharsetsKt")
package kotlin.text

import java.nio.charset.*
so its working fine for android 😁 so i was looking for such functions also toByteArray() which is stringJVM.kt its works!!👌 so for my use case I needed US_ASCII so i am currently using the expect/Actual way!!
j
Well yeah,
toByteArray
and
Charset
are both JVM concepts. They should both be accessible from either JVM or Android targets. If you only target JVM and/or Android then they should be available in
commonMain
. If you target anything else, it'll be an error