1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use super::{Error, Result as Res};
use crate::StructureBlock;
use core::{fmt, slice, str};
#[derive(Clone)]
pub struct Str<'a>(pub(super) &'a [u8]);
impl<'a> Str<'a> {
#[inline]
pub(super) fn new(value: &'a [StructureBlock], len: usize) -> Res<Self> {
let buf = unsafe { slice::from_raw_parts(value.as_ptr().cast(), len) };
if let Some(b'\0') = buf.last().copied() {
Ok(Self(&buf[..buf.len() - 1]))
} else {
Err(Error)
}
}
}
impl Str<'_> {
#[inline]
pub fn as_bytes(&self) -> &[u8] {
self.0
}
#[inline]
pub fn as_str(&self) -> Result<&str, str::Utf8Error> {
str::from_utf8(self.0)
}
#[inline]
pub unsafe fn as_str_unchecked(&self) -> &str {
str::from_utf8_unchecked(self.0)
}
}
impl fmt::Display for Str<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
'"'.fmt(f)?;
unsafe { self.as_str_unchecked() }.fmt(f)?;
'"'.fmt(f)
}
}
#[derive(Clone)]
pub struct StrList<'a>(&'a [u8]);
impl<'a> StrList<'a> {
#[inline]
pub(super) fn new(value: &'a [StructureBlock], len: usize) -> Res<Self> {
let buf = unsafe { slice::from_raw_parts(value.as_ptr().cast(), len) };
if let Some(b'\0') = buf.last().copied() {
Ok(Self(buf))
} else {
Err(Error)
}
}
}
impl<'a> Iterator for StrList<'a> {
type Item = Str<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.0.is_empty() {
return None;
}
let (head, tail) = self
.0
.split_at(slice::memchr::memchr(b'\0', self.0).unwrap());
self.0 = &tail[1..];
Some(Str(head))
}
}
impl fmt::Display for StrList<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut iter = self.clone();
'['.fmt(f)?;
if let Some(first) = iter.next() {
first.fmt(f)?;
for s in iter {
", ".fmt(f)?;
s.fmt(f)?;
}
}
']'.fmt(f)
}
}