///|
pub(all) suberror FrameError {
InvalidMacLength(Int)
InvalidMacText(String)
InvalidIpv4Length(Int)
InvalidIpv4Text(String)
InvalidHexText(String)
} derive(Eq, Debug, ToJson)
///|
pub(all) struct MacAddress {
bytes : Bytes
} derive(Eq)
///|
pub(all) struct IPv4Address {
bytes : Bytes
} derive(Eq)
///|
fn byte_to_hex(byte : Byte) -> String {
let digits = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
]
let value = byte.to_int()
digits[(value >> 4) & 0x0F] + digits[value & 0x0F]
}
///|
pub fn bytes_to_hex(data : Bytes, separator? : StringView = " ") -> String {
let mut output = ""
for index, byte in data {
if index > 0 {
output = output + separator.to_owned()
}
output = output + byte_to_hex(byte)
}
output
}
///|
pub fn bytes_from_hex(
text : StringView,
separator? : StringView = " ",
) -> Bytes raise FrameError {
let parts = text.split(separator).to_array().filter(part => part != "")
let bytes : Array[Byte] = []
for part in parts {
guard part.length() == 2 else {
raise FrameError::InvalidHexText(text.to_owned())
}
let value = @string.parse_uint(part, base=16) catch {
_ => raise FrameError::InvalidHexText(text.to_owned())
}
guard value <= 255U else {
raise FrameError::InvalidHexText(text.to_owned())
}
bytes.push(value.to_byte())
}
Bytes::from_array(bytes)
}
///|
pub fn MacAddress::new(bytes : Bytes) -> MacAddress raise FrameError {
guard bytes.length() == 6 else {
raise FrameError::InvalidMacLength(bytes.length())
}
MacAddress::{ bytes, }
}
///|
pub fn MacAddress::broadcast() -> MacAddress {
MacAddress::{
bytes: Bytes::from_array([
Int::to_byte(255),
Int::to_byte(255),
Int::to_byte(255),
Int::to_byte(255),
Int::to_byte(255),
Int::to_byte(255),
]),
}
}
///|
pub fn MacAddress::from_hex(text : StringView) -> MacAddress raise FrameError {
let parts = text.split(":").to_array()
guard parts.length() == 6 else {
raise FrameError::InvalidMacLength(parts.length())
}
let bytes : Array[Byte] = []
for part in parts {
guard part.length() == 2 else {
raise FrameError::InvalidMacText(text.to_owned())
}
let value = @string.parse_uint(part, base=16) catch {
_ => raise FrameError::InvalidMacText(text.to_owned())
}
guard value <= 255U else {
raise FrameError::InvalidMacText(text.to_owned())
}
bytes.push(value.to_byte())
}
MacAddress::new(Bytes::from_array(bytes))
}
///|
pub fn MacAddress::to_hex(
self : MacAddress,
separator? : StringView = ":",
) -> String {
bytes_to_hex(self.bytes, separator~)
}
///|
pub fn MacAddress::octets(self : MacAddress) -> Bytes {
self.bytes
}
///|
pub fn IPv4Address::new(bytes : Bytes) -> IPv4Address raise FrameError {
guard bytes.length() == 4 else {
raise FrameError::InvalidIpv4Length(bytes.length())
}
IPv4Address::{ bytes, }
}
///|
pub fn IPv4Address::from_text(
text : StringView,
) -> IPv4Address raise FrameError {
let parts = text.split(".").to_array()
guard parts.length() == 4 else {
raise FrameError::InvalidIpv4Length(parts.length())
}
let bytes : Array[Byte] = []
for part in parts {
let value = @string.parse_uint(part, base=10) catch {
_ => raise FrameError::InvalidIpv4Text(text.to_owned())
}
guard value <= 255U else {
raise FrameError::InvalidIpv4Text(text.to_owned())
}
bytes.push(value.to_byte())
}
IPv4Address::new(Bytes::from_array(bytes))
}
///|
pub fn IPv4Address::to_text(self : IPv4Address) -> String {
let mut output = ""
for index, byte in self.bytes {
if index > 0 {
output = output + "."
}
output = output + byte.to_int().to_string()
}
output
}
///|
pub fn IPv4Address::octets(self : IPv4Address) -> Bytes {
self.bytes
}
///|
pub fn uint32_to_hex(value : Int) -> String {
let digits = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
]
let bytes : Array[Byte] = []
bytes.push(((value >> 24) & 0xFF).to_byte())
bytes.push(((value >> 16) & 0xFF).to_byte())
bytes.push(((value >> 8) & 0xFF).to_byte())
bytes.push((value & 0xFF).to_byte())
let mut output = ""
for byte in bytes {
let v = byte.to_int()
output = output + digits[(v >> 4) & 0x0F] + digits[v & 0x0F]
}
output
}
///|
pub fn uint16_to_hex(value : Int) -> String {
let digits = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
]
let bytes : Array[Byte] = []
bytes.push(((value >> 8) & 0xFF).to_byte())
bytes.push((value & 0xFF).to_byte())
let mut output = ""
for byte in bytes {
let v = byte.to_int()
output = output + digits[(v >> 4) & 0x0F] + digits[v & 0x0F]
}
output
}