#[cfg(not(feature = "std"))]
use crate::consts::{ASK_MAX_BUF_LEN_USIZE, ASK_MAX_PAYLOAD_LEN_USIZE};
#[cfg(not(feature = "std"))]
use heapless::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
pub static SYMBOLS: [u8; 16] = [
0xd, 0xe, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34,
];
pub fn encode_4b6b(byte: u8) -> [u8; 2] {
let high = byte >> 4;
let low = byte & 0x0F;
[SYMBOLS[high as usize], SYMBOLS[low as usize]]
}
pub fn decode_6b4b(symbol1: &u8, symbol2: &u8) -> u8 {
let b1 = SYMBOLS.iter().position(|s| s == symbol1).unwrap_or(0) as u8;
let b2 = SYMBOLS.iter().position(|s| s == symbol2).unwrap_or(0) as u8;
(b1 << 4) | b2
}
#[cfg(feature = "std")]
pub fn encode_buffer(input: &[u8]) -> Vec<u8> {
let mut output = Vec::with_capacity(input.len() * 2);
for &byte in input {
output.extend_from_slice(&encode_4b6b(byte));
}
output
}
#[cfg(not(feature = "std"))]
pub fn encode_buffer(input: &[u8]) -> Vec<u8, ASK_MAX_BUF_LEN_USIZE> {
let mut output = Vec::new();
for &byte in input {
let _ = output.extend_from_slice(&encode_4b6b(byte));
}
output
}
#[cfg(feature = "std")]
pub fn decode_buffer(input: &[u8]) -> Vec<u8> {
if input.len() % 2 != 0 {
return Vec::new(); }
let mut output: Vec<u8> = Vec::with_capacity(input.len() / 2);
for chunk in input.chunks(2) {
output.push(decode_6b4b(&chunk[0], &chunk[1]));
}
output
}
#[cfg(not(feature = "std"))]
pub fn decode_buffer(input: &[u8]) -> Vec<u8, ASK_MAX_PAYLOAD_LEN_USIZE> {
if input.len() % 2 != 0 {
return Vec::new(); }
let mut output = Vec::new();
for chunk in input.chunks(2) {
let _ = output.push(decode_6b4b(&chunk[0], &chunk[1]));
}
output
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_encode_4b6b_correct_output() {
let encoded = encode_4b6b(0xAB); assert_eq!(encoded[0], 0x26);
assert_eq!(encoded[1], 0x29);
}
#[test]
fn test_decode_6b4b_correct_output() {
let decoded = decode_6b4b(&0b10101, &0b1101);
assert_eq!(decoded, 0b110000);
}
#[test]
fn test_encode_buffer_correct_length_and_content() {
let input = [0xAB, 0xCD];
let output = encode_buffer(&input);
assert_eq!(output.len(), 4);
assert_eq!(output[0], 0x26);
assert_eq!(output[1], 0x29);
assert_eq!(output[2], 0x2a);
assert_eq!(output[3], 0x2c);
}
#[test]
fn test_decode_buffer_successful() {
let input = [0x26, 0x29];
let output = decode_buffer(&input);
assert_eq!(output.len(), 1);
assert_eq!(output[0], 0xAB);
}
#[test]
fn test_decode_buffer_odd_length_fails() {
#[cfg(not(feature = "std"))]
use heapless::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
let input = [0x2a];
let result = decode_buffer(&input);
#[cfg(feature = "std")]
let expected: Vec<u8> = Vec::new();
#[cfg(not(feature = "std"))]
let expected: Vec<u8, ASK_MAX_PAYLOAD_LEN_USIZE> = Vec::new();
assert_eq!(result, expected);
}
}