Maraiah/src/durandal/bin.rs

168 lines
3.1 KiB
Rust
Raw Normal View History

2018-09-06 09:01:52 -07:00
//! Binary data conversion utilities.
2018-12-11 00:08:23 -08:00
use crate::durandal::err::*;
2019-02-09 11:01:35 -08:00
use std::{fmt,
num::NonZeroU16};
2018-09-06 09:01:52 -07:00
2018-12-11 00:08:23 -08:00
pub type Ident = [u8; 4];
2018-09-11 12:07:42 -07:00
pub trait BinUtil
{
// Checked
fn c_iden(&self, i: usize) -> ResultS<Ident>;
fn c_u32b(&self, i: usize) -> ResultS<u32>;
fn c_u16b(&self, i: usize) -> ResultS<u16>;
fn c_i32b(&self, i: usize) -> ResultS<i32>
2019-02-08 21:53:27 -08:00
{
match self.c_u32b(i) {
Ok(n) => Ok(n as i32),
Err(e) => Err(e),
}
}
2018-09-11 12:07:42 -07:00
fn c_i16b(&self, i: usize) -> ResultS<i16>
2019-02-08 21:53:27 -08:00
{
match self.c_u16b(i) {
Ok(n) => Ok(n as i16),
Err(e) => Err(e),
}
}
2018-09-11 12:07:42 -07:00
// Optional
2019-02-08 21:53:27 -08:00
fn o_iden(&self, i: usize) -> Option<Ident>
{
self.c_iden(i).ok()
}
fn o_u32b(&self, i: usize) -> Option<u32>
{
self.c_u32b(i).ok()
}
fn o_u16b(&self, i: usize) -> Option<u16>
{
self.c_u16b(i).ok()
}
fn o_i32b(&self, i: usize) -> Option<i32>
{
self.c_i32b(i).ok()
}
fn o_i16b(&self, i: usize) -> Option<i16>
{
self.c_i16b(i).ok()
}
2018-09-11 12:07:42 -07:00
// Unchecked
2019-02-08 21:53:27 -08:00
fn b_iden(&self, i: usize) -> Ident
{
self.c_iden(i).unwrap()
}
fn b_u32b(&self, i: usize) -> u32
{
self.c_u32b(i).unwrap()
}
fn b_u16b(&self, i: usize) -> u16
{
self.c_u16b(i).unwrap()
}
fn b_i32b(&self, i: usize) -> i32
{
self.c_i32b(i).unwrap()
}
fn b_i16b(&self, i: usize) -> i16
{
self.c_i16b(i).unwrap()
}
2018-09-11 12:07:42 -07:00
}
impl BinUtil for [u8]
{
fn c_iden(&self, i: usize) -> ResultS<Ident>
{
2019-02-05 23:01:47 -08:00
if i + 3 < self.len() {
Ok([self[i], self[i + 1], self[i + 2], self[i + 3]])
} else {
Err(err_msg("not enough data"))
}
2018-09-11 12:07:42 -07:00
}
fn c_u32b(&self, i: usize) -> ResultS<u32>
{
2019-02-05 23:01:47 -08:00
if i + 3 < self.len() {
2019-02-08 21:53:27 -08:00
Ok(u32::from_be_bytes([self[i],
self[i + 1],
self[i + 2],
self[i + 3]]))
2019-02-05 23:01:47 -08:00
} else {
Err(err_msg("not enough data"))
}
2018-09-11 12:07:42 -07:00
}
fn c_u16b(&self, i: usize) -> ResultS<u16>
{
2019-02-05 23:01:47 -08:00
if i + 1 < self.len() {
Ok(u16::from_be_bytes([self[i], self[i + 1]]))
} else {
Err(err_msg("not enough data"))
}
2018-09-11 12:07:42 -07:00
}
}
2018-09-06 09:01:52 -07:00
2019-02-08 21:53:27 -08:00
pub fn d_u32b(n: u32) -> [u8; 4]
{
n.to_be_bytes()
}
pub fn d_u16b(n: u16) -> [u8; 2]
{
n.to_be_bytes()
}
pub fn d_i32b(n: i32) -> [u8; 4]
{
d_u32b(n as u32)
}
pub fn d_i16b(n: i16) -> [u8; 2]
{
d_u16b(n as u16)
}
2018-09-06 09:01:52 -07:00
2019-02-09 11:01:35 -08:00
pub struct ObjID(Option<NonZeroU16>);
impl fmt::Debug for ObjID
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
match self.0 {
None => write!(f, "ObjID(None)"),
Some(n) => write!(f, "ObjID({})", n.get()),
}
}
}
impl ObjID
{
pub fn from_repr(n: u16) -> ObjID
{
if n == u16::max_value() {
ObjID(None)
} else {
ObjID(NonZeroU16::new(n + 1))
}
}
pub fn get_repr(&self) -> u16
{
match self.0 {
None => u16::max_value(),
Some(n) => n.get() - 1,
}
}
pub fn get(&self) -> Option<u16>
{
match self.0 {
None => None,
Some(n) => Some(n.get()),
}
}
}
2018-09-06 09:01:52 -07:00
// EOF