Files
swift-mirror/validation-test/stdlib/CoreAudio.swift
Andrew Trick 0b75ee975e Remove "illegal" UnsafePointer casts from the stdlib.
Update for SE-0107: UnsafeRawPointer

This adds a "mutating" initialize to UnsafePointer to make
Immutable -> Mutable conversions explicit.

These are quick fixes to stdlib, overlays, and test cases that are necessary
in order to remove arbitrary UnsafePointer conversions.

Many cases can be expressed better up by reworking the surrounding
code, but we first need a working starting point.
2016-07-28 20:42:23 -07:00

307 lines
10 KiB
Swift

// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// REQUIRES: objc_interop
// UNSUPPORTED: OS=watchos
import StdlibUnittest
import StdlibCollectionUnittest
import CoreAudio
// Used in tests below.
extension AudioBuffer : Equatable {}
public func == (lhs: AudioBuffer, rhs: AudioBuffer) -> Bool {
return lhs.mNumberChannels == rhs.mNumberChannels &&
lhs.mDataByteSize == rhs.mDataByteSize &&
lhs.mData == rhs.mData
}
var CoreAudioTestSuite = TestSuite("CoreAudio")
// The size of the non-flexible part of an AudioBufferList.
#if arch(i386) || arch(arm)
let ablHeaderSize = 4
#elseif arch(x86_64) || arch(arm64)
let ablHeaderSize = 8
#endif
CoreAudioTestSuite.test("UnsafeBufferPointer.init(_: AudioBuffer)") {
do {
let audioBuffer = AudioBuffer(
mNumberChannels: 0, mDataByteSize: 0, mData: nil)
let result: UnsafeBufferPointer<Float> = UnsafeBufferPointer(audioBuffer)
expectEqual(nil, result.baseAddress)
expectEqual(0, result.count)
}
do {
let audioBuffer = AudioBuffer(
mNumberChannels: 2, mDataByteSize: 1024,
mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678))
let result: UnsafeBufferPointer<Float> = UnsafeBufferPointer(audioBuffer)
expectEqual(audioBuffer.mData, UnsafeRawPointer(result.baseAddress!))
expectEqual(256, result.count)
}
}
CoreAudioTestSuite.test("UnsafeMutableBufferPointer.init(_: AudioBuffer)") {
do {
let audioBuffer = AudioBuffer(
mNumberChannels: 0, mDataByteSize: 0, mData: nil)
let result: UnsafeMutableBufferPointer<Float> =
UnsafeMutableBufferPointer(audioBuffer)
expectEqual(nil, result.baseAddress)
expectEqual(0, result.count)
}
do {
let audioBuffer = AudioBuffer(
mNumberChannels: 2, mDataByteSize: 1024,
mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678))
let result: UnsafeMutableBufferPointer<Float> =
UnsafeMutableBufferPointer(audioBuffer)
expectEqual(audioBuffer.mData!, UnsafeMutableRawPointer(result.baseAddress!))
expectEqual(256, result.count)
}
}
CoreAudioTestSuite.test(
"AudioBuffer.init(_: UnsafeMutableBufferPointer, numberOfChannels: Int)") {
do {
// NULL pointer.
let buffer = UnsafeMutableBufferPointer<Float>(start: nil, count: 0)
let result = AudioBuffer(buffer, numberOfChannels: 2)
expectEqual(2, result.mNumberChannels)
expectEqual(0, result.mDataByteSize)
expectEqual(nil, result.mData)
}
do {
// Non-NULL pointer.
let buffer = UnsafeMutableBufferPointer<Float>(
start: UnsafeMutablePointer<Float>(bitPattern: 0x1234_5678), count: 0)
let result = AudioBuffer(buffer, numberOfChannels: 2)
expectEqual(2, result.mNumberChannels)
expectEqual(0, result.mDataByteSize)
expectEqual(buffer.baseAddress, result.mData)
}
}
CoreAudioTestSuite.test(
"AudioBuffer.init(_: UnsafeMutableBufferPointer, numberOfChannels: Int)/trap") {
#if arch(i386) || arch(arm)
let overflowingCount = Int.max
#elseif arch(x86_64) || arch(arm64)
let overflowingCount = Int(UInt32.max)
#endif
let buffer = UnsafeMutableBufferPointer<Float>(
start: UnsafeMutablePointer<Float>(bitPattern: 0x1234_5678),
count: overflowingCount)
expectCrashLater()
// An overflow happens when we try to compute the value for mDataByteSize.
_ = AudioBuffer(buffer, numberOfChannels: 2)
}
CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)") {
expectEqual(ablHeaderSize + strideof(AudioBuffer.self),
AudioBufferList.sizeInBytes(maximumBuffers: 1))
expectEqual(ablHeaderSize + 16 * strideof(AudioBuffer.self),
AudioBufferList.sizeInBytes(maximumBuffers: 16))
}
CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/count<0") {
expectCrashLater()
_ = AudioBufferList.sizeInBytes(maximumBuffers: -1)
}
CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/count==0") {
expectCrashLater()
_ = AudioBufferList.sizeInBytes(maximumBuffers: -1)
}
CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/overflow") {
expectCrashLater()
_ = AudioBufferList.sizeInBytes(maximumBuffers: Int.max)
}
CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)") {
do {
let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 1)
expectEqual(1, ablPtrWrapper.count)
free(ablPtrWrapper.unsafeMutablePointer)
}
do {
let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 16)
expectEqual(16, ablPtrWrapper.count)
free(ablPtrWrapper.unsafeMutablePointer)
}
}
CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/count==0") {
expectCrashLater()
_ = AudioBufferList.allocate(maximumBuffers: 0)
}
CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/count<0") {
expectCrashLater()
_ = AudioBufferList.allocate(maximumBuffers: -1)
}
CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/overflow") {
expectCrashLater()
_ = AudioBufferList.allocate(maximumBuffers: Int.max)
}
CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer/AssociatedTypes") {
typealias Subject = UnsafeMutableAudioBufferListPointer
expectRandomAccessCollectionAssociatedTypes(
collectionType: Subject.self,
iteratorType: IndexingIterator<Subject>.self,
subSequenceType: MutableRandomAccessSlice<Subject>.self,
indexType: Int.self,
indexDistanceType: Int.self,
indicesType: CountableRange<Int>.self)
}
CoreAudioTestSuite.test(
"UnsafeMutableAudioBufferListPointer.init(_: UnsafeMutablePointer<AudioBufferList>)," +
"UnsafeMutableAudioBufferListPointer.unsafePointer," +
"UnsafeMutableAudioBufferListPointer.unsafeMutablePointer") {
do {
let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(nil)
expectEmpty(ablPtrWrapper)
}
do {
let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(
UnsafeMutablePointer<AudioBufferList>(bitPattern: 0x1234_5678)!)
expectEqual(
UnsafePointer<AudioBufferList>(bitPattern: 0x1234_5678),
ablPtrWrapper.unsafePointer)
expectEqual(
UnsafePointer<AudioBufferList>(bitPattern: 0x1234_5678),
ablPtrWrapper.unsafeMutablePointer)
}
do {
let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(
UnsafeMutablePointer<AudioBufferList>(bitPattern: 0x1234_5678))
expectNotEmpty(ablPtrWrapper)
expectEqual(
UnsafePointer<AudioBufferList>(bitPattern: 0x1234_5678),
ablPtrWrapper!.unsafePointer)
expectEqual(
UnsafePointer<AudioBufferList>(bitPattern: 0x1234_5678),
ablPtrWrapper!.unsafeMutablePointer)
}
}
CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.count") {
let sizeInBytes = AudioBufferList.sizeInBytes(maximumBuffers: 16)
let rawPtr = UnsafeMutableRawPointer.allocate(
bytes: sizeInBytes, alignedTo: alignof(AudioBufferList.self))
let ablPtr = rawPtr.bindMemory(to: AudioBufferList.self,
capacity: sizeInBytes / strideof(AudioBufferList.self))
// It is important that 'ablPtrWrapper' is a 'let'. We are verifying that
// the 'count' property has a nonmutating setter.
let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(ablPtr)
// Test getter.
rawPtr.storeBytes(of: 0x1234_5678, as: UInt32.self)
expectEqual(0x1234_5678, ablPtrWrapper.count)
// Test setter.
ablPtrWrapper.count = 0x7765_4321
expectEqual(0x7765_4321, rawPtr.load(as: UInt32.self))
rawPtr.deallocate(
bytes: sizeInBytes, alignedTo: alignof(AudioBufferList.self))
}
CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)") {
let sizeInBytes = AudioBufferList.sizeInBytes(maximumBuffers: 16)
let rawPtr = UnsafeMutableRawPointer.allocate(
bytes: sizeInBytes, alignedTo: 1)
let ablPtr = rawPtr.bindMemory(
to: AudioBufferList.self,
capacity: sizeInBytes / sizeof(AudioBufferList.self))
// It is important that 'ablPtrWrapper' is a 'let'. We are verifying that
// the subscript has a nonmutating setter.
let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(ablPtr)
do {
// Test getter.
let audioBuffer = AudioBuffer(
mNumberChannels: 2, mDataByteSize: 1024,
mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678))
let bufPtr = (rawPtr + ablHeaderSize).assumingMemoryBound(
to: AudioBuffer.self)
bufPtr.pointee = audioBuffer
ablPtrWrapper.count = 1
expectEqual(2, ablPtrWrapper[0].mNumberChannels)
expectEqual(1024, ablPtrWrapper[0].mDataByteSize)
expectEqual(audioBuffer.mData, ablPtrWrapper[0].mData)
}
do {
// Test setter.
let audioBuffer = AudioBuffer(
mNumberChannels: 5, mDataByteSize: 256,
mData: UnsafeMutableRawPointer(bitPattern: 0x8765_4321 as UInt))
ablPtrWrapper.count = 2
ablPtrWrapper[1] = audioBuffer
let audioBufferPtr = (rawPtr + ablHeaderSize).assumingMemoryBound(
to: AudioBuffer.self) + 1
expectEqual(5, audioBufferPtr.pointee.mNumberChannels)
expectEqual(256, audioBufferPtr.pointee.mDataByteSize)
expectEqual(audioBuffer.mData, audioBufferPtr.pointee.mData)
}
ablPtr.deallocate(capacity: sizeInBytes)
}
CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)/trap") {
let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 4)
ablPtrWrapper[0].mNumberChannels = 42
ablPtrWrapper[1].mNumberChannels = 42
ablPtrWrapper[2].mNumberChannels = 42
ablPtrWrapper[3].mNumberChannels = 42
expectCrashLater()
ablPtrWrapper[4].mNumberChannels = 42
}
CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer/Collection") {
var ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 16)
expectType(UnsafeMutableAudioBufferListPointer.self, &ablPtrWrapper)
var expected: [AudioBuffer] = []
for i in 0..<16 {
let audioBuffer = AudioBuffer(
mNumberChannels: UInt32(2 + i), mDataByteSize: UInt32(1024 * i),
mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678 + i * 10))
ablPtrWrapper[i] = audioBuffer
expected.append(audioBuffer)
}
// FIXME: use checkMutableRandomAccessCollection, when we have that function.
checkRandomAccessCollection(expected, ablPtrWrapper)
free(ablPtrWrapper.unsafeMutablePointer)
}
runAllTests()