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
use std::{self, io::{Read, Write}};
use crate::{
data_types::*,
date_time::DateTime,
diagnostic_info::DiagnosticInfo,
encoding::*,
extension_object::ExtensionObject,
request_header::RequestHeader,
status_codes::StatusCode,
string::UAString,
};
#[derive(Debug, Clone, PartialEq)]
pub struct ResponseHeader {
pub timestamp: UtcTime,
pub request_handle: IntegerId,
pub service_result: StatusCode,
pub service_diagnostics: DiagnosticInfo,
pub string_table: Option<Vec<UAString>>,
pub additional_header: ExtensionObject,
}
impl BinaryEncoder<ResponseHeader> for ResponseHeader {
fn byte_len(&self) -> usize {
let mut size = 0;
size += self.timestamp.byte_len();
size += self.request_handle.byte_len();
size += self.service_result.byte_len();
size += self.service_diagnostics.byte_len();
size += byte_len_array(&self.string_table);
size += self.additional_header.byte_len();
size
}
fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
let mut size = 0;
size += self.timestamp.encode(stream)?;
size += self.request_handle.encode(stream)?;
size += self.service_result.encode(stream)?;
size += self.service_diagnostics.encode(stream)?;
size += write_array(stream, &self.string_table)?;
size += self.additional_header.encode(stream)?;
assert_eq!(size, self.byte_len());
Ok(size)
}
fn decode<S: Read>(stream: &mut S, decoding_limits: &DecodingLimits) -> EncodingResult<Self> {
let timestamp = UtcTime::decode(stream, decoding_limits)?;
let request_handle = IntegerId::decode(stream, decoding_limits)?;
let service_result = StatusCode::decode(stream, decoding_limits)?;
let service_diagnostics = DiagnosticInfo::decode(stream, decoding_limits)?;
let string_table: Option<Vec<UAString>> = read_array(stream, decoding_limits)?;
let additional_header = ExtensionObject::decode(stream, decoding_limits)?;
Ok(ResponseHeader {
timestamp,
request_handle,
service_result,
service_diagnostics,
string_table,
additional_header,
})
}
}
impl ResponseHeader {
pub fn new_good(request_header: &RequestHeader) -> ResponseHeader {
ResponseHeader::new_service_result(request_header, StatusCode::Good)
}
pub fn new_service_result(request_header: &RequestHeader, service_result: StatusCode) -> ResponseHeader {
ResponseHeader::new_timestamped_service_result(DateTime::now(), request_header, service_result)
}
pub fn new_timestamped_service_result(timestamp: DateTime, request_header: &RequestHeader, service_result: StatusCode) -> ResponseHeader {
ResponseHeader {
timestamp,
request_handle: request_header.request_handle,
service_result,
service_diagnostics: DiagnosticInfo::default(),
string_table: None,
additional_header: ExtensionObject::null(),
}
}
pub fn null() -> ResponseHeader {
ResponseHeader {
timestamp: DateTime::now(),
request_handle: 0,
service_result: StatusCode::Good,
service_diagnostics: DiagnosticInfo::default(),
string_table: None,
additional_header: ExtensionObject::null(),
}
}
}