use std::{
cell::Cell,
ffi::{CStr, CString},
os::raw::c_char,
path::Path,
ptr::null_mut,
};
use libloading::Library;
use crate::v1alpha1::bindings::*;
use crate::v1alpha1::mdspi::*;
pub struct MdApi {
pub api_ptr: *mut CThostFtdcMdApi,
pub spi_ptr: Cell<* mut CThostFtdcMdSpiExt>,
pub dynlib: Option<Library>,
}
unsafe impl Sync for MdApi {}
unsafe impl Send for MdApi {}
impl MdApi {
pub fn release(&self) {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_Release)(self.api_ptr)
}
}
pub fn init(&self) {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_Init)(self.api_ptr)
}
}
pub fn join(&self) -> i32 {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_Join)(self.api_ptr)
}
}
pub fn get_trading_day(&self) -> String {
unsafe {
let cstr_ptr = ((*(*self.api_ptr).vtable_).CThostFtdcMdApi_GetTradingDay)(self.api_ptr);
let c_str = CStr::from_ptr(cstr_ptr);
c_str.to_string_lossy().to_string()
}
}
pub fn register_front(&self, psz_front_address: &str) {
unsafe {
let psz_front_address = CString::new(psz_front_address).unwrap();
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_RegisterFront)(self.api_ptr, psz_front_address.as_ptr() as *mut i8)
}
}
pub fn register_name_server(&self, psz_ns_address: &str) {
unsafe {
let psz_ns_address = CString::new(psz_ns_address).unwrap();
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_RegisterNameServer)(self.api_ptr, psz_ns_address.as_ptr() as *mut i8)
}
}
pub fn register_fens_user_info(&self, p_fens_user_info: &mut CThostFtdcFensUserInfoField) {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_RegisterFensUserInfo)(self.api_ptr, p_fens_user_info as *mut CThostFtdcFensUserInfoField)
}
}
pub fn register_spi(&self, p_spi: *mut dyn MdSpi) {
let spi_ptr = Box::into_raw(Box::new(CThostFtdcMdSpiExt::new(p_spi)));
let last_spi_ptr = self.spi_ptr.get();
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_RegisterSpi)(self.api_ptr, spi_ptr as _)
}
self.spi_ptr.set(spi_ptr);
if !last_spi_ptr.is_null() {
unsafe {
let _ = Box::from_raw(last_spi_ptr); }
}
}
pub fn subscribe_market_data(&self, pp_instrument_id: &Vec<String>) -> i32 {
let cstrings: Vec<_> = pp_instrument_id.iter().map(|x| CString::new(x.clone()).unwrap()).collect();
let cstr_slice: Vec<*const i8> = cstrings.iter().map(|cstr| cstr.as_ptr()).collect();
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_SubscribeMarketData)(self.api_ptr, cstr_slice.as_ptr() as *mut *mut i8, pp_instrument_id.len() as i32)
}
}
pub fn unsubscribe_market_data(&self, pp_instrument_id: &Vec<String>) -> i32 {
let cstrings: Vec<_> = pp_instrument_id.iter().map(|x| CString::new(x.clone()).unwrap()).collect();
let cstr_slice: Vec<*const i8> = cstrings.iter().map(|cstr| cstr.as_ptr()).collect();
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_UnSubscribeMarketData)(self.api_ptr, cstr_slice.as_ptr() as *mut *mut i8, pp_instrument_id.len() as i32)
}
}
pub fn subscribe_for_quote_rsp(&self, pp_instrument_id: &Vec<String>) -> i32 {
let cstrings: Vec<_> = pp_instrument_id.iter().map(|x| CString::new(x.clone()).unwrap()).collect();
let cstr_slice: Vec<*const i8> = cstrings.iter().map(|cstr| cstr.as_ptr()).collect();
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_SubscribeForQuoteRsp)(self.api_ptr, cstr_slice.as_ptr() as *mut *mut i8, pp_instrument_id.len() as i32)
}
}
pub fn unsubscribe_for_quote_rsp(&self, pp_instrument_id: &Vec<String>) -> i32 {
let cstrings: Vec<_> = pp_instrument_id.iter().map(|x| CString::new(x.clone()).unwrap()).collect();
let cstr_slice: Vec<*const i8> = cstrings.iter().map(|cstr| cstr.as_ptr()).collect();
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_UnSubscribeForQuoteRsp)(self.api_ptr, cstr_slice.as_ptr() as *mut *mut i8, pp_instrument_id.len() as i32)
}
}
pub fn req_user_login(&self, p_req_user_login_field: &mut CThostFtdcReqUserLoginField, n_request_id: i32) -> i32 {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_ReqUserLogin)(self.api_ptr, p_req_user_login_field as *mut CThostFtdcReqUserLoginField, n_request_id)
}
}
pub fn req_user_logout(&self, p_user_logout: &mut CThostFtdcUserLogoutField, n_request_id: i32) -> i32 {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_ReqUserLogout)(self.api_ptr, p_user_logout as *mut CThostFtdcUserLogoutField, n_request_id)
}
}
pub fn req_qry_multicast_instrument(&self, p_qry_multicast_instrument: &mut CThostFtdcQryMulticastInstrumentField, n_request_id: i32) -> i32 {
unsafe {
((*(*self.api_ptr).vtable_).CThostFtdcMdApi_ReqQryMulticastInstrument)(self.api_ptr, p_qry_multicast_instrument as *mut CThostFtdcQryMulticastInstrumentField, n_request_id)
}
}
}