Skip to content

Commit 6327fba

Browse files
committed
Generalize BCD helpers to FixedWidthInteger; add encoder + tests
1 parent 76a78d8 commit 6327fba

File tree

3 files changed

+64
-15
lines changed

3 files changed

+64
-15
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Cornucopia – (C) Dr. Lauer Information Technology
3+
//
4+
public extension FixedWidthInteger {
5+
6+
/// Returns the corresponding BCD-decoded decimal, or `-1`, if the encoding is invalid.
7+
/// NOTE: Only values in the range `0x00`...`0x99` are considered valid.
8+
var CC_BCD: Int {
9+
guard self >= 0 && self <= 0xFF else { return -1 }
10+
let value = UInt8(truncatingIfNeeded: self)
11+
let highNibble = value >> 4
12+
guard highNibble < 10 else { return -1 }
13+
let loNibble = value & 0x0F
14+
guard loNibble < 10 else { return -1 }
15+
return Int(highNibble * 10 + loNibble)
16+
}
17+
18+
/// Returns the BCD-encoded byte for a decimal value (00...99), or `nil` if out of range.
19+
func CC_toBCD() -> Self? {
20+
guard self >= 0 && self <= 99 else { return nil }
21+
let value = UInt8(truncatingIfNeeded: self)
22+
let highNibble = (value / 10) << 4
23+
let loNibble = value % 10
24+
let encoded = Int(highNibble | loNibble)
25+
return Self(exactly: encoded)
26+
}
27+
}

Sources/CornucopiaCore/Extensions/UInt8/UInt8+BCD.swift

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import XCTest
2+
3+
import CornucopiaCore
4+
5+
class FixedWidthInteger_BCD_Tests: XCTestCase {
6+
7+
func testDecodeValid() {
8+
9+
XCTAssertEqual(UInt8(0x00).CC_BCD, 0)
10+
XCTAssertEqual(UInt8(0x42).CC_BCD, 42)
11+
XCTAssertEqual(UInt16(0x99).CC_BCD, 99)
12+
XCTAssertEqual(Int(0x10).CC_BCD, 10)
13+
}
14+
15+
func testDecodeInvalid() {
16+
17+
XCTAssertEqual(UInt8(0xFA).CC_BCD, -1)
18+
XCTAssertEqual(UInt16(0x12A).CC_BCD, -1)
19+
XCTAssertEqual(Int(0x0F).CC_BCD, -1)
20+
XCTAssertEqual(Int(-1).CC_BCD, -1)
21+
}
22+
23+
func testEncodeValid() {
24+
25+
XCTAssertEqual(UInt8(45).CC_toBCD(), 0x45)
26+
XCTAssertEqual(UInt16(90).CC_toBCD(), 0x90)
27+
XCTAssertEqual(Int(99).CC_toBCD(), 0x99)
28+
}
29+
30+
func testEncodeInvalid() {
31+
32+
XCTAssertNil(Int(-1).CC_toBCD())
33+
XCTAssertNil(Int(100).CC_toBCD())
34+
XCTAssertNil(UInt16(120).CC_toBCD())
35+
XCTAssertNil(Int8(80).CC_toBCD())
36+
}
37+
}

0 commit comments

Comments
 (0)