From e24f67843f4743b1b49ff7fa5870893e3dbb6b0e Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:15:41 +0300 Subject: [PATCH] FString ANSI decoding/encoding --- src/fot/fstring.rs | 9 +++++---- src/fot/world.rs | 10 ++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/fot/fstring.rs b/src/fot/fstring.rs index 0cf67b8..7995a64 100644 --- a/src/fot/fstring.rs +++ b/src/fot/fstring.rs @@ -25,10 +25,10 @@ impl Decoder for FString { fn decode(raw: &Raw, offset: usize, _: usize) -> Result { let mut rdr = Cursor::new(&raw.mem[offset..]); let flen = rdr.read_u32::()? as usize; - let len = flen ^ (1<<31); + let len = flen & !(1<<31); let start = offset + 4; if flen & (1<<31) == 0 { // ANSI - let str = str::from_utf8(&raw.mem[start..start+len])?; + let (str, _, _) = WINDOWS_1251.decode(&raw.mem[start..start+len]); Ok(FString { encoding: FStringEncoding::ANSI, enc_len: len, str: str.to_string() }) } else { // WCS2 let chars: Vec = raw.mem[start..start+len*2] @@ -42,8 +42,9 @@ impl Decoder for FString { let mut buf = vec![0u8; 4]; let mut wdr = Cursor::new(&mut buf[..]); if self.encoding == FStringEncoding::ANSI { - wdr.write_u32::(self.str.len() as u32 ^ (1<<31))?; - buf.append(&mut self.str.clone().into_bytes()); + let (chars, _, _) = WINDOWS_1251.encode(self.str.as_str()); + wdr.write_u32::(chars.len() as u32 & !(1<<31))?; + buf.extend(chars.iter()); } else { // WCS2 let (chars, _, _) = WINDOWS_1251.encode(self.str.as_str()); wdr.write_u32::(chars.len() as u32 | (1<<31))?; diff --git a/src/fot/world.rs b/src/fot/world.rs index 71e3848..5804e72 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -1,3 +1,5 @@ +use crate::fot::fstring::FStringEncoding; + use super::decoder::Decoder; use super::raw::Raw; use super::tag::Tag; @@ -22,12 +24,16 @@ impl World { const WORLD_HDR_LEN: usize = 0x13; pub fn test(&self) -> Result<()> { - let a = FString::decode(&self.data, 0xA2, 0)?; + let mut a = FString::decode(&self.data, 0xA2, 0)?; dbg!(&a); - let b = a.encode(); + a.encoding = FStringEncoding::ANSI; + let b = a.encode()?; dbg!(&b); + let c = FString::decode(&b, 0, 0)?; + dbg!(&c); + Ok(()) } }