1use encoding_rs::mem::{decode_latin1, encode_latin1_lossy};
2use log::warn;
3use nom::ToUsize;
4use nom::number::complete::{le_f32, le_f64, le_i16, le_i32, le_i64, le_u16, le_u32, le_u64};
5use utf16string::WStr;
6
7use super::model::{StringEncoding, StringWithEncoding};
8
9pub trait BiffRead {
10    fn biff_read(reader: &mut BiffReader<'_>) -> Self;
11}
12
13pub trait BiffWrite {
14    fn biff_write(&self, writer: &mut BiffWriter);
15}
16
17pub struct BiffReader<'a> {
23    data: &'a [u8],
24    pos: usize,
25    bytes_in_record_remaining: usize,
26    record_start: usize,
27    tag: String,
28    warn_remaining: bool,
29}
30pub const RECORD_TAG_LEN: u32 = 4;
35
36pub const WARN: bool = true;
37
38impl<'a> BiffReader<'a> {
39    pub fn new(data: &'a [u8]) -> Self {
40        let reader: BiffReader<'a> = BiffReader {
41            data,
42            pos: 0,
43            bytes_in_record_remaining: 0,
44            record_start: 0,
45            tag: "".to_string(),
46            warn_remaining: true,
47        };
48        reader
49    }
50
51    pub fn with_remaining(data: &'a [u8], bytes_in_record_remaining: usize) -> Self {
52        let reader: BiffReader<'a> = BiffReader {
53            data,
54            pos: 0,
55            bytes_in_record_remaining,
56            record_start: 0,
57            tag: "".to_string(),
58            warn_remaining: true,
59        };
60        reader
61    }
62
63    pub fn disable_warn_remaining(&mut self) {
67        self.warn_remaining = false;
68    }
69
70    pub fn pos(&self) -> usize {
71        self.pos
72    }
73
74    pub fn tag(&self) -> String {
75        self.tag.to_string()
76    }
77
78    pub fn is_eof(&self) -> bool {
79        self.pos >= self.data.len() || self.tag == "ENDB"
80    }
81
82    pub fn get(&mut self, count: usize) -> &[u8] {
83        self.bytes_in_record_remaining -= count;
84        self.get_no_remaining_update(count)
85    }
86
87    pub fn get_no_remaining_update(&mut self, count: usize) -> &[u8] {
88        let p = self.pos;
89        self.pos += count;
90        &self.data[p..p + count]
91    }
92
93    pub fn remaining_in_record(&mut self) -> usize {
94        self.bytes_in_record_remaining
95    }
96
97    pub fn get_bool(&mut self) -> bool {
98        let all = &self.data[self.pos..self.pos + 4];
99        if all != [0, 0, 0, 0] && all != [1, 0, 0, 0] {
101            panic!("Unexpected bytes for bool: {all:?}");
102        }
103        let b = self.data[self.pos] != 0;
104        self.pos += 4;
105        self.bytes_in_record_remaining -= 4;
106        b
107    }
108
109    pub fn get_u8(&mut self) -> u8 {
110        let i = self.get_u8_no_remaining_update();
111        self.bytes_in_record_remaining -= 1;
112        i
113    }
114
115    pub fn get_u8_no_remaining_update(&mut self) -> u8 {
116        let i = self.data[self.pos];
117        self.pos += 1;
118        i
119    }
120
121    pub fn get_u16(&mut self) -> u16 {
122        let res = self.get_u16_no_remaining_update();
123        self.bytes_in_record_remaining -= 2;
124        res
125    }
126
127    pub fn get_u16_no_remaining_update(&mut self) -> u16 {
128        let i: Result<(&[u8], u16), nom::Err<()>> = le_u16(&self.data[self.pos..]);
129        self.pos += 2;
130        i.unwrap().1
131    }
132
133    pub fn get_u32(&mut self) -> u32 {
134        let res = self.get_u32_no_remaining_update();
135        self.bytes_in_record_remaining -= 4;
136        res
137    }
138
139    pub fn get_u32_no_remaining_update(&mut self) -> u32 {
140        let i: Result<(&[u8], u32), nom::Err<()>> = le_u32(&self.data[self.pos..]);
141        self.pos += 4;
142        i.unwrap().1
143    }
144
145    pub fn get_32(&mut self) -> i32 {
146        let res = self.get_32_no_remaining_update();
147        self.bytes_in_record_remaining -= 4;
148        res
149    }
150    pub fn get_32_no_remaining_update(&mut self) -> i32 {
151        let i: Result<(&[u8], i32), nom::Err<()>> = le_i32(&self.data[self.pos..]);
152        self.pos += 4;
153        i.unwrap().1
154    }
155
156    pub fn get_f32(&mut self) -> f32 {
157        let data = &self.data[self.pos..self.pos + 4];
158        let i: Result<(&[u8], f32), nom::Err<()>> = le_f32(data);
159        self.pos += 4;
160        self.bytes_in_record_remaining -= 4;
161
162        let res = i.unwrap().1;
163        if res.is_nan() {
164            warn!("NaN value found in f32 for tag {}: {:?}", self.tag, data);
165        }
166        res
167    }
168
169    pub fn get_str(&mut self, count: usize) -> String {
170        let mut pos_0 = count;
171        for p in 0..count {
173            if self.data[self.pos + p] == 0 {
174                pos_0 = p;
175                break;
176            }
177        }
178        let data = &self.data[self.pos..self.pos + pos_0];
179        let s = decode_latin1(data);
180        self.pos += count;
181        self.sub_remaining(count);
182        s.to_string()
183    }
184
185    pub fn get_str_with_encoding_no_remaining_update(
186        &mut self,
187        count: usize,
188    ) -> StringWithEncoding {
189        let mut pos_0 = count;
202        for p in 0..count {
204            if self.data[self.pos + p] == 0 {
205                pos_0 = p;
206                break;
207            }
208        }
209        let data = &self.data[self.pos..self.pos + pos_0];
210
211        self.pos += count;
212        let s: StringWithEncoding = data.into();
213        s
214    }
215
216    pub fn get_str_no_remaining_update(&mut self, count: usize) -> String {
217        let mut pos_0 = count;
218        for p in 0..count {
220            if self.data[self.pos + p] == 0 {
221                pos_0 = p;
222                break;
223            }
224        }
225        let data = &self.data[self.pos..self.pos + pos_0];
226
227        let s = decode_latin1(data);
228        self.pos += count;
229        s.to_string()
230    }
231
232    pub fn get_string(&mut self) -> String {
233        let size = self.get_u32().to_usize();
234        self.get_str(size)
235    }
236
237    pub fn get_string_no_remaining_update(&mut self) -> String {
238        let size = self.get_u32_no_remaining_update().to_usize();
239        self.get_str_no_remaining_update(size)
240    }
241
242    pub fn get_wide_string(&mut self) -> String {
243        let count = self.get_u32().to_usize();
244        let data = &self.data[self.pos..self.pos + count];
245        let i = WStr::from_utf16le(data).unwrap().to_utf8();
248        self.pos += count;
249        self.bytes_in_record_remaining -= count;
250        i
251    }
252
253    #[deprecated]
254    pub fn get_color(&mut self, has_alpha: bool) -> (f32, f32, f32, f32) {
255        if has_alpha {
256            (
257                self.get_u8() as f32 / 255.0,
258                self.get_u8() as f32 / 255.0,
259                self.get_u8() as f32 / 255.0,
260                self.get_u8() as f32 / 255.0,
261            )
262        } else {
263            (
264                self.get_u8() as f32 / 255.0,
265                self.get_u8() as f32 / 255.0,
266                self.get_u8() as f32 / 255.0,
267                1.0,
268            )
269        }
270    }
271
272    pub fn get_double(&mut self) -> f64 {
273        let i: Result<(&[u8], f64), nom::Err<()>> = le_f64(&self.data[self.pos..]);
274        self.pos += 8;
275        self.bytes_in_record_remaining -= 8;
276        i.unwrap().1
277    }
278
279    pub fn get_i16(&mut self) -> i16 {
280        let i: Result<(&[u8], i16), nom::Err<()>> = le_i16(&self.data[self.pos..]);
281        self.pos += 2;
282        self.bytes_in_record_remaining -= 2;
283        i.unwrap().1
284    }
285
286    pub fn get_i32(&mut self) -> i32 {
287        let i: Result<(&[u8], i32), nom::Err<()>> = le_i32(&self.data[self.pos..]);
288        self.pos += 4;
289        self.bytes_in_record_remaining -= 4;
290        i.unwrap().1
291    }
292
293    pub fn get_i64(&mut self) -> i64 {
294        let i: Result<(&[u8], i64), nom::Err<()>> = le_i64(&self.data[self.pos..]);
295        self.pos += 8;
296        self.bytes_in_record_remaining -= 8;
297        i.unwrap().1
298    }
299
300    pub fn get_u64(&mut self) -> u64 {
301        let i: Result<(&[u8], u64), nom::Err<()>> = le_u64(&self.data[self.pos..]);
302        self.pos += 8;
303        self.bytes_in_record_remaining -= 8;
304        i.unwrap().1
305    }
306
307    pub fn get_u32_array(&mut self, count: usize) -> Vec<u32> {
308        let mut v = Vec::with_capacity(count);
309        for _ in 0..count {
310            v.push(self.get_u32());
311        }
312        v
313    }
314
315    pub fn get_u16_array(&mut self, count: usize) -> Vec<u16> {
316        let mut v = Vec::with_capacity(count);
317        for _ in 0..count {
318            v.push(self.get_u16());
319        }
320        v
321    }
322
323    pub fn get_i16_array(&mut self, count: usize) -> Vec<i16> {
324        let mut v = Vec::with_capacity(count);
325        for _ in 0..count {
326            v.push(self.get_i16());
327        }
328        v
329    }
330
331    pub fn get_i32_array(&mut self, count: usize) -> Vec<i32> {
332        let mut v = Vec::with_capacity(count);
333        for _ in 0..count {
334            v.push(self.get_i32());
335        }
336        v
337    }
338
339    pub fn get_i64_array(&mut self, count: usize) -> Vec<i64> {
340        let mut v = Vec::with_capacity(count);
341        for _ in 0..count {
342            v.push(self.get_i64());
343        }
344        v
345    }
346
347    pub fn get_u64_array(&mut self, count: usize) -> Vec<u64> {
348        let mut v = Vec::with_capacity(count);
349        for _ in 0..count {
350            v.push(self.get_u64());
351        }
352        v
353    }
354
355    pub fn get_f32_array(&mut self, count: usize) -> Vec<f32> {
356        let mut v = Vec::with_capacity(count);
357        for _ in 0..count {
358            v.push(self.get_f32());
359        }
360        v
361    }
362
363    pub fn get_f64_array(&mut self, count: usize) -> Vec<f64> {
364        let mut v = Vec::with_capacity(count);
365        for _ in 0..count {
366            v.push(self.get_double());
367        }
368        v
369    }
370
371    pub fn get_string_array(&mut self, count: usize) -> Vec<String> {
372        let mut v = Vec::with_capacity(count);
373        for _ in 0..count {
374            v.push(self.get_string().to_string());
375        }
376        v
377    }
378
379    pub fn get_record_data(&mut self, with_tag: bool) -> Vec<u8> {
380        let d = if with_tag {
381            &self.data[self.pos - 4..self.pos + self.bytes_in_record_remaining]
382        } else {
383            if self.pos + self.bytes_in_record_remaining >= self.data.len() {
384                panic!("range is too big for {}", self.tag);
385            }
386            &self.data[self.pos..self.pos + self.bytes_in_record_remaining]
387        };
388        self.pos += self.bytes_in_record_remaining;
389        self.bytes_in_record_remaining = 0;
390        d.to_vec()
391    }
392
393    pub fn get_data_no_remaining_update(&mut self) -> Vec<u8> {
394        let len = self.get_u32_no_remaining_update() as usize;
395        let data = &self.data[self.pos..self.pos + len];
396
397        self.pos += len;
398        self.bytes_in_record_remaining = 0;
399        data.to_vec()
400    }
401
402    pub fn get_data(&mut self, count: usize) -> &[u8] {
403        let d = &self.data[self.pos..self.pos + count];
404        self.pos += count;
405        self.bytes_in_record_remaining = 0;
406        d
407    }
408
409    pub(crate) fn get_remaining(&self) -> &[u8] {
410        &self.data[self.pos..]
411    }
412
413    pub fn skip(&mut self, count: usize) {
414        self.pos += count;
415        self.bytes_in_record_remaining -= count;
416    }
417
418    pub fn skip_end_tag(&mut self, count: usize) {
419        self.pos += count;
420        self.bytes_in_record_remaining = 0;
421    }
422
423    pub fn skip_tag(&mut self) -> usize {
424        let remaining = self.bytes_in_record_remaining;
425        self.pos += remaining;
426        self.bytes_in_record_remaining = 0;
427        remaining
428    }
429
430    pub fn next(&mut self, warn: bool) -> Option<String> {
431        if self.bytes_in_record_remaining > 0 {
432            if warn {
433                warn!(
434                    "{} : {} unread octets",
435                    self.tag, self.bytes_in_record_remaining
436                );
437            }
438            self.skip(self.bytes_in_record_remaining);
439        }
440        self.record_start = self.pos;
441        if self.pos >= self.data.len() {
442            panic!(
443                "Unexpected end of biff stream at {}/{} while reading next tag. Missing ENDB?",
444                self.pos(),
445                self.data.len()
446            );
447        }
448        self.bytes_in_record_remaining = self.get_u32_no_remaining_update().to_usize();
449        let tag = self.get_str(RECORD_TAG_LEN.try_into().unwrap());
450        if tag.is_empty() {
451            panic!("Empty tag at {}/{}", self.pos(), self.data.len());
452        }
453        self.tag = tag;
454        if self.warn_remaining && self.tag == "ENDB" && self.pos < self.data.len() {
455            panic!("{} Remaining bytes after ENDB", self.data.len() - self.pos);
456        }
457        if self.is_eof() {
458            None
459        } else {
460            Some(self.tag.clone())
461        }
462    }
463
464    pub fn child_reader(&mut self) -> BiffReader<'_> {
465        BiffReader {
466            data: &self.data[self.pos..],
467            pos: 0,
468            bytes_in_record_remaining: 0,
469            record_start: 0,
470            tag: "".to_string(),
471            warn_remaining: false,
472        }
473    }
474
475    fn sub_remaining(&mut self, count: usize) {
476        if self.bytes_in_record_remaining < count {
477            panic!(
478                "WARN: {} bytes remaining in record {}, but {} bytes requested",
479                self.bytes_in_record_remaining, self.tag, count
480            );
481        } else {
482            self.bytes_in_record_remaining -= count;
483        }
484    }
485
486    pub fn data_until(&mut self, tag: &[u8]) -> Vec<u8> {
487        let mut pos = self.pos;
489        let mut found = false;
490        while pos < self.data.len() {
491            if &self.data[pos..pos + tag.len()] == tag {
492                found = true;
493                break;
494            }
495            pos += 1;
496        }
497        if !found {
498            panic!("Tag {tag:?} not found");
499        }
500        pos -= 4;
502        let data = &self.data[self.pos..pos];
503        self.pos = pos;
504        self.bytes_in_record_remaining = 0;
505        data.to_vec()
506    }
507}
508
509pub struct BiffWriter {
510    data: Vec<u8>,
511    tag_start: usize,
512    tag: String,
513    record_size: usize,
514}
515
516impl Default for BiffWriter {
517    fn default() -> Self {
518        BiffWriter {
519            data: Vec::new(),
520            tag_start: 0,
521            tag: "".to_string(),
522            record_size: 0,
523        }
524    }
525}
526
527impl BiffWriter {
528    pub fn new() -> BiffWriter {
529        BiffWriter::default()
530    }
531
532    pub fn get_data(&self) -> &[u8] {
533        &self.data
534    }
535
536    pub fn end_tag(&mut self) {
537        if !self.tag.is_empty() {
538            let length: &u32 = &self.record_size.try_into().unwrap();
540            let length_bytes = length.to_le_bytes();
541            self.data[self.tag_start..self.tag_start + 4].copy_from_slice(&length_bytes);
542            self.tag = "".to_string();
543        }
544    }
545
546    pub fn end_tag_no_size(&mut self) {
547        if !self.tag.is_empty() {
548            let length: u32 = 4;
549            let length_bytes = length.to_le_bytes();
550            self.data[self.tag_start..self.tag_start + 4].copy_from_slice(&length_bytes);
551            self.tag = "".to_string();
552        }
553    }
554
555    pub fn new_tag(&mut self, tag: &str) {
556        self.end_tag();
557        self.tag_start = self.data.len();
558        self.data.extend_from_slice(&[0, 0, 0, 0]); let tag_bytes = tag.as_bytes();
560        let mut padded_tag_bytes = [0; 4];
562        padded_tag_bytes[..tag_bytes.len()].copy_from_slice(tag_bytes);
563        self.data.extend_from_slice(&padded_tag_bytes);
564        self.tag = tag.to_string();
565        self.record_size = 4;
566    }
567
568    pub fn write_u8(&mut self, value: u8) {
569        self.record_size += 1;
570        self.data.push(value);
571    }
572
573    pub fn write_8(&mut self, value: i8) {
574        self.record_size += 1;
575        self.data.push(value as u8);
576    }
577
578    pub fn write_u16(&mut self, value: u16) {
579        self.record_size += 2;
580        self.data.extend_from_slice(&value.to_le_bytes());
581    }
582
583    pub fn write_16(&mut self, value: i16) {
584        self.record_size += 2;
585        self.data.extend_from_slice(&value.to_le_bytes());
586    }
587
588    pub fn write_u32(&mut self, value: u32) {
589        self.record_size += 4;
590        self.data.extend_from_slice(&value.to_le_bytes());
591    }
592
593    pub fn write_32(&mut self, value: i32) {
594        self.record_size += 4;
595        self.data.extend_from_slice(&value.to_le_bytes());
596    }
597
598    pub fn write_f32(&mut self, value: f32) {
599        self.record_size += 4;
600        self.data.extend_from_slice(&value.to_le_bytes());
601    }
602
603    pub fn write_short_string(&mut self, value: &str) {
604        let d = encode_latin1_lossy(value);
605        self.write_u8(d.len().try_into().unwrap());
606        self.write_data(&d);
607    }
608
609    pub fn write_string(&mut self, value: &str) {
610        let d = encode_latin1_lossy(value);
611        self.write_u32(d.len().try_into().unwrap());
612        self.write_data(&d);
613    }
614
615    pub fn write_string_with_encoding(&mut self, value: &StringWithEncoding) {
616        let d = match value.encoding {
617            StringEncoding::Latin1 => encode_latin1_lossy(&value.string).to_vec(),
618            StringEncoding::Utf8 => value.string.clone().into_bytes(),
619        };
620        self.write_u32(d.len().try_into().unwrap());
621        self.write_data(&d);
622    }
623
624    pub fn write_string_empty_zero(&mut self, value: &str) {
625        if value.is_empty() {
626            self.write_u32(1);
628            self.write_u8(0);
629        } else {
630            self.write_string(value);
631        }
632    }
633
634    pub fn write_wide_string(&mut self, value: &str) {
635        let d = value
637            .encode_utf16()
638            .flat_map(|c| c.to_le_bytes())
639            .collect::<Vec<u8>>();
640        self.write_u32(d.len().try_into().unwrap());
641        self.write_data(&d);
642    }
643
644    pub fn write_bool(&mut self, value: bool) {
645        if value {
646            self.write_u32(0x00000001);
647        } else {
648            self.write_u32(0x00000000);
649        }
650    }
651
652    pub fn write_length_prefixed_data(&mut self, value: &[u8]) {
653        self.write_u32(value.len().try_into().unwrap());
654        self.write_data(value);
655    }
656
657    pub fn write_data(&mut self, value: &[u8]) {
658        self.record_size += value.len();
659        self.data.extend_from_slice(value);
660    }
661
662    pub fn write_tagged_empty(&mut self, tag: &str) {
663        self.new_tag(tag);
664        self.end_tag();
665    }
666
667    pub fn write_tagged_bool(&mut self, tag: &str, value: bool) {
668        self.new_tag(tag);
669        self.write_bool(value);
670        self.end_tag();
671    }
672
673    pub fn write_tagged_f32(&mut self, tag: &str, value: f32) {
674        self.new_tag(tag);
675        self.write_f32(value);
676        self.end_tag();
677    }
678
679    pub fn write_tagged_u32(&mut self, tag: &str, value: u32) {
680        self.new_tag(tag);
681        self.write_u32(value);
682        self.end_tag();
683    }
684
685    pub fn write_tagged_i32(&mut self, tag: &str, value: i32) {
686        self.new_tag(tag);
687        self.write_32(value);
688        self.end_tag();
689    }
690
691    pub fn write_tagged_string(&mut self, tag: &str, value: &str) {
692        self.new_tag(tag);
693        self.write_string(value);
694        self.end_tag();
695    }
696
697    pub fn write_tagged_string_no_size(&mut self, tag: &str, value: &str) {
698        self.new_tag(tag);
699        self.write_string(value);
700        self.end_tag_no_size();
701    }
702
703    pub fn write_tagged_string_with_encoding_no_size(
704        &mut self,
705        tag: &str,
706        value: &StringWithEncoding,
707    ) {
708        self.new_tag(tag);
709        self.write_string_with_encoding(value);
710        self.end_tag_no_size();
711    }
712
713    pub fn write_tagged_wide_string(&mut self, tag: &str, value: &str) {
714        self.new_tag(tag);
715        self.write_wide_string(value);
716        self.end_tag();
717    }
718
719    pub fn write_tagged_vec2(&mut self, tag: &str, x: f32, y: f32) {
720        self.new_tag(tag);
721        self.write_f32(x);
722        self.write_f32(y);
723        self.end_tag();
724    }
725
726    pub fn write_tagged_padded_vector(&mut self, tag: &str, x: f32, y: f32, z: f32) {
727        self.new_tag(tag);
728        self.write_f32(x);
729        self.write_f32(y);
730        self.write_f32(z);
731        self.write_f32(0.0);
732        self.end_tag();
733    }
734
735    pub fn write_tagged_data(&mut self, tag: &str, value: &[u8]) {
736        self.new_tag(tag);
737        self.write_data(value);
738        self.end_tag();
739    }
740
741    pub fn write_tagged_data_without_size(&mut self, tag: &str, value: &[u8]) {
742        self.new_tag(tag);
743        self.write_data(value);
744        self.end_tag_no_size();
745    }
746
747    pub fn write_tagged<T: BiffWrite>(&mut self, tag: &str, value: &T) {
748        self.new_tag(tag);
749        BiffWrite::biff_write(value, self);
750        self.end_tag();
751    }
752
753    pub fn write_tagged_without_size<T: BiffWrite>(&mut self, tag: &str, value: &T) {
754        self.new_tag(tag);
755        BiffWrite::biff_write(value, self);
756        self.end_tag_no_size();
757    }
758
759    pub fn write_tagged_with<T>(&mut self, tag: &str, value: &T, f: fn(&T, &mut BiffWriter) -> ()) {
760        self.new_tag(tag);
761        f(value, self);
762        self.end_tag();
763    }
764
765    pub fn close(&mut self, write_endb: bool) {
766        if write_endb {
767            self.new_tag("ENDB");
768        }
769        self.end_tag();
770    }
771
772    pub(crate) fn write_marker_tag(&mut self, tag: &str) {
773        self.new_tag(tag);
774        self.end_tag();
775    }
776}
777
778#[cfg(test)]
779mod tests {
780
781    use super::*;
782    use pretty_assertions::assert_eq;
783
784    #[test]
785    fn read_write_empty() {
786        let mut writer = BiffWriter::new();
787        writer.close(true);
788        let mut reader = BiffReader::new(writer.get_data());
789        assert_eq!(reader.next(false), None);
790        assert_eq!(reader.is_eof(), true);
791    }
792
793    #[test]
794    fn read_write_empty_tag() {
795        let mut writer = BiffWriter::new();
796        writer.write_tagged_empty("TEST");
797        writer.close(true);
798        let mut reader = BiffReader::new(writer.get_data());
799        assert_eq!(reader.next(false), Some("TEST".to_string()));
800        reader.next(false);
801        assert_eq!(reader.is_eof(), true);
802    }
803}