rsfbclient_native/
services.rs1use crate::{connection::LinkageMarker, ibase, ibase::IBase, status::Status};
12use rsfbclient_core::FbError;
13
14pub struct NativeServiceManager<T: LinkageMarker> {
19 ibase: T::L,
20 status: Status,
21 handle: ibase::isc_svc_handle,
22}
23
24#[cfg(feature = "linking")]
25impl NativeServiceManager<crate::connection::DynLink> {
26 pub fn attach_dyn_link(host: &str, port: u16, attach_spb: &[u8]) -> Result<Self, FbError> {
28 Self::attach(ibase::IBaseLinking, host, port, attach_spb)
29 }
30}
31
32#[cfg(feature = "dynamic_loading")]
33impl NativeServiceManager<crate::connection::DynLoad> {
34 pub fn attach_dyn_load(
37 lib_path: &str,
38 host: &str,
39 port: u16,
40 attach_spb: &[u8],
41 ) -> Result<Self, FbError> {
42 let lib = ibase::IBaseDynLoading::with_client(lib_path.as_ref())
43 .map_err(|e| FbError::from(e.to_string()))?;
44 Self::attach(lib, host, port, attach_spb)
45 }
46}
47
48impl<T: LinkageMarker> NativeServiceManager<T> {
49 fn attach(ibase: T::L, host: &str, port: u16, attach_spb: &[u8]) -> Result<Self, FbError> {
55 let mut status: Status = Default::default();
56 let mut handle: ibase::isc_svc_handle = 0;
57
58 let conn_string = format!("{}/{}:service_mgr", host, port);
59
60 unsafe {
61 if ibase.isc_service_attach()(
62 &mut status[0],
63 conn_string.len() as u16,
64 conn_string.as_ptr() as *const _,
65 &mut handle,
66 attach_spb.len() as u16,
67 attach_spb.as_ptr() as *const _,
68 ) != 0
69 {
70 return Err(status.as_error(&ibase));
71 }
72 }
73
74 debug_assert_ne!(handle, 0);
75
76 Ok(Self {
77 ibase,
78 status,
79 handle,
80 })
81 }
82
83 pub fn start(&mut self, request: &[u8]) -> Result<(), FbError> {
85 unsafe {
86 if self.ibase.isc_service_start()(
87 &mut self.status[0],
88 &mut self.handle,
89 std::ptr::null_mut(),
90 request.len() as u16,
91 request.as_ptr() as *const _,
92 ) != 0
93 {
94 return Err(self.status.as_error(&self.ibase));
95 }
96 }
97 Ok(())
98 }
99
100 pub fn query(
103 &mut self,
104 send_items: &[u8],
105 receive_items: &[u8],
106 buffer: &mut [u8],
107 ) -> Result<(), FbError> {
108 unsafe {
109 if self.ibase.isc_service_query()(
110 &mut self.status[0],
111 &mut self.handle,
112 std::ptr::null_mut(),
113 send_items.len() as u16,
114 send_items.as_ptr() as *const _,
115 receive_items.len() as u16,
116 receive_items.as_ptr() as *const _,
117 buffer.len() as u16,
118 buffer.as_mut_ptr() as *mut _,
119 ) != 0
120 {
121 return Err(self.status.as_error(&self.ibase));
122 }
123 }
124 Ok(())
125 }
126
127 pub fn detach(&mut self) -> Result<(), FbError> {
129 unsafe {
130 if self.handle != 0
131 && self.ibase.isc_service_detach()(&mut self.status[0], &mut self.handle) != 0
132 {
133 return Err(self.status.as_error(&self.ibase));
134 }
135 }
136 self.handle = 0;
137 Ok(())
138 }
139}
140
141impl<T: LinkageMarker> Drop for NativeServiceManager<T> {
142 fn drop(&mut self) {
143 self.detach().ok();
144 }
145}