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
use std::io::{Read, Write};
use std::fmt;
use encoding::{write_i32, BinaryEncoder, EncodingResult, process_encode_io_result, process_decode_io_result};
use basic_types::Int32;
use constants;
use status_codes::StatusCode::{BadDecodingError, BadEncodingLimitsExceeded};
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
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) -> EncodingResult<Self> {
let buf_len = Int32::decode(stream)?;
if buf_len == -1 {
Ok(UAString::null())
} else if buf_len < -1 {
error!("String buf length is a negative number {}", buf_len);
Err(BadDecodingError)
} else if buf_len > constants::MAX_STRING_LENGTH as i32 {
error!("String buf length {} is larger than max string length", buf_len);
Err(BadEncodingLimitsExceeded)
} else {
let mut string_buf: Vec<u8> = Vec::with_capacity(buf_len as usize);
string_buf.resize(buf_len as usize, 0u8);
process_decode_io_result(stream.read_exact(&mut string_buf))?;
Ok(UAString {
value: Some(String::from_utf8(string_buf).unwrap())
})
}
}
}
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 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;