func data(for byteRange: CountableRange<Int>) -> DispatchData? { | |
// … | |
guard let byteRangePointer = malloc(byteRange.count) else { return nil } | |
for storageItem in intersectingItems { | |
let rangeToCopyInData: CountableRange<Int> = { | |
switch (byteRange.contains(storageItem.byteRange.startIndex), byteRange.contains(storageItem.byteRange.endIndex - 1)) { | |
case (true, true): | |
// Everything: |+++++++++++++| | |
return 0..<storageItem.byteRange.count | |
case (false, true): | |
// End: |---++++++++++| | |
return byteRange.startIndex - storageItem.byteRange.startIndex..<storageItem.byteRange.count | |
case (true, false): | |
// Start: |++++++++++---| | |
return 0..<byteRange.endIndex - storageItem.byteRange.startIndex | |
case (false, false): | |
// Middle: |---+++++++---| | |
return byteRange.startIndex - storageItem.byteRange.startIndex..<byteRange.endIndex - storageItem.byteRange.startIndex | |
} | |
}() | |
// Find the byte range in the allocated memory range where to copy the cached data section | |
let destinationByteIndex = storageItem.byteRange.startIndex - byteRange.startIndex + rangeToCopyInData.startIndex | |
let destinationPointer = byteRangePointer.advanced(by: destinationByteIndex) | |
let destinationBufferPointer = UnsafeMutableRawBufferPointer(start: destinationPointer, count: rangeToCopyInData.count) | |
storageItem.data.copyBytes(to: destinationBufferPointer, from: rangeToCopyInData) | |
// Ignore remaining intersections because everything is copied | |
if destinationByteIndex + rangeToCopyInData.count >= byteRange.endIndex { | |
break | |
} | |
} | |
let byteRangeBufferPointer = UnsafeRawBufferPointer(start: byteRangePointer, count: byteRange.count) | |
return DispatchData(bytesNoCopy: byteRangeBufferPointer, deallocator: .free) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment