1use std::{fmt, sync::Arc};
2
3use scroll::{ctx, Uleb128};
4
5use crate::error;
6
7#[derive(Debug)]
8pub struct ABCString {
9 str: Arc<String>,
11 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 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 len += 1;
56
57 Ok((
58 ABCString {
59 str: Arc::new(str.to_string()),
60 length: len,
61 },
62 source.len(),
63 ))
64 }
65}