Skip to main content

chess/formats/chessbase/
table.rs

1use crate::formats::{ByteInput as Input, prelude::*};
2
3#[derive(Clone, Copy, Debug)]
4pub struct Header {
5    pub first_record: usize,
6    pub len: usize,
7    pub avl_root: u32,
8    pub first_deleted: Option<usize>,
9    pub record_len: usize,
10    pub len_existing: usize,
11}
12
13pub fn header(input: &mut Input<'_>) -> ModalResult<Header> {
14    let len = le_u32.parse_next(input)? as usize;
15    let avl_root = le_u32.parse_next(input)?;
16    let _one_to_zero = le_u32.verify(|value| *value == 1234567890).parse_next(input)?;
17    let record_len = le_u32.parse_next(input)? as usize;
18    // Not true for CBT which reuses the header
19    // println!("size: {size}");
20    // assert_eq!(67, size + 9);
21    let first_deleted = le_i32.map(|x| (x != -1).then_some(x as usize)).parse_next(input)?;
22    let len_existing = le_u32.parse_next(input)? as usize;
23    // assert!(len_existing >= len);
24    // padding? is 4 in an example
25    let more_offset = le_u32.verify(|offset| matches!(*offset, 0 | 4)).parse_next(input)?;
26    // println!("more offset: {more_offset}");
27    // compared to talkchess.com post, there's another four bytes
28    let _padding = take(more_offset)
29        .verify(|padding: &[u8]| padding.iter().all(|byte| *byte == 0))
30        .parse_next(input)?;
31
32    Ok(Header {
33        first_record: 28 + more_offset as usize,
34        len,
35        avl_root,
36        record_len,
37        first_deleted,
38        len_existing,
39    })
40}