Skip to content

Commit ccfe362

Browse files
committed
Add CrcKeysStorage enum and helper methods
- [x] 1. Phase 1: Add CrcKeysStorage enum and helper methods - Add CrcKeysStorage enum with KeysFold256 and KeysFutureTest variants - Implement get_key() and key_count() methods on CrcKeysStorage - Add const constructor methods from_keys_fold_256() and from_keys_fold_future_test() - Add safe accessor methods to CrcParams that delegate to existing keys field - Write comprehensive unit tests for CrcKeysStorage functionality
1 parent dfc6de6 commit ccfe362

File tree

3 files changed

+205
-1
lines changed

3 files changed

+205
-1
lines changed

.kiro/specs/future-proof-crc-params/tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Implementation Plan
22

3-
- [ ] 1. Phase 1: Add CrcKeysStorage enum and helper methods
3+
- [x] 1. Phase 1: Add CrcKeysStorage enum and helper methods
44
- Add CrcKeysStorage enum with KeysFold256 and KeysFutureTest variants
55
- Implement get_key() and key_count() methods on CrcKeysStorage
66
- Add const constructor methods from_keys_fold_256() and from_keys_fold_future_test()

src/lib.rs

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,63 @@ pub enum CrcAlgorithm {
162162
Crc64Xz,
163163
}
164164

165+
/// Internal storage for CRC folding keys that can accommodate different array sizes.
166+
/// This enum allows future expansion to support larger folding distances while maintaining
167+
/// backwards compatibility with existing const definitions.
168+
#[derive(Clone, Copy, Debug)]
169+
#[allow(dead_code)] // Used in Phase 3 of migration
170+
enum CrcKeysStorage {
171+
/// Current 23-key format for existing algorithms (supports up to 256-byte folding distances)
172+
KeysFold256([u64; 23]),
173+
/// Future 25-key format for potential expanded folding distances (testing purposes only)
174+
KeysFutureTest([u64; 25]),
175+
}
176+
177+
#[allow(dead_code)] // Used in Phase 3 of migration
178+
impl CrcKeysStorage {
179+
/// Safe key access with bounds checking. Returns 0 for out-of-bounds indices.
180+
#[inline(always)]
181+
const fn get_key(self, index: usize) -> u64 {
182+
match self {
183+
CrcKeysStorage::KeysFold256(keys) => {
184+
if index < 23 {
185+
keys[index]
186+
} else {
187+
0
188+
}
189+
}
190+
CrcKeysStorage::KeysFutureTest(keys) => {
191+
if index < 25 {
192+
keys[index]
193+
} else {
194+
0
195+
}
196+
}
197+
}
198+
}
199+
200+
/// Returns the number of keys available in this storage variant.
201+
#[inline(always)]
202+
const fn key_count(self) -> usize {
203+
match self {
204+
CrcKeysStorage::KeysFold256(_) => 23,
205+
CrcKeysStorage::KeysFutureTest(_) => 25,
206+
}
207+
}
208+
209+
/// Const constructor for 23-key arrays (current format).
210+
#[inline(always)]
211+
const fn from_keys_fold_256(keys: [u64; 23]) -> Self {
212+
CrcKeysStorage::KeysFold256(keys)
213+
}
214+
215+
/// Const constructor for 25-key arrays (future expansion testing).
216+
#[inline(always)]
217+
const fn from_keys_fold_future_test(keys: [u64; 25]) -> Self {
218+
CrcKeysStorage::KeysFutureTest(keys)
219+
}
220+
}
221+
165222
/// Parameters for CRC computation, including polynomial, initial value, and other settings.
166223
#[derive(Clone, Copy, Debug)]
167224
pub struct CrcParams {
@@ -1100,4 +1157,120 @@ mod lib {
11001157
CRC64_ECMA_182.check,
11011158
)
11021159
}
1160+
1161+
#[test]
1162+
fn test_crc_keys_storage_fold_256() {
1163+
let test_keys = [
1164+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
1165+
];
1166+
let storage = CrcKeysStorage::from_keys_fold_256(test_keys);
1167+
1168+
// Test valid key access
1169+
for i in 0..23 {
1170+
assert_eq!(storage.get_key(i), test_keys[i]);
1171+
}
1172+
1173+
// Test out-of-bounds access returns 0
1174+
assert_eq!(storage.get_key(23), 0);
1175+
assert_eq!(storage.get_key(24), 0);
1176+
assert_eq!(storage.get_key(100), 0);
1177+
1178+
// Test key count
1179+
assert_eq!(storage.key_count(), 23);
1180+
}
1181+
1182+
#[test]
1183+
fn test_crc_keys_storage_future_test() {
1184+
let test_keys = [
1185+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1186+
25,
1187+
];
1188+
let storage = CrcKeysStorage::from_keys_fold_future_test(test_keys);
1189+
1190+
// Test valid key access
1191+
for i in 0..25 {
1192+
assert_eq!(storage.get_key(i), test_keys[i]);
1193+
}
1194+
1195+
// Test out-of-bounds access returns 0
1196+
assert_eq!(storage.get_key(25), 0);
1197+
assert_eq!(storage.get_key(26), 0);
1198+
assert_eq!(storage.get_key(100), 0);
1199+
1200+
// Test key count
1201+
assert_eq!(storage.key_count(), 25);
1202+
}
1203+
1204+
#[test]
1205+
fn test_crc_params_safe_accessors() {
1206+
// Create a test CrcParams with known keys
1207+
let test_keys = [
1208+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
1209+
];
1210+
let params = CrcParams {
1211+
algorithm: CrcAlgorithm::Crc32IsoHdlc,
1212+
name: "test",
1213+
width: 32,
1214+
poly: 0x04C11DB7,
1215+
init: 0xFFFFFFFF,
1216+
refin: true,
1217+
refout: true,
1218+
xorout: 0xFFFFFFFF,
1219+
check: 0xCBF43926,
1220+
keys: test_keys,
1221+
};
1222+
1223+
// Test valid key access
1224+
for i in 0..23 {
1225+
assert_eq!(params.get_key(i), test_keys[i]);
1226+
assert_eq!(params.get_key_checked(i), Some(test_keys[i]));
1227+
}
1228+
1229+
// Test out-of-bounds access
1230+
assert_eq!(params.get_key(23), 0);
1231+
assert_eq!(params.get_key(24), 0);
1232+
assert_eq!(params.get_key(100), 0);
1233+
1234+
assert_eq!(params.get_key_checked(23), None);
1235+
assert_eq!(params.get_key_checked(24), None);
1236+
assert_eq!(params.get_key_checked(100), None);
1237+
1238+
// Test key count
1239+
assert_eq!(params.key_count(), 23);
1240+
}
1241+
1242+
#[test]
1243+
fn test_crc_keys_storage_const_constructors() {
1244+
// Test that const constructors work in const context
1245+
const TEST_KEYS_23: [u64; 23] = [1; 23];
1246+
const TEST_KEYS_25: [u64; 25] = [2; 25];
1247+
1248+
const STORAGE_256: CrcKeysStorage = CrcKeysStorage::from_keys_fold_256(TEST_KEYS_23);
1249+
const STORAGE_FUTURE: CrcKeysStorage =
1250+
CrcKeysStorage::from_keys_fold_future_test(TEST_KEYS_25);
1251+
1252+
// Verify the const constructors work correctly
1253+
assert_eq!(STORAGE_256.get_key(0), 1);
1254+
assert_eq!(STORAGE_256.key_count(), 23);
1255+
1256+
assert_eq!(STORAGE_FUTURE.get_key(0), 2);
1257+
assert_eq!(STORAGE_FUTURE.key_count(), 25);
1258+
}
1259+
1260+
#[test]
1261+
fn test_crc_keys_storage_bounds_safety() {
1262+
let storage_256 = CrcKeysStorage::from_keys_fold_256([42; 23]);
1263+
let storage_future = CrcKeysStorage::from_keys_fold_future_test([84; 25]);
1264+
1265+
// Test edge cases for bounds checking
1266+
assert_eq!(storage_256.get_key(22), 42); // Last valid index
1267+
assert_eq!(storage_256.get_key(23), 0); // First invalid index
1268+
1269+
assert_eq!(storage_future.get_key(24), 84); // Last valid index
1270+
assert_eq!(storage_future.get_key(25), 0); // First invalid index
1271+
1272+
// Test very large indices
1273+
assert_eq!(storage_256.get_key(usize::MAX), 0);
1274+
assert_eq!(storage_future.get_key(usize::MAX), 0);
1275+
}
11031276
}

src/structs.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,35 @@ impl CrcParams {
7979
keys,
8080
}
8181
}
82+
83+
/// Gets a key at the specified index, returning 0 if out of bounds.
84+
/// This provides safe access regardless of internal key storage format.
85+
#[inline(always)]
86+
pub fn get_key(self, index: usize) -> u64 {
87+
// Phase 1: Delegate to existing keys field for backwards compatibility
88+
if index < 23 {
89+
self.keys[index]
90+
} else {
91+
0
92+
}
93+
}
94+
95+
/// Gets a key at the specified index, returning None if out of bounds.
96+
/// This provides optional key access for cases where bounds checking is needed.
97+
#[inline(always)]
98+
pub fn get_key_checked(self, index: usize) -> Option<u64> {
99+
// Phase 1: Delegate to existing keys field for backwards compatibility
100+
if index < 23 {
101+
Some(self.keys[index])
102+
} else {
103+
None
104+
}
105+
}
106+
107+
/// Returns the number of keys available in this CrcParams instance.
108+
#[inline(always)]
109+
pub fn key_count(self) -> usize {
110+
// Phase 1: Return fixed count for existing keys field
111+
23
112+
}
82113
}

0 commit comments

Comments
 (0)