A Swiftier Way to Convert String to Unsafepointer<Xmlchar> in Swift 3 (Libxml2)

A swiftier way to convert String to UnsafePointerxmlChar in Swift 3 (libxml2)

Swiftiest way I can think of is to just use the bitPattern: initializer:

let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }

This will give you an Array of xmlChars. Hang onto that, and use Array's withUnsafeBufferPointer method when you need to pass an UnsafePointer to something:

xmlstr.withUnsafeBufferPointer { someAPIThatWantsAPointer($0.baseAddress!) }

Don't let the UnsafePointer escape from the closure, as it won't be valid outside it.

EDIT: How's this for a compromise? Instead of having your function return a pointer, have it take a closure.

func withXmlString<T>(from string: String, handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
let xmlstr = string.utf8CString.map { xmlChar(bitPattern: $0) }

return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
}

Or, as an extension on String:

extension String {
func withXmlString<T>(handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
let xmlstr = self.utf8CString.map { xmlChar(bitPattern: $0) }

return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
}
}

Swift convert string to UnsafeMutablePointerInt8

Previous answers on StackOverflow using CString don't seem to work anymore

Nevertheless, UnsafePointer<Int8> is a C string. If your context absolutely requires an UnsafeMutablePointer, just coerce, like this:

let s = NSBundle.mainBundle().bundlePath
let cs = (s as NSString).UTF8String
var buffer = UnsafeMutablePointer<Int8>(cs)
swe_set_ephe_path(buffer)

Of course I don't have your swe_set_ephe_path, but it works fine in my testing when it is stubbed like this:

func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
println(String.fromCString(path))
}

How can I convert a String to an MD5 hash in iOS using Swift?

There are two steps:

1. Create md5 data from a string

2. Covert the md5 data to a hex string

Swift 2.0:

func md5(string string: String) -> String {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}

var digestHex = ""
for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}

return digestHex
}

//Test:
let digest = md5(string:"Hello")
print("digest: \(digest)")

Output:

digest: 8b1a9953c4611296a827abf8c47804d7

Swift 3.0:

func MD5(string: String) -> Data {
let messageData = string.data(using:.utf8)!
var digestData = Data(count: Int(CC_MD5_DIGEST_LENGTH))

_ = digestData.withUnsafeMutableBytes {digestBytes in
messageData.withUnsafeBytes {messageBytes in
CC_MD5(messageBytes, CC_LONG(messageData.count), digestBytes)
}
}

return digestData
}

//Test:
let md5Data = MD5(string:"Hello")

let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")

let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")

Output:

md5Hex: 8b1a9953c4611296a827abf8c47804d7

md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==

Swift 5.0:

import Foundation
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG

func MD5(string: String) -> Data {
let length = Int(CC_MD5_DIGEST_LENGTH)
let messageData = string.data(using:.utf8)!
var digestData = Data(count: length)

_ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
messageData.withUnsafeBytes { messageBytes -> UInt8 in
if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let messageLength = CC_LONG(messageData.count)
CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
}
return 0
}
}
return digestData
}

//Test:
let md5Data = MD5(string:"Hello")

let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")

let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")

Output:

md5Hex: 8b1a9953c4611296a827abf8c47804d7

md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==

Notes:

#import <CommonCrypto/CommonCrypto.h> must be added to a Bridging-Header file

For how to create a Bridging-Header see this SO answer.

In general MD5 should not be used for new work, SHA256 is a current best practice.

Example from deprecated documentation section:

MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3+)

These functions will hash either String or Data input with one of eight cryptographic hash algorithms.

The name parameter specifies the hash function name as a String

Supported functions are MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
a
This example requires Common Crypto

It is necessary to have a bridging header to the project:

#import <CommonCrypto/CommonCrypto.h>
Add the Security.framework to the project.



This function takes a hash name and String to be hashed and returns a Data:


name: A name of a hash function as a String
string: The String to be hashed
returns: the hashed result as Data
func hash(name:String, string:String) -> Data? {
let data = string.data(using:.utf8)!
return hash(name:name, data:data)
}

Examples:

let clearString = "clearData0123456"
let clearData = clearString.data(using:.utf8)!
print("clearString: \(clearString)")
print("clearData: \(clearData as NSData)")

let hashSHA256 = hash(name:"SHA256", string:clearString)
print("hashSHA256: \(hashSHA256! as NSData)")

let hashMD5 = hash(name:"MD5", data:clearData)
print("hashMD5: \(hashMD5! as NSData)")

Output:

clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>

hashSHA256: <aabc766b 6b357564 e41f4f91 2d494bcc bfa16924 b574abbd ba9e3e9d a0c8920a>
hashMD5: <4df665f7 b94aea69 695b0e7b baf9e9d6>

Populating MTLBuffer with 16-bit Floats

Half-precision floats in Swift are very awkward, since there is no Float16 type yet (though one has been proposed) and the nonstandard __fp16 type supported by Clang isn't fully supported in Swift either.

Through the magic of type-punning and bridging headers, however, you may be able to cobble together a workable solution.

The basic approach is this: In an Objective-C header, declare a half2 type with two uint16_t members. These will be our storage type. Also declare a function that takes a float and writes it as if it were a __fp16 to a pointer-to-uint16_t:

typedef struct {
uint16_t x, y;
} half2;

static void storeAsF16(float value, uint16_t *_Nonnull pointer) { *(__fp16 *)pointer = value; }

Back in Swift, you can declare a typealias and use it in your particle struct definition:

typealias Half2 = half2

struct Particle {
var position: Half2
}

(Here I'm typealiasing from the lower-case type to a Swiftier name; you could skip this and just name the Obj-C type Half2 if you prefer).

Instead of binding to the particle type, you'll need to bind the buffer to your half vector type instead:

var pointer = particleBuffer.contents().bindMemory(to: Half2.self, capacity: particleCount)

When we use our utility function to store a float, the bit pattern for the corresponding half value gets written to the UInt16:

var x: UInt16 = 0
var y: UInt16 = 0
storeAsF16(1.0, &x) // 0x3c00
storeAsF16(0.5, &y) // 0x3800

Now that we have correctly-formated half values in this pair of variables, we can write them into the buffer:

pointer.pointee = Half2(x: x, y: y)

Note that this approach is neither portable nor safe, especially because Swift doesn't make any guarantees about struct member layout. There may be other less cumbersome approaches, too; this is just what has worked for me in the past.

Swift equivalent to Objective-C FourCharCode single quote literals (e.g. 'TEXT')

I'm using this in my Cocoa Scripting apps, it considers characters > 0x80 correctly

func OSTypeFrom(string : String) -> UInt {
var result : UInt = 0
if let data = string.dataUsingEncoding(NSMacOSRomanStringEncoding) {
let bytes = UnsafePointer<UInt8>(data.bytes)
for i in 0..<data.length {
result = result << 8 + UInt(bytes[i])
}
}
return result
}

Edit:

Alternatively

func fourCharCodeFrom(string : String) -> FourCharCode
{
assert(string.count == 4, "String length must be 4")
var result : FourCharCode = 0
for char in string.utf16 {
result = (result << 8) + FourCharCode(char)
}
return result
}

or still swiftier

func fourCharCode(from string : String) -> FourCharCode
{
return string.utf16.reduce(0, {$0 << 8 + FourCharCode($1)})
}

What is the swift equivalent to setting properties on `id`?

In Swift 2.0 beta 4, your prayers are answered; this code becomes legal:

@IBAction
func handleEvent(sender: AnyObject) {
if sender.respondsToSelector("setHidden:") {
sender.performSelector("setHidden:", withObject: true)
}
}

observing contentSize (CGSize) with KVO in swift

Are you on iOS? Because I am, I did the same thing and arrived at the same question; why NSSize? Maybe that's just the xcode terminal playing a trick on us.

Anyway, you can cast it to an NSValue then you will be able to use CGSizeValue:

if let zeChange = change as? [NSString: NSValue] {
let oldSize = zeChange[NSKeyValueChangeOldKey]?.CGSizeValue()
let newSize = zeChange[NSKeyValueChangeNewKey]?.CGSizeValue()
}


Related Topics



Leave a reply



Submit