Hi, I'm dipping my toes in the K/N pond and I'd li...
# kotlin-native
o
Hi, I'm dipping my toes in the K/N pond and I'd like to have any basic mistakes be pointed out early. Would you please look at the following piece of code and tell me if there's anything fundamentally wrong with my mental model? `iosMain`:
Copy code
internal actual fun encode(text: String, charset: Charset): ByteArray {
  var cfCharsetName: CPointer<__CFString>? = null
  try {
    // (1) Cast a NSString as CFStringRef for the CF lookup function.
    //     The BridgingRetain function will transfer the ownership to us,
    //     making us responsible for freeing the memory.
    cfCharsetName = CFBridgingRetain(charset.ianaName as NSString) as CFStringRef?

    // (2) Using the prepared CFStringRef, find the CFStringEncoding.
    val cfEncoding = CFStringConvertIANACharSetNameToEncoding(cfCharsetName)
    if (cfEncoding == kCFStringEncodingInvalidId) {
      throw RuntimeException("invalid encoding: ${charset.ianaName}")
    }

    // (3) Using the CF encoding, find the corresponding NSStringEncoding
    val nsEncoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding)

    // (4) Encode the Kotlin String using the NS Encoding. The resulting NSData
    //     lives in the ARC-enabled iOS runtime and since it does not escape the current
    //     scope, will be collected when scope ends.
    val encodedData: NSData =
        (text as NSString).dataUsingEncoding(nsEncoding, allowLossyConversion = true)
            ?: throw RuntimeException("encoder failed")
    val encodedBytes = encodedData.bytes ?: throw RuntimeException("encoder failed")

    // (5) Create a Kotlin-land ByteArray and copy over the encoded bytes
    // from the ObjC-land NSData.
    //
    // <https://github.com/JetBrains/kotlin-native/issues/3172>
    return ByteArray(encodedData.length.toInt()).apply {
      usePinned { pinnedByteArray ->
        memcpy(pinnedByteArray.addressOf(0), encodedBytes, encodedData.length)
      }
    }
  } finally {
    // Don't forget to free the unmanaged CF pointer! 
    CFRelease(cfCharsetName)
  }
}