Skip to content

Add NSData.toByteString() and ByteString.toNSData() for Apple targets #266

Closed
@joffrey-bion

Description

@joffrey-bion

It seems that NSData is the Foundation type to represent immutable byte arrays, which means it corresponds to ByteString in purpose. It would be great to have these conversions in the kotlinx-io-bytestring lib by default.

Example implementation:

/**
 * Creates a new [NSData] containing the data copied from this [ByteString].
 */
fun ByteString.toNSData(): NSData = getBackingArrayReference().toNSData()

/**
 * Creates a new [NSData] containing the data copied from this [ByteArray].
 */
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class, BetaInteropApi::class)
private fun ByteArray.toNSData(): NSData = memScoped {
    NSData.create(bytes = allocArrayOf(this@toNSData), length = this@toNSData.size.convert())
}

/**
 * Creates a new [ByteString] containing the data copied from this [NSData].
 */
fun NSData.toByteString(): ByteString = ByteString.wrap(toByteArray())

/**
 * Creates a new [ByteArray] containing the data copied from this [NSData].
 */
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
private fun NSData.toByteArray(): ByteArray {
    // length=0 breaks memcpy for some reason (ArrayIndexOutOfBoundsException)
    // and it doesn't hurt to skip memcpy anyway if the array is empty
    if (length.toInt() == 0) return ByteArray(0)

    val nsData = this
    return ByteArray(nsData.length.toInt()).apply {
        usePinned { pinned ->
            memcpy(pinned.addressOf(0), nsData.bytes, nsData.length)
        }
    }
}

Arguably, the ByteArray conversions could be part of the stdlib instead, and kotlinx-io-bytestring could just build on top.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DesignenhancementintegrationAn issue related to the integration with other libraries or platform-specific APIs

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions