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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::{
fmt, io::{Read, Write},
};
use crate::{
encoding::{write_i32, BinaryEncoder, EncodingResult, DecodingLimits, process_encode_io_result, process_decode_io_result},
status_codes::StatusCode,
};
#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize)]
pub struct UAString {
pub value: Option<String>,
}
impl fmt::Display for UAString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(ref value) = self.value {
write!(f, "{}", value)
} else {
write!(f, "[null]")
}
}
}
impl BinaryEncoder<UAString> for UAString {
fn byte_len(&self) -> usize {
4 + if self.value.is_none() { 0 } else { self.value.as_ref().unwrap().len() }
}
fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
if self.value.is_none() {
write_i32(stream, -1)
} else {
let value = self.value.clone().unwrap();
let mut size: usize = 0;
size += write_i32(stream, value.len() as i32)?;
let buf = value.as_bytes();
size += process_encode_io_result(stream.write(&buf))?;
assert_eq!(size, self.byte_len());
Ok(size)
}
}
fn decode<S: Read>(stream: &mut S, decoding_limits: &DecodingLimits) -> EncodingResult<Self> {
let len = i32::decode(stream, decoding_limits)?;
if len == -1 {
Ok(UAString::null())
} else if len < -1 {
error!("String buf length is a negative number {}", len);
Err(StatusCode::BadDecodingError)
} else if len as usize > decoding_limits.max_string_length {
error!("String buf length {} exceeds decoding limit {}", len, decoding_limits.max_string_length);
Err(StatusCode::BadDecodingError)
} else {
let mut buf = vec![0u8; len as usize];
process_decode_io_result(stream.read_exact(&mut buf))?;
Ok(UAString {
value: Some(String::from_utf8(buf).unwrap())
})
}
}
}
impl From<UAString> for String {
fn from(value: UAString) -> Self {
value.as_ref().to_string()
}
}
impl AsRef<str> for UAString {
fn as_ref(&self) -> &str {
if self.is_null() { "" } else { self.value.as_ref().unwrap() }
}
}
impl<'a> From<&'a str> for UAString {
fn from(value: &'a str) -> Self {
Self::from(value.to_string())
}
}
impl From<String> for UAString {
fn from(value: String) -> Self {
UAString { value: Some(value) }
}
}
impl Default for UAString {
fn default() -> Self {
UAString::null()
}
}
impl UAString {
pub fn is_empty(&self) -> bool {
if self.value.is_none() { true } else { self.value.as_ref().unwrap().is_empty() }
}
pub fn len(&self) -> isize {
if self.value.is_none() { -1 } else { self.value.as_ref().unwrap().len() as isize }
}
pub fn null() -> UAString {
UAString { value: None }
}
pub fn is_null(&self) -> bool {
self.value.is_none()
}
}
pub type XmlElement = UAString;