Skip to content

Commit

Permalink
#154 Improve BluetoothAddress Embedded Swift support
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Nov 6, 2024
1 parent 825e336 commit c36b496
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
8 changes: 6 additions & 2 deletions Sources/Bluetooth/Address.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ extension BluetoothAddress: RawRepresentable {

/// Initialize a Bluetooth Address from its big endian string representation (e.g. `00:1A:7D:DA:71:13`).
public init?(rawValue: String) {
self.init(rawValue)
}

/// Initialize a Bluetooth Address from its big endian string representation (e.g. `00:1A:7D:DA:71:13`).
internal init?<S: StringProtocol>(_ rawValue: S) {

// verify string length
let characters = rawValue.utf8
Expand All @@ -107,8 +112,7 @@ extension BluetoothAddress: RawRepresentable {
for (index, subsequence) in components.enumerated() {

guard subsequence.count == 2,
let string = String(subsequence),
let byte = UInt8(hexadecimal: string)
let byte = UInt8(hexadecimal: subsequence)
else { return nil }

withUnsafeMutablePointer(to: &bytes) {
Expand Down
53 changes: 34 additions & 19 deletions Sources/Bluetooth/Extensions/Hexadecimal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,14 @@ internal extension Collection where Element: FixedWidthInteger {

internal extension FixedWidthInteger {

init?(parse string: String, radix: Self) {
init?<S: StringProtocol>(parse string: S, radix: Self) {
#if !hasFeature(Embedded)
let string = string.uppercased()
#endif
let digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".utf8
var result = Self(0)
for character in string.utf8 {
if let stringIndex = digits.enumerated().first(where: { $0.element == character })?.offset {
let val = Self(stringIndex)
if val >= radix {
return nil
}
result = result * radix + val
} else {
return nil
}
}
self = result
self.init(utf8: string.utf8, radix: radix)
}
}

internal extension FixedWidthInteger {

init?(hexadecimal string: String) {
init?<S: StringProtocol>(hexadecimal string: S) {
guard string.utf8.count == MemoryLayout<Self>.size * 2 else {
return nil
}
Expand All @@ -68,6 +52,37 @@ internal extension FixedWidthInteger {
self.init(string, radix: 16)
#endif
}

init?<C>(hexadecimal utf8: C) where C: Collection, C.Element == UInt8 {
guard utf8.count == MemoryLayout<Self>.size * 2 else {
return nil
}
guard let value = Self(utf8: utf8, radix: 16) else {
return nil
}
self.init(value)
}

/// Expects uppercase UTF8 data.
init?<C>(utf8: C, radix: Self) where C: Collection, C.Element == UInt8 {
#if !hasFeature(Embedded) && DEBUG
assert(String(decoding: utf8, as: UTF8.self) == String(decoding: utf8, as: UTF8.self).uppercased(), "Expected uppercase string")
#endif
let digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".utf8
var result = Self(0)
for character in utf8 {
if let stringIndex = digits.enumerated().first(where: { $0.element == character })?.offset {
let val = Self(stringIndex)
if val >= radix {
return nil
}
result = result * radix + val
} else {
return nil
}
}
self = result
}
}

#if !hasFeature(Embedded)
Expand Down

0 comments on commit c36b496

Please sign in to comment.