How to add offset for array for memcpy(...) invocation?
I have array of String
:
var source = ["a","b","c","d"]
var dest = [String](count:n, repeatedValue: "")
memcpy(&dest, source, UInt(2 * sizeof(String))
This copy ["a","b"] to dest. I'ts obvious. How can i copy ["b", "c"] ?
Do not use memcpy or other low-level "C" operators on objects. That will not work for many reasons.
Use the slice operator:
var source = ["a","b","c","d"]
var dest = Array(source[1...2])
println("dest: \(dest)")
output:
dest: [b, c]
Unicode is handled correctly:
var source = ["🇪🇸", "😂", "a","b","c","d"]
var dest = Array(source[1...2])
println("dest: \(dest)")
output:
dest: [😂, a]
I'm still new to Swift, and use of methods with "Unsafe" in the name still worries me, but I'm fairly sure this is a usable technique for calling memcpy() and specifying an offset for the destination and/or source address. But this only works for byte arrays, i.e., [UInt8]. Definitely not for strings, as explained by @zaph.
public class SystemMisc {
/// Wrapper for the memcpy() method that allows specification of an offset for the destination
/// and/or the source addresses.
///
/// This version for when destination is a normal Swift byte array.
///
/// - Parameters:
/// - destPointer: Address for destination byte array, typically Swift [UInt8].
/// - destOffset: Offset to be added to the destination address, may be zero.
/// - sourcePointer: Address for source byte array, typically Swift [UInt8].
/// - sourceOffset: Offset to be added to the source address, may be zero.
/// - byteLength: Number of bytes to be copied.
public static func memoryCopy(_ destPointer : UnsafeRawPointer, _ destOffset : Int,
_ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int,
_ byteLength : Int) {
memoryCopy(UnsafeMutableRawPointer(mutating: destPointer), destOffset,
sourcePointer, sourceOffset, byteLength)
}
/// Wrapper for the memcpy() method that allows specification of an offset for the destination
/// and/or the source addresses.
///
/// This version for when destination address is already available as an UnsafeMutableRawPointer,
/// for example if caller has used UnsafeMutableRawPointer() to create it or is working with
/// unmanaged memory. The destPointer argument may also be a converted pointer, as done by the
/// above wrapper method.
///
/// - Parameters:
/// - destPointer: Address for destination byte array, see above notes.
/// - destOffset: Offset to be added to the destination address, may be zero.
/// - sourcePointer: Address for source byte array, typically Swift [UInt8].
/// - sourceOffset: Offset to be added to the source address, may be zero.
/// - byteLength: Number of bytes to be copied.
public static func memoryCopy(_ destPointer : UnsafeMutableRawPointer, _ destOffset : Int,
_ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int,
_ byteLength : Int) {
memcpy(destPointer.advanced(by: destOffset),
sourcePointer.advanced(by: sourceOffset),
byteLength)
}
}
And here's some test code:
// Test the memoryCopy() method, using extra UnsafeMutableRawPointer conversion
let destArray1 : [UInt8] = [ 0, 1, 2, 3 ] // Note - doesn't need to be var
let sourceArray1 : [UInt8] = [ 42, 43, 44, 45 ]
SystemMisc.memoryCopy(destArray1, 1, sourceArray1, 1, 2)
assert(destArray1[0] == 0 && destArray1[1] == 43 && destArray1[2] == 44 && destArray1[3] == 3)
// Test the memoryCopy() method, providing UnsafeMutableRawPointer for destination
var destArray2 : [UInt8] = [ 0, 1, 2, 3 ]
let sourceArray2 : [UInt8] = [ 42, 43, 44, 45 ]
let destArray2Pointer = UnsafeMutableRawPointer(&destArray2)
SystemMisc.memoryCopy(destArray2Pointer, 1, sourceArray2, 1, 2)
assert(destArray2[0] == 0 && destArray2[1] == 43 && destArray2[2] == 44 && destArray2[3] == 3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With