From 37d7a036a87b8078ff3f31178d784178733d0a40 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Wed, 8 Feb 2023 18:18:52 +0800 Subject: [PATCH] SwiftExtension // Add String.parsedAsHexLiteral(). --- .../SwiftExtension/SwiftExtension.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift index b9a04a8e..a999c855 100644 --- a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift +++ b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift @@ -245,3 +245,39 @@ public extension Int { self = target.revolvedIndex(self, clockwise: clockwise, steps: steps) } } + +// MARK: - Parse String As Hex Literal + +public extension String { + func parsedAsHexLiteral(encoding: CFStringEncodings? = nil) -> String? { + guard !isEmpty, count % 2 == 0 else { return nil } + guard range(of: "^[a-fA-F0-9]+$", options: .regularExpression) != nil else { return nil } + let encodingRaw: UInt32 = { + if let encoding = encoding { + return UInt32(encoding.rawValue) + } else { + return CFStringBuiltInEncodings.UTF8.rawValue + } + }() + 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 result = data.withUnsafeBytes { n in + CFStringCreateWithBytes(nil, n.baseAddress, data.count, CFStringEncoding(encodingRaw), false) + } + if let string = result { + return string as String + } + return nil + } +}