opc_da/client/traits/async_io3.rs
1use crate::utils::RemoteArray;
2
3/// Asynchronous I/O functionality (OPC DA 3.0).
4///
5/// Provides methods for enhanced asynchronous read/write operations with
6/// quality and timestamp information.
7pub trait AsyncIo3Trait {
8 fn interface(&self) -> windows::core::Result<&opc_da_bindings::IOPCAsyncIO3>;
9
10 /// Reads values with maximum age constraint.
11 ///
12 /// # Arguments
13 /// * `server_handles` - Array of server item handles
14 /// * `max_age` - Maximum age constraints for each item (milliseconds)
15 /// * `transaction_id` - Client-provided transaction identifier
16 ///
17 /// # Returns
18 /// Tuple containing cancel ID and array of per-item error codes
19 fn read_max_age(
20 &self,
21 server_handles: &[u32],
22 max_age: &[u32],
23 transaction_id: u32,
24 ) -> windows::core::Result<(u32, RemoteArray<windows::core::HRESULT>)> {
25 if server_handles.len() != max_age.len() {
26 return Err(windows::core::Error::new(
27 windows::Win32::Foundation::E_INVALIDARG,
28 "server_handles and max_age must have the same length",
29 ));
30 }
31
32 let len = server_handles.len().try_into()?;
33
34 let mut cancel_id = 0;
35 let mut errors = RemoteArray::new(len);
36
37 unsafe {
38 self.interface()?.ReadMaxAge(
39 len,
40 server_handles.as_ptr(),
41 max_age.as_ptr(),
42 transaction_id,
43 &mut cancel_id,
44 errors.as_mut_ptr(),
45 )?;
46 }
47
48 Ok((cancel_id, errors))
49 }
50
51 /// Writes values with quality and timestamp information.
52 ///
53 /// # Arguments
54 /// * `server_handles` - Array of server item handles
55 /// * `values` - Array of values with quality and timestamp (VQT)
56 /// * `transaction_id` - Client-provided transaction identifier
57 ///
58 /// # Returns
59 /// Tuple containing cancel ID and array of per-item error codes
60 fn write_vqt(
61 &self,
62 server_handles: &[u32],
63 values: &[opc_da_bindings::tagOPCITEMVQT],
64 transaction_id: u32,
65 ) -> windows::core::Result<(u32, RemoteArray<windows::core::HRESULT>)> {
66 if server_handles.len() != values.len() {
67 return Err(windows::core::Error::new(
68 windows::Win32::Foundation::E_INVALIDARG,
69 "server_handles and values must have the same length",
70 ));
71 }
72
73 let len = server_handles.len().try_into()?;
74
75 let mut cancel_id = 0;
76 let mut errors = RemoteArray::new(len);
77
78 unsafe {
79 self.interface()?.WriteVQT(
80 len,
81 server_handles.as_ptr(),
82 values.as_ptr(),
83 transaction_id,
84 &mut cancel_id,
85 errors.as_mut_ptr(),
86 )?;
87 }
88
89 Ok((cancel_id, errors))
90 }
91
92 /// Refreshes all active items with maximum age constraint.
93 ///
94 /// # Arguments
95 /// * `max_age` - Maximum age constraint in milliseconds
96 /// * `transaction_id` - Client-provided transaction identifier
97 ///
98 /// # Returns
99 /// Cancel ID for the refresh operation
100 fn refresh_max_age(&self, max_age: u32, transaction_id: u32) -> windows::core::Result<u32> {
101 unsafe { self.interface()?.RefreshMaxAge(max_age, transaction_id) }
102 }
103}