qvopenapi/models/query/
mod.rs

1mod c8201;
2pub use c8201::*;
3use qvopenapi_bindings::OutDataBlock;
4use serde::Serialize;
5
6use serde_json::Value;
7use std::ffi::c_char;
8
9use crate::{client::QvOpenApiRequest, error::*, utils::from_cp949_ptr, wmca_lib};
10
11pub fn parse_data(lparam: isize) -> std::result::Result<DataResponse, QvOpenApiError> {
12    let data_block = lparam as *const OutDataBlock<c_char>;
13    unsafe {
14        let tr_index = (*data_block).tr_index;
15        let data = (*data_block).p_data;
16        let block_name = from_cp949_ptr((*data).block_name);
17        let block_data = (*data).sz_data;
18        let block_len = (*data).len;
19
20        Ok(DataResponse {
21            tr_index,
22            block_data: parse_block(block_name.as_str(), block_data, block_len)?,
23            block_name,
24            block_len,
25        })
26    }
27}
28
29pub fn parse_sise(lparam: isize) -> std::result::Result<DataResponse, QvOpenApiError> {
30    let data_block = lparam as *const OutDataBlock<c_char>;
31    unsafe {
32        let tr_index = (*data_block).tr_index;
33        let data = (*data_block).p_data;
34        let block_name = from_cp949_ptr((*data).block_name);
35        let block_data = (*data).sz_data.offset(3); //앞쪽 3바이트는 패킷유형과 압축구분이므로 skip
36        let block_len = (*data).len;
37
38        Ok(DataResponse {
39            tr_index,
40            block_data: parse_block(block_name.as_str(), block_data, block_len)?,
41            block_name,
42            block_len,
43        })
44    }
45}
46
47fn parse_block(
48    block_name: &str,
49    block_data: *const c_char,
50    block_len: i32,
51) -> Result<Value, QvOpenApiError> {
52    match block_name {
53        BLOCK_NAME_C8201_OUT => parse_c8201_response(block_data, block_len),
54        BLOCK_NAME_C8201_OUT1_ARRAY => parse_c8201_response1_array(block_data, block_len),
55        _ => Err(QvOpenApiError::UnimplementedBlockError {
56            block_name: block_name.into(),
57        }),
58    }
59}
60
61pub struct RawQueryRequest<T: ?Sized> {
62    pub tr_code: &'static str,
63    pub account_index: i32,
64    pub raw_input: Box<T>,
65}
66
67impl<T: Send + Sync> QvOpenApiRequest for RawQueryRequest<T> {
68    fn before_post(&self) -> Result<(), QvOpenApiError> {
69        wmca_lib::assert_connected()
70    }
71
72    fn call_lib(&self, tr_index: i32, hwnd: isize) -> Result<(), QvOpenApiError> {
73        wmca_lib::query(
74            hwnd,
75            tr_index,
76            self.tr_code,
77            self.raw_input.as_ref(),
78            self.account_index,
79        )
80    }
81
82    fn get_tr_code(&self) -> &str {
83        self.tr_code
84    }
85}
86
87impl<T> RawQueryRequest<T> {
88    pub fn new(tr_code: &'static str, account_index: i32, raw_input: Box<T>) -> RawQueryRequest<T> {
89        RawQueryRequest {
90            tr_code,
91            account_index,
92            raw_input,
93        }
94    }
95}
96
97#[derive(Debug, Clone, Serialize)]
98pub struct DataResponse {
99    pub tr_index: i32,
100    pub block_name: String,
101    pub block_len: i32,
102    pub block_data: Value,
103}
104
105pub struct DisconnectRequest {}
106
107impl QvOpenApiRequest for DisconnectRequest {
108    fn before_post(&self) -> Result<(), QvOpenApiError> {
109        Ok(())
110    }
111
112    fn call_lib(&self, _tr_index: i32, _hwnd: isize) -> Result<(), QvOpenApiError> {
113        wmca_lib::disconnect()
114    }
115
116    fn get_tr_code(&self) -> &str {
117        "DISCONNECT"
118    }
119}