xabc_lib/
string.rs

1use std::{fmt, sync::Arc};
2
3use scroll::{ctx, Uleb128};
4
5use crate::error;
6
7#[derive(Debug)]
8pub struct ABCString {
9    // str: Rc<String>,
10    str: Arc<String>,
11    /// ABCString 长度,包括 `\0`
12    length: usize,
13}
14
15impl ABCString {
16    pub fn str(&self) -> String {
17        self.str.clone().to_string()
18    }
19
20    pub fn length(&self) -> usize {
21        self.length
22    }
23}
24
25impl Clone for ABCString {
26    fn clone(&self) -> Self {
27        ABCString {
28            str: self.str.clone(),
29            length: self.length,
30        }
31    }
32}
33
34impl fmt::Display for ABCString {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "{}", self.str.clone())
37    }
38}
39
40impl<'a> ctx::TryFromCtx<'a, scroll::Endian> for ABCString {
41    type Error = error::Error;
42    fn try_from_ctx(source: &'a [u8], _: scroll::Endian) -> Result<(Self, usize), Self::Error> {
43        let off = &mut 0;
44        let utf16_length = Uleb128::read(source, off).unwrap();
45
46        // 字符串的长度
47        let count = (utf16_length >> 1) as usize;
48        let bytes = &source[*off..*off + count];
49
50        let str = std::str::from_utf8(bytes).unwrap_or("-utf8-error-");
51
52        let mut len = *off + count;
53
54        // 还有`\0`
55        len += 1;
56
57        Ok((
58            ABCString {
59                str: Arc::new(str.to_string()),
60                length: len,
61            },
62            source.len(),
63        ))
64    }
65}