You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/SessionUtilitiesKit/General/Collection+Utilities.swift

67 lines
2.6 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
public extension Collection where Element == String {
func withUnsafeCStrArray<R>(
_ body: (UnsafeBufferPointer<UnsafePointer<CChar>?>) throws -> R
) throws -> R {
let cCharArrays: [[CChar]] = try map { swiftStr in
guard let cChars = swiftStr.cString(using: .utf8) else {
throw LibSessionError.invalidCConversion
}
return cChars
}
func getPointers(
remainingArrays: ArraySlice<[CChar]>,
collectedPointers: [UnsafePointer<CChar>?]
) throws -> R {
guard let currentArray = remainingArrays.first else {
return try collectedPointers.withUnsafeBufferPointer { collectedPointersBuffer in
try body(collectedPointersBuffer)
}
}
return try currentArray.withUnsafeBufferPointer { currentBufferPtr in
try getPointers(
remainingArrays: remainingArrays.dropFirst(),
collectedPointers: collectedPointers + [currentBufferPtr.baseAddress]
)
}
}
return try getPointers(remainingArrays: ArraySlice(cCharArrays), collectedPointers: [])
}
}
public extension Collection where Element == [UInt8]? {
func withUnsafeUInt8CArray<R>(
_ body: (UnsafeBufferPointer<UnsafePointer<UInt8>?>) throws -> R
) throws -> R {
func processNext<I: IteratorProtocol>(
iterator: inout I,
collectedPointers: [UnsafePointer<UInt8>?]
) throws -> R where I.Element == Element {
if let optionalElement: [UInt8]? = iterator.next() {
if let array: [UInt8] = optionalElement {
return try array.withUnsafeBufferPointer { bufferPtr in
try processNext(iterator: &iterator, collectedPointers: collectedPointers + [bufferPtr.baseAddress])
}
}
// It's a nil element in the input collection, add a nil pointer and recurse
return try processNext(iterator: &iterator, collectedPointers: collectedPointers + [nil])
} else {
return try collectedPointers.withUnsafeBufferPointer { pointersBuffer in
try body(pointersBuffer)
}
}
}
var iterator = makeIterator()
return try processNext(iterator: &iterator, collectedPointers: [])
}
}