2022-03-20 16:28:34 -07:00
|
|
|
///
|
|
|
|
/// Generic record-level read/write functionality.
|
|
|
|
///
|
2021-12-18 21:05:00 -08:00
|
|
|
use std::io::Write;
|
2022-03-20 16:28:34 -07:00
|
|
|
use std::convert::TryInto;
|
|
|
|
use byteorder::{ByteOrder, BigEndian};
|
2021-12-18 21:05:00 -08:00
|
|
|
|
|
|
|
|
2022-05-08 16:41:43 -07:00
|
|
|
use crate::basic::{pack_datetime, pack_bitarray, pack_ascii, pack_int2, pack_int4, pack_real8}; #[warn(unused_imports)]
|
|
|
|
use crate::basic::{parse_datetime, parse_bitarray, parse_ascii, parse_int2, parse_int4, parse_real8}; #[warn(unused_imports)]
|
2025-04-10 01:07:11 -07:00
|
|
|
use crate::basic::{OResult, IResult, fail, parse_u16, take_bytes}; //ErrType,
|
2022-05-08 16:41:43 -07:00
|
|
|
use crate::records;
|
2021-12-18 21:05:00 -08:00
|
|
|
|
|
|
|
|
|
|
|
//#[no_mangle]
|
|
|
|
//pub extern "C" fn write_record_header(
|
|
|
|
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct RecordHeader {
|
|
|
|
pub tag: u16,
|
|
|
|
pub data_size: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RecordHeader {
|
2025-04-11 11:18:56 -07:00
|
|
|
pub fn read(input: &[u8]) -> IResult<RecordHeader> {
|
2022-03-20 16:28:34 -07:00
|
|
|
let (input, size) = parse_u16(input)?;
|
|
|
|
let (input, tag) = parse_u16(input)?;
|
2025-04-11 11:18:56 -07:00
|
|
|
Ok((input, RecordHeader{tag, data_size:size - 4}))
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub fn pack_into(&self) -> [u8; 4] {
|
|
|
|
assert!(self.data_size < 0xffff - 4, "Record too big!");
|
|
|
|
let vals = [self.data_size, self.tag];
|
2021-12-18 21:05:00 -08:00
|
|
|
let mut buf = [0x77; 4];
|
|
|
|
BigEndian::write_u16_into(&vals, &mut buf);
|
|
|
|
buf
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub fn write<W: Write>(&self, ww: &mut W) -> OResult {
|
|
|
|
let bytes = self.pack_into();
|
|
|
|
ww.write(&bytes)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub trait RecordData {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a>;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData : ?Sized;
|
|
|
|
type ByteData : AsRef<[u8]>;
|
2021-12-18 21:05:00 -08:00
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>>;
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData);
|
2025-04-10 01:07:11 -07:00
|
|
|
//fn size(data: &Self::BareData<'_>) -> u16;
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData;
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
|
|
|
|
pub trait Record<RData: RecordData> {
|
|
|
|
fn tag() -> u16;
|
|
|
|
fn expected_size() -> Option<u16>;
|
|
|
|
|
|
|
|
fn check_size(actual_size: u16) -> Result<(), String> {
|
|
|
|
match Self::expected_size() {
|
2021-12-18 21:05:00 -08:00
|
|
|
Some(size) => if size == actual_size {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(format!("Expected record size {}, got {}", size, actual_size))
|
|
|
|
},
|
|
|
|
None => Ok(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn read_header(input: &[u8]) -> IResult<RecordHeader> {
|
|
|
|
RecordHeader::read(input)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_header<W: Write>(ww: &mut W, data_size: u16) -> OResult {
|
2025-04-11 11:18:56 -07:00
|
|
|
RecordHeader{tag: Self::tag(), data_size}.write(ww)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2025-04-10 01:07:11 -07:00
|
|
|
fn read_data(input: &[u8], size: u16) -> IResult<RData::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
RData::read(input, size)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_data(buf: &mut [u8], data: &RData::InData) {
|
|
|
|
RData::pack_into(buf, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Skip to the end of the next occurence of this record.
|
|
|
|
///
|
|
|
|
/// Return:
|
|
|
|
/// True if the record was encountered and skipped.
|
|
|
|
/// False if the end of the library was reached.
|
|
|
|
///
|
|
|
|
fn skip_past(input: &[u8]) -> IResult<bool> {
|
|
|
|
let original_input = input;
|
|
|
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
|
|
|
while header.tag != Self::tag() {
|
|
|
|
(input, _) = take_bytes(input, header.data_size)?;
|
2021-12-18 21:05:00 -08:00
|
|
|
if header.tag == records::RTAG_ENDLIB {
|
2022-03-20 16:28:34 -07:00
|
|
|
return Ok((original_input, false))
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
2022-03-20 16:28:34 -07:00
|
|
|
(input, header) = RecordHeader::read(input)?;
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
2022-03-20 16:28:34 -07:00
|
|
|
(input, _) = take_bytes(input, header.data_size)?;
|
2021-12-18 21:05:00 -08:00
|
|
|
Ok((input, true))
|
|
|
|
}
|
|
|
|
|
2025-04-10 01:07:11 -07:00
|
|
|
fn skip_and_read(input: &[u8]) -> IResult<RData::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
|
|
|
while header.tag != Self::tag() {
|
|
|
|
(input, _) = take_bytes(input, header.data_size)?;
|
|
|
|
(input, header) = RecordHeader::read(input)?;
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
2022-03-20 16:28:34 -07:00
|
|
|
let (input, data) = Self::read_data(input, header.data_size)?;
|
|
|
|
Ok((input, data))
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn expect_header(input: &[u8]) -> IResult<u16> {
|
|
|
|
let (input, header) = RecordHeader::read(input)?;
|
|
|
|
if header.tag != Self::tag() {
|
|
|
|
fail(input, format!("Unexpected record! Got tag 0x{:04x}, expected 0x{:04x}", header.tag, Self::tag()))
|
|
|
|
} else {
|
|
|
|
Ok((input, header.data_size))
|
|
|
|
}
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8]) -> IResult<RData::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
let (input, size) = Self::expect_header(input)?;
|
|
|
|
Self::check_size(size).unwrap();
|
|
|
|
let (input, data) = Self::read_data(input, size)?;
|
|
|
|
Ok((input, data))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write<W: Write>(ww: &mut W, data: &RData::InData) -> OResult {
|
|
|
|
let packed_data = RData::pack(data);
|
|
|
|
let data_bytes = packed_data.as_ref();
|
|
|
|
let len: u16 = data_bytes.len().try_into().expect("Record longer than max size (u16)!");
|
|
|
|
let mut size = 0;
|
|
|
|
size += Self::write_header(ww, len)?;
|
|
|
|
size += ww.write(data_bytes)?;
|
|
|
|
Ok(size)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct BitArray;
|
|
|
|
impl RecordData for BitArray {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = [bool; 16];
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = [bool; 16];
|
|
|
|
type ByteData = [u8; 2];
|
2021-12-18 21:05:00 -08:00
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 2);
|
2021-12-18 21:05:00 -08:00
|
|
|
parse_bitarray(input)
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
|
|
|
pack_bitarray(buf, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 2];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
|
|
|
|
pub struct Int2;
|
|
|
|
impl RecordData for Int2 {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = i16;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = i16;
|
|
|
|
type ByteData = [u8; 2];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 2);
|
2021-12-18 21:05:00 -08:00
|
|
|
parse_int2(input)
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
|
|
|
pack_int2(buf, *data)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 2];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct Int4;
|
|
|
|
impl RecordData for Int4 {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = i32;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = i32;
|
|
|
|
type ByteData = [u8; 4];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 4);
|
2021-12-18 21:05:00 -08:00
|
|
|
parse_int4(input)
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
|
|
|
pack_int4(buf, *data)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 4];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
|
|
|
|
pub struct Int2Array;
|
|
|
|
impl RecordData for Int2Array {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = Int2ArrayReader<'a>;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = [i16];
|
|
|
|
type ByteData = Vec<u8>;
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2021-12-18 21:05:00 -08:00
|
|
|
assert!(size % 2 == 0, "Record must contain an integer quantity of integers");
|
2025-04-10 01:07:11 -07:00
|
|
|
//let mut input = input;
|
|
|
|
let (input, bytes) = take_bytes(input, size)?;
|
2025-04-11 11:18:56 -07:00
|
|
|
Ok((input, Int2ArrayReader{bytes}))
|
2022-03-20 16:28:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
2025-04-11 11:18:56 -07:00
|
|
|
BigEndian::write_i16_into(data, buf)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = Vec::with_capacity(data.len() * 2);
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-04-10 01:07:11 -07:00
|
|
|
pub struct Int2ArrayReader<'a> {
|
|
|
|
bytes: &'a [u8],
|
|
|
|
}
|
|
|
|
impl Iterator for Int2ArrayReader<'_> {
|
|
|
|
type Item = i16;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.bytes.len() < 2 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let (remaining, val) = parse_int2(self.bytes).unwrap();
|
|
|
|
self.bytes = remaining;
|
|
|
|
Some(val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct Int4Array;
|
|
|
|
impl RecordData for Int4Array {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = Int4ArrayReader<'a>;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = [i32];
|
|
|
|
type ByteData = Vec<u8>;
|
2021-12-18 21:05:00 -08:00
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2021-12-18 21:05:00 -08:00
|
|
|
assert!(size % 4 == 0, "Record must contain an integer quantity of integers");
|
2025-04-10 01:07:11 -07:00
|
|
|
//let mut input = input;
|
|
|
|
let (input, bytes) = take_bytes(input, size)?;
|
2025-04-11 11:18:56 -07:00
|
|
|
Ok((input, Int4ArrayReader{bytes}))
|
2022-03-20 16:28:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
2025-04-11 11:18:56 -07:00
|
|
|
BigEndian::write_i32_into(data, buf)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = Vec::with_capacity(data.len() * 4);
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-04-10 01:07:11 -07:00
|
|
|
pub struct Int4ArrayReader<'a> {
|
|
|
|
bytes: &'a [u8],
|
|
|
|
}
|
|
|
|
impl Iterator for Int4ArrayReader<'_> {
|
|
|
|
type Item = i32;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.bytes.len() < 4 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let (remaining, val) = parse_int4(self.bytes).unwrap();
|
|
|
|
self.bytes = remaining;
|
|
|
|
Some(val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct Real8;
|
|
|
|
impl RecordData for Real8 {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = f64;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = f64;
|
|
|
|
type ByteData = [u8; 8];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 8);
|
2021-12-18 21:05:00 -08:00
|
|
|
parse_real8(input)
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
2025-04-11 11:18:56 -07:00
|
|
|
pack_real8(buf, *data).unwrap_or_else(|_| panic!("Float {0} too big for Real8", data))
|
2022-03-20 16:28:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 8];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct Real8Pair;
|
|
|
|
impl RecordData for Real8Pair {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = (f64, f64);
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = (f64, f64);
|
|
|
|
type ByteData = [u8; 2 * 8];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 2 * 8);
|
|
|
|
let (input, data0) = parse_real8(input)?;
|
|
|
|
let (input, data1) = parse_real8(input)?;
|
|
|
|
Ok((input, (data0, data1)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
2025-04-11 11:18:56 -07:00
|
|
|
pack_real8(&mut buf[8 * 0..], data.0).unwrap_or_else(|_| panic!("Float.0 {0} too big for Real8", data.0));
|
|
|
|
pack_real8(&mut buf[8 * 1..], data.1).unwrap_or_else(|_| panic!("Float.1 {0} too big for Real8", data.1));
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 2 * 8];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
2022-03-20 16:28:34 -07:00
|
|
|
|
|
|
|
//fn write<W: Write>(ww: &mut W, data: &Self::BareData) -> OResult {
|
|
|
|
// let mut buf = [u8; 2 * 6 * 2];
|
|
|
|
// Self::pack_into(&mut buf, data)
|
|
|
|
//}
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
pub struct ASCII;
|
|
|
|
impl RecordData for ASCII {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = Vec<u8>;
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = [u8];
|
|
|
|
type ByteData = Vec<u8>;
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
parse_ascii(input, size)
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
|
|
|
pack_ascii(buf, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = Vec::with_capacity(data.len() * 4);
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-20 16:28:34 -07:00
|
|
|
|
|
|
|
pub struct DateTimePair;
|
|
|
|
impl RecordData for DateTimePair {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = [[i16; 6]; 2];
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = [[i16; 6]; 2];
|
|
|
|
type ByteData = [u8; 2 * 6 * 2];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 2 * 6 * 2);
|
|
|
|
let (input, data0) = parse_datetime(input)?;
|
|
|
|
let (input, data1) = parse_datetime(input)?;
|
|
|
|
Ok((input, [data0, data1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack_into(buf: &mut [u8], data: &Self::InData) {
|
|
|
|
pack_datetime(&mut buf[6 * 2 * 0..], &data[0]);
|
|
|
|
pack_datetime(&mut buf[6 * 2 * 1..], &data[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(data: &Self::InData) -> Self::ByteData {
|
|
|
|
let mut buf = [0; 2 * 6 * 2];
|
|
|
|
Self::pack_into(&mut buf, data);
|
|
|
|
buf
|
|
|
|
}
|
|
|
|
|
|
|
|
//fn write<W: Write>(ww: &mut W, data: &Self::BareData) -> OResult {
|
|
|
|
// let mut buf = [u8; 2 * 6 * 2];
|
|
|
|
// Self::pack_into(&mut buf, data)
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Empty;
|
|
|
|
impl RecordData for Empty {
|
2025-04-10 01:07:11 -07:00
|
|
|
type BareData<'a> = ();
|
2022-03-20 16:28:34 -07:00
|
|
|
type InData = ();
|
|
|
|
type ByteData = [u8; 0];
|
|
|
|
|
2025-04-11 11:18:56 -07:00
|
|
|
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
2022-03-20 16:28:34 -07:00
|
|
|
assert!(size == 0);
|
|
|
|
Ok((input, ()))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack_into(_buf: &mut [u8], _data: &Self::InData) {
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pack(_data: &Self::InData) -> Self::ByteData {
|
|
|
|
[]
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|
2022-03-20 16:28:34 -07:00
|
|
|
//fn write<W: Write>(ww: &mut W, data: &Self::BareData) {
|
|
|
|
//}
|
2021-12-18 21:05:00 -08:00
|
|
|
}
|