2025-02-23 16:30:49 -05:00
|
|
|
use crate::common::{read_string_with_length, write_string_with_length};
|
2025-02-23 16:03:08 -05:00
|
|
|
use binrw::binrw;
|
2025-02-19 19:34:13 -05:00
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct StrProperty {
|
2025-02-23 16:30:49 -05:00
|
|
|
#[brw(pad_after = 5)]
|
|
|
|
// Only add + 1 for the null terminator if the string *isn't* empty.
|
|
|
|
#[bw(calc = value.len() as u32 + 4 + if value.is_empty() { 0 } else { 1})]
|
2025-02-23 15:52:21 -05:00
|
|
|
pub size_in_bytes: u32,
|
|
|
|
|
|
|
|
#[br(parse_with = read_string_with_length)]
|
2025-02-23 16:30:49 -05:00
|
|
|
#[bw(write_with = write_string_with_length)]
|
2025-02-23 15:52:21 -05:00
|
|
|
pub value: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2025-02-23 16:30:49 -05:00
|
|
|
use binrw::{BinRead, BinWrite};
|
2025-02-23 15:52:21 -05:00
|
|
|
use std::io::Cursor;
|
|
|
|
|
|
|
|
#[test]
|
2025-02-23 16:30:49 -05:00
|
|
|
fn read_empty_string() {
|
2025-02-23 15:52:21 -05:00
|
|
|
// From Slot.sav
|
|
|
|
let data = [
|
2025-02-23 16:30:49 -05:00
|
|
|
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
2025-02-23 15:52:21 -05:00
|
|
|
];
|
|
|
|
let mut cursor = Cursor::new(data);
|
|
|
|
let decoded = StrProperty::read_le(&mut cursor).unwrap();
|
|
|
|
assert_eq!(decoded.value, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2025-02-23 16:30:49 -05:00
|
|
|
fn write_empty_string() {
|
|
|
|
let expected_data: [u8; 13] = [
|
|
|
|
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
];
|
|
|
|
let property = StrProperty {
|
|
|
|
value: "".to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut buffer: Vec<u8> = Vec::new();
|
|
|
|
{
|
|
|
|
let mut cursor = Cursor::new(&mut buffer);
|
|
|
|
property.write_le(&mut cursor).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(expected_data, &buffer[..]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_regular_string() {
|
2025-02-23 15:52:21 -05:00
|
|
|
// From Slot.sav
|
|
|
|
let data = [
|
2025-02-23 16:03:08 -05:00
|
|
|
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x41,
|
|
|
|
0x52, 0x30, 0x58, 0x4a, 0x47, 0x46, 0x57, 0x41, 0x36, 0x48, 0x4e, 0x49, 0x51, 0x31,
|
|
|
|
0x41, 0x41, 0x55, 0x4a, 0x39, 0x55, 0x52, 0x38, 0x32, 0x38, 0x00,
|
2025-02-23 15:52:21 -05:00
|
|
|
];
|
|
|
|
let mut cursor = Cursor::new(data);
|
|
|
|
let decoded = StrProperty::read_le(&mut cursor).unwrap();
|
|
|
|
assert_eq!(decoded.value, "AR0XJGFWA6HNIQ1AAUJ9UR828");
|
|
|
|
}
|
2025-02-23 16:30:49 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn write_regular_string() {
|
|
|
|
let expected_data: [u8; 39] = [
|
|
|
|
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x41,
|
|
|
|
0x52, 0x30, 0x58, 0x4a, 0x47, 0x46, 0x57, 0x41, 0x36, 0x48, 0x4e, 0x49, 0x51, 0x31,
|
|
|
|
0x41, 0x41, 0x55, 0x4a, 0x39, 0x55, 0x52, 0x38, 0x32, 0x38, 0x00,
|
|
|
|
];
|
|
|
|
let property = StrProperty {
|
|
|
|
value: "AR0XJGFWA6HNIQ1AAUJ9UR828".to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut buffer: Vec<u8> = Vec::new();
|
|
|
|
{
|
|
|
|
let mut cursor = Cursor::new(&mut buffer);
|
|
|
|
property.write_le(&mut cursor).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(expected_data, &buffer[..]);
|
|
|
|
}
|
2025-02-19 19:34:13 -05:00
|
|
|
}
|