SwiftExtension // Refactor String.parsedAsHexLiteral().

Co-authored-by: IsaacXen <blackoutxen@gmail.com>
This commit is contained in:
ShikiSuen 2023-02-08 20:37:08 +08:00
parent 37d7a036a8
commit ce0d6e1fe4
1 changed files with 15 additions and 26 deletions

View File

@ -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
} }
} }