SwiftExtension // Refactor String.parsedAsHexLiteral().
Co-authored-by: IsaacXen <blackoutxen@gmail.com>
This commit is contained in:
parent
37d7a036a8
commit
ce0d6e1fe4
|
@ -248,36 +248,25 @@ public extension Int {
|
||||||
|
|
||||||
// MARK: - Parse String As Hex Literal
|
// MARK: - Parse String As Hex Literal
|
||||||
|
|
||||||
|
// Original author: Shiki Suen
|
||||||
|
// Refactored by: Isaac Xen
|
||||||
|
|
||||||
public extension String {
|
public extension String {
|
||||||
func parsedAsHexLiteral(encoding: CFStringEncodings? = nil) -> String? {
|
func parsedAsHexLiteral(encoding: CFStringEncodings? = nil) -> String? {
|
||||||
guard !isEmpty, count % 2 == 0 else { return nil }
|
guard !isEmpty else { return nil }
|
||||||
guard range(of: "^[a-fA-F0-9]+$", options: .regularExpression) != nil else { return nil }
|
var charBytes = [Int8]()
|
||||||
let encodingRaw: UInt32 = {
|
var buffer: Int?
|
||||||
if let encoding = encoding {
|
compactMap(\.hexDigitValue).forEach { neta in
|
||||||
return UInt32(encoding.rawValue)
|
if let validBuffer = buffer {
|
||||||
|
charBytes.append(.init(bitPattern: UInt8(validBuffer << 4 + neta)))
|
||||||
|
buffer = nil
|
||||||
} else {
|
} else {
|
||||||
return CFStringBuiltInEncodings.UTF8.rawValue
|
buffer = neta
|
||||||
}
|
|
||||||
}()
|
|
||||||
let charBytesRAW: [Int] = compactMap(\.hexDigitValue)
|
|
||||||
var charBytes = [UInt8]()
|
|
||||||
var buffer = 0
|
|
||||||
charBytesRAW.forEach { neta in
|
|
||||||
if buffer == 0 {
|
|
||||||
buffer += neta
|
|
||||||
} else {
|
|
||||||
buffer = Int(buffer) * 16
|
|
||||||
charBytes.append(UInt8(buffer + neta))
|
|
||||||
buffer = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let data = Data(charBytes)
|
let encodingUBE = CFStringBuiltInEncodings.UTF16BE.rawValue
|
||||||
let result = data.withUnsafeBytes { n in
|
let encodingRAW = encoding.map { UInt32($0.rawValue) } ?? encodingUBE
|
||||||
CFStringCreateWithBytes(nil, n.baseAddress, data.count, CFStringEncoding(encodingRaw), false)
|
let result = CFStringCreateWithCString(nil, &charBytes, encodingRAW) as String?
|
||||||
}
|
return result?.isEmpty ?? true ? nil : result
|
||||||
if let string = result {
|
|
||||||
return string as String
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue