Swift 2 #convention use error - swift

I have a problem with Swift 2, I'm not able to convert this part of my code:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
let transient = CFunctionPointer<((UnsafeMutablePointer<()>) -> Void)>(tranPointer)
I receive this error:
'CFunctionPointer' is unavailable: use a function type '#convention(c) (T) -> U'
I am trying to change it for this way:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
But I am not able to use transient2 and I am not sure why.
Than you

I have been playing around with your code inside a Swift playground and noticed that this piece of code (your substitution to the original one) fails due to the bitPattern when it's set to -1 (notice that I've been getting a runtime exception - not a compiler error). When I replaced it with something appropriate (e.g. with 1, as bitPattern must represent a valid address inside you virtual address space and, as implied, must be a non-negative integer) it worked out. I managed to make it up and running with the following code:
import Foundation
let intTran = UnsafeMutablePointer<Int>(bitPattern: 1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
let abc: transient2? = nil
Good luck, hope this solves your problem.

Related

'withUnsafeMutableBytes' is deprecated: use `withUnsafeMutableBytes<R>

I am very green with Xcode (apologize in advance). Trying to bring some old code to life. Getting the following with trying to move to Swift 5.
withUnsafeMutableBytes' is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead
Goal: All I need to do is modify the code appropriately and be done.
I have looked at other Stack Overflow messages, searched various articles, experimented with different things, but can't quickly determine what needs to change. I am sure the solution is super simple for someone that knows more.
var responseData = Data(count: Int(responseDataLength))
_ = responseData.withUnsafeMutableBytes
{
mfError = MFMediaIDResponse_GetAsString(mfMediaIdResponsePtr.pointee, MFString($0), responseDataLength)
}
Here is my example, when refreshing old code of withUnsafeMutableBytes
hope it helps
The old one:
_ = data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
memcpy((ioData.pointee.mBuffers.mData?.assumingMemoryBound(to: UInt8.self))!, bytes, dataCount)
}
The new one:
_ = data.withUnsafeMutableBytes { (rawMutableBufferPointer) in
let bufferPointer = rawMutableBufferPointer.bindMemory(to: UInt8.self)
if let address = bufferPointer.baseAddress{
memcpy((ioData.pointee.mBuffers.mData?.assumingMemoryBound(to: UInt8.self))!, address, dataCount)
}
}
Explains:
use UnsafeMutablePointer<ContentType>, you get an unsafeMutablePointer in its closure.
To access to its memory, so need to typed it with bindMemory,
more details on Apple Pointer Doc

Is there any way to know how Swift calculates hashValue?

I recently found that the code below ends up with hash collision.
FYI, I'm using XCode 9.4.1 (9F2000), which uses Swift 4.1.2
import Foundation
let lhs = "あいうえおあいう21あいうえ"
let rhs = "あいうえおあいう22あいうえ"
let percentEncodedLhs = lhs.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let percentEncodedRhs = rhs.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
let lhsHashValue = lhs.hashValue
let rhsHashValue = rhs.hashValue
let lhsPercentHashValue = percentEncodedLhs.hashValue
let rhsPercentHashValue = percentEncodedRhs.hashValue
print(lhsHashValue == rhsHashValue)
print(lhsPercentHashValue == rhsPercentHashValue)
/*
Output:
false
true
*/
I know that hash collision can happen in some circumstance, but I couldn't find how Swift calculates hashValue for String.
For example, Java calculates hashCode of String like:
https://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()
Is there any official explanation or maybe some assumptions?
but I couldn't find how Swift calculates hashValue for String
Why couldn’t you? Swift is open source. If you are interested, read the source.
https://github.com/apple/swift/blob/111499d2bfc58dc12fcb9cd1ce1dda7978c995b7/stdlib/public/core/StringHashable.swift

Swift 4: 'subscript' is unavailable error

I'm using the MapBox navigation framework that hasn't quite been updated to Swift 4. I have one 'subscript' error that I can't quite get around. Here's the code. I'd really appreciate any help. Thank you.
private func extractNextChunk(_ encodedString: inout String.UnicodeScalarView) throws -> String {
var currentIndex = encodedString.startIndex
while currentIndex != encodedString.endIndex {
let currentCharacterValue = Int32(encodedString[currentIndex].value)
if isSeparator(currentCharacterValue) {
let extractedScalars = encodedString[encodedString.startIndex...currentIndex]
encodedString = encodedString[encodedString.index(after: currentIndex)..<encodedString.endIndex]
return String(extractedScalars)
}
currentIndex = encodedString.index(after: currentIndex)
}
throw PolylineError.chunkExtractingError
}
The error message is misleading. The real problem is that subscripting
a String.UnicodeScalarView with a range returns a String.UnicodeScalarView.SubSequence, so you cannot assign that back to
encodedString.
One solution would be to create a String.UnicodeScalarView
from the subsequence:
encodedString = String.UnicodeScalarView(encodedString[encodedString.index(after: currentIndex)...])
Alternatively (and perhaps simpler) go the other way around and
remove the initial part of encodedString instead:
encodedString.removeSubrange(...currentIndex)
In either case, you can take use "one-sided ranges", compare
SE-0172

Calling getsectiondata from Swift

This question and answer describe how to read data from a Mach-O section with Objective-C on modern OS X/macOS versions: Crash reading bytes from getsectbyname
The described answer works. I'm trying to implement the same thing with Swift. I can't make it work.
I have the following in "Other linker flags": -Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r.
This Swift code gets me the a pointer to the embedded data, until I try to run the code outside Xcode and ASLR breaks it:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
To get around the ASLR problem, according to the above question and answer, and based on my own testing, I should be using getsectiondata instead. It works great in Objective-C, but I'm having no luck in Swift. The following is the only thing I've managed to get past the compiler, but it returns nil:
var size: UInt = 0
var header = _mh_execute_header
let localizationSection = getsectiondata(
&header,
"__LOCALIZATIONS",
"__base",
&size)
Is taking a copy of _mh_execute_header the problem and is there any way to avoid it? I need an UnsafePointer<mach_header_64>, but using &_mh_execute_header as the first parameter to getsectiondata causes a compilation error.
I'm using Swift 3.0, and running my code on macOS 10.12.
The difference between the linked-to Objective-C code
void *ptr = getsectiondata(&_mh_execute_header, ...);
and your Swift translation
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
is that the latter passes the address of a copy of the global
_mh_execute_header variable to the function, and apparently that
is not accepted. If you modify the Objective-C code to
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
then it fails as well (and actually crashed in my test).
Now the problem is that _mh_execute_header is exposed to Swift
as a constant:
public let _mh_execute_header: mach_header_64
and one cannot take the address of a constant in Swift. One possible
workaround is to define
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
in the bridging header file, and then use it as
let localizationSection = getsectiondata(mhExecHeaderPtr, ...)
in Swift.
Another option is to lookup the symbol via dlopen/dlsym
import MachO
if let handle = dlopen(nil, RTLD_LAZY) {
defer { dlclose(handle) }
if let ptr = dlsym(handle, MH_EXECUTE_SYM) {
let mhExecHeaderPtr = ptr.assumingMemoryBound(to: mach_header_64.self)
var size: UInt = 0
let localizationSection = getsectiondata(
mhExecHeaderPtr,
"__LOCALIZATIONS",
"__base",
&size)
// ...
}
}

Swift: what's the difference between Array<OtherModule.MyType>() and [OtherModule.MyType]()

I'm using a type from a different module, let's call it OtherModule.MyType,
This code:
var a = [OtherModule.MyType]()
will produce an error invalid use of '()' to call a value of non-function type '[MyType.Type]'
This code won't:
var ax = [OtherModule.MyType]
But I believe ax is not an array any more, since this code
ax.append(OtherModule.MyType())
will cause an error Cannot invoke 'append' with an argument list of '(MyType)'
So I wonder what ax really is?
Besides, this code works fine:
var ay = Array<OtherModule.MyType>()
ay.append(OtherModule.MyType())
UPDATE:
I'm using swift 1.2 with Xcode 6.3
For some reason best known to the Swift team (modules are very scantly documented), Module.Thing behaves differently to Thing.
While Int is just a type name:
let i: Int = 1 // fine
// not fine, "expected member name or constructor call after type name"
let j = Int
Swift.Int can be both:
// used as a type name
let k: Swift.Int = 1
let t = Swift.Int.self
// but also used as a value
let x = Swift.Int
// equivalent to this
let y = Int.self
toString(x) == toString(y) // true
Under some uses it only wants to be a value, not a type name though. Hence this works:
// a will be of type [Int.Type], initialized with an array
// literal of 1 element, the Int metatype
let a = [Swift.Int]
But trying to use it as a type name in this context fails: [Swift.Int]() is no more valid than writing [1]() or let strs = ["fred"]; strs().
This behaviour seems a little arbitrary, and may even be a bug/unintentional.
Since the only way in which Swift.Int can be used in this context:
Array<Swift.Int>()
is as a type not a value (since only types can go between the angle brackets), it kind of makes sense that this works while the more ambiguous array literal syntax behaves differently.