Before I start I would like to apologise if I say something crazy.
I am working on an app that implements a c library. Among others, It shares idArrays.
I have the part decodes an idArray and it was given to me:
func decodeArrayID(aArray:UnsafeMutablePointer<CChar>, aTokenLen:UInt32)->([UInt32], String){
let arrayCount = Int(aTokenLen / 4)
var idArrayTemp = [UInt32]()
var idArrayStringTemp = ""
for i in 0..<arrayCount{
let idValue = decodeArrayIDItem(index: i, array: aArray)
idArrayTemp.append(idValue)
idArrayStringTemp += "\(idValue) "
}
return (idArrayTemp, idArrayStringTemp)
}
func decodeArrayIDItem(index:Int, array:UnsafeMutablePointer<CChar>) -> UInt32{
var value:UInt32 = UInt32(array[index * 4]) & 0xFF
value <<= 8
value |= UInt32(array [index * 4 + 1]) & 0xFF
value <<= 8
value |= UInt32(array [index * 4 + 2]) & 0xFF
value <<= 8
value |= UInt32(array [index * 4 + 3]) & 0xFF
return value
}
As we can see the idArray is send through UnsafeMutablePointer AKA UnsafeMutablePointer.
Now I am working with the encoding part. The function will take an array of UInt32 values and will try to convert it into byte array and will convert into a sting for sending it through the library.
So far I have the following code but it doesn't work:
func encodeIDArray(idArray:[UInt32])->String{
var aIDArray8:[UInt8] = [UInt8]()
for var value in idArray{
let count = MemoryLayout<UInt32>.size
let bytePtr = withUnsafePointer(to: &value) {
$0.withMemoryRebound(to: UInt8.self, capacity: count) {
UnsafeBufferPointer(start: $0, count: count)
}
}
aIDArray8 += Array(bytePtr)
}
let stringTest = String(data: Data(aIDArray8), encoding: .utf8)
return stringTest!
}
A test result for the input [1,2] returns "\u{01}\0\0\0\u{02}\0\0\0" and something tells is not quite right...
Thank you
Edited The c functions are
DllExport void STDCALL DvProviderAvOpenhomeOrgPlaylist1EnableActionIdArray(THandle aProvider, CallbackPlaylist1IdArray aCallback, void* aPtr);
where CallbackPlaylist1IdArray is
typedef int32_t (STDCALL *CallbackPlaylist1IdArray)(void* aPtr, IDvInvocationC* aInvocation, void* aInvocationPtr, uint32_t* aToken, char** aArray, uint32_t* aArrayLen);
and the value to aArray is the value that get the Byte array
Data(aIDArray8)contains the correct bytes (01 00 00 00 02 00 00 00), but converting that to a string makes no sense (and can easily fail for arbitrary data).