Add writing support for strings and StrProperty
This commit is contained in:
parent
8713a48351
commit
beaa0e784f
2 changed files with 68 additions and 9 deletions
|
@ -1,4 +1,4 @@
|
|||
use binrw::BinRead;
|
||||
use binrw::{BinRead, BinWrite};
|
||||
use binrw::BinResult;
|
||||
|
||||
pub(crate) fn read_bool_from<T: From<u8> + PartialEq>(x: T) -> bool {
|
||||
|
@ -25,6 +25,26 @@ pub(crate) fn read_string_with_length() -> BinResult<String> {
|
|||
}))
|
||||
}
|
||||
|
||||
#[binrw::writer(writer, endian)]
|
||||
pub(crate) fn write_string_with_length(string: &String) -> BinResult<()> {
|
||||
if string.is_empty() {
|
||||
let length = 0u32;
|
||||
length.write_le(writer)?;
|
||||
return Ok(());
|
||||
}
|
||||
// + 1 for the null terminator
|
||||
let length = string.len() as u32 + 1;
|
||||
length.write_le(writer)?;
|
||||
for char in string.chars() {
|
||||
let byte = char as u8;
|
||||
byte.write_le(writer)?;
|
||||
}
|
||||
let null_terminator = 0u8;
|
||||
null_terminator.write_le(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
use crate::common::read_string_with_length;
|
||||
use crate::common::{read_string_with_length, write_string_with_length};
|
||||
use binrw::binrw;
|
||||
|
||||
#[binrw]
|
||||
#[derive(Debug)]
|
||||
pub struct StrProperty {
|
||||
#[br(pad_after = 5)]
|
||||
#[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})]
|
||||
pub size_in_bytes: u32,
|
||||
|
||||
#[br(parse_with = read_string_with_length)]
|
||||
#[bw(ignore)]
|
||||
#[bw(write_with = write_string_with_length)]
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use binrw::BinRead;
|
||||
use binrw::{BinRead, BinWrite};
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
fn empty_string() {
|
||||
fn read_empty_string() {
|
||||
// From Slot.sav
|
||||
let data = [
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
|
||||
0x00, 0x00, 0x00, 0x4c, 0x6f, 0x61, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let mut cursor = Cursor::new(data);
|
||||
let decoded = StrProperty::read_le(&mut cursor).unwrap();
|
||||
|
@ -31,7 +32,25 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn regular_string() {
|
||||
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() {
|
||||
// From Slot.sav
|
||||
let data = [
|
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x41,
|
||||
|
@ -42,4 +61,24 @@ mod tests {
|
|||
let decoded = StrProperty::read_le(&mut cursor).unwrap();
|
||||
assert_eq!(decoded.value, "AR0XJGFWA6HNIQ1AAUJ9UR828");
|
||||
}
|
||||
|
||||
#[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[..]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue