mod.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. use concurrent_hashmap::{ ConcHashMap };
  2. use libc::c_int;
  3. use crate::bytes_vec::ZRFUBytesVec;
  4. use crate::errno::{ZRFUErrBehavior, ZRFUErrNo, ZRFUErrPrefix};
  5. use once_cell::sync::OnceCell;
  6. use crate::proc::{ZRFUProcInstanceTrait, ZRFUProcResultCode};
  7. use std::boxed::Box;
  8. use ciborium::de;
  9. struct ProcCaller {
  10. proc_registry: ConcHashMap<String, ProcEntity>,
  11. }
  12. impl ProcCaller {
  13. fn new() -> Self {
  14. ProcCaller{
  15. proc_registry: ConcHashMap::<String, ProcEntity>::new(),
  16. }
  17. }
  18. fn do_with_proc<F, R>(&self, name: &String, callback: F) -> Result<R, ZRFUErrNo>
  19. where
  20. F: FnOnce(&ProcEntity) -> Result<R, ZRFUErrNo>,
  21. {
  22. let find_res = self.proc_registry.find(name);
  23. let pe = match find_res {
  24. None => { return Result::Err(ZRFUErrBehavior::ProcNotFound.to_errno(ZRFUErrPrefix::ProcCallBasic)); },
  25. Some(t) => {
  26. t.get()
  27. },
  28. };
  29. callback(pe)
  30. }
  31. }
  32. pub trait ProcCallerLibSide {
  33. fn register_proc(&self, name: String, factory_func: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>);
  34. }
  35. impl ProcCallerLibSide for ProcCaller{
  36. fn register_proc(&self, name: String, factory_func: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>) {
  37. let pe = ProcEntity{
  38. name: name.clone(),
  39. factory: factory_func,
  40. };
  41. self.proc_registry.insert(name, pe);
  42. }
  43. }
  44. struct ProcEntity {
  45. name: String,
  46. factory: fn(name: String) -> Box<dyn ZRFUProcInstanceTrait>,
  47. }
  48. static PROC_CALLER: OnceCell<ProcCaller> = OnceCell::new();
  49. extern "C" {
  50. fn LibWithZRFU_Init(caller: &dyn ProcCallerLibSide);
  51. }
  52. #[no_mangle]
  53. pub extern fn ZRFU_Proc_Init() -> c_int {
  54. let opc = PROC_CALLER.get();
  55. match opc {
  56. Some(_) => {return ZRFUErrNo::ProcCaller_ProcCallerRepeatlyInit.get_return_code(); },
  57. None => (),
  58. };
  59. let pcls = ProcCaller::new();
  60. unsafe { LibWithZRFU_Init(&pcls as &dyn ProcCallerLibSide); }
  61. let _ = PROC_CALLER.set(pcls);
  62. return 0;
  63. }
  64. #[no_mangle]
  65. pub extern fn ZRFU_Proc_Call(name_hptr: *const u64, in_hptr: *const u64, out_hptr: *const u64) -> c_int {
  66. if name_hptr.is_null() {
  67. return ZRFUErrNo::ProcCallBasic_NullPointerHandle.get_return_code();
  68. }
  69. let name_h = unsafe{ name_hptr.read() };
  70. let name_res:Result<String, ZRFUErrBehavior> = ZRFUBytesVec::do_with_mut_object(name_h, |bv| {
  71. let res = de::from_reader(bv);
  72. match res {
  73. Ok(t) => Result::Ok(t),
  74. Err(e) => Result::Err(
  75. ZRFUErrBehavior::CBORDecodeError
  76. .with_complex_error(format!("CBOR Decode Error in ProcName Decoding: {:?}", e).as_str())
  77. ),
  78. }
  79. });
  80. let proc_name:String = match name_res {
  81. Ok(t) => t,
  82. Err(e) => {
  83. return e.to_errno(ZRFUErrPrefix::ProcCallBasic).get_return_code();
  84. },
  85. };
  86. //println!("ProcCall Test: ProcName={}", proc_name.as_str());
  87. let pc_opt= PROC_CALLER.get();
  88. let pc = match pc_opt {
  89. None => {
  90. return ZRFUErrNo::ProcCaller_ProcCallerNotInit.get_return_code();
  91. },
  92. Some(t) => t,
  93. };
  94. let proc_find_res = pc.do_with_proc(&proc_name, |pe| {
  95. let has_input = !in_hptr.is_null();
  96. let has_return = !out_hptr.is_null();
  97. let mut proc_inst = (pe.factory)(pe.name.clone());
  98. if has_input {
  99. let h = unsafe{ in_hptr.read() };
  100. let input_dec_res = ZRFUBytesVec::do_with_mut_object(h, |bv| {
  101. let res = proc_inst.decode_input(bv);
  102. if res != ZRFUProcResultCode::Ok {
  103. Result::Err(ZRFUErrBehavior::from(res))
  104. }else{
  105. Result::Ok(())
  106. }
  107. });
  108. match input_dec_res {
  109. Ok(_) => (),
  110. Err(e) => { return Result::Err(e.to_errno(ZRFUErrPrefix::ProcCallInput)); },
  111. }
  112. };
  113. let call_res = proc_inst.call();
  114. if call_res != ZRFUProcResultCode::Ok {
  115. return Result::Err(ZRFUErrBehavior::from(call_res).to_errno(ZRFUErrPrefix::ProcCalling))
  116. }
  117. if has_return {
  118. let h = unsafe{ out_hptr.read() };
  119. let return_enc_res = ZRFUBytesVec::do_with_mut_object(h, |bv| {
  120. let res = proc_inst.encode_return(bv);
  121. if res != ZRFUProcResultCode::Ok {
  122. Result::Err(ZRFUErrBehavior::from(res))
  123. }else{
  124. Result::Ok(())
  125. }
  126. });
  127. match return_enc_res {
  128. Ok(_) => (),
  129. Err(e) => { return Result::Err(e.to_errno(ZRFUErrPrefix::ProcCallReturn)); },
  130. }
  131. }
  132. return Result::Ok(());
  133. });
  134. let proc_res:c_int = match proc_find_res {
  135. Err(e) => {
  136. return e.get_return_code();
  137. },
  138. Ok(_) => 0,
  139. };
  140. proc_res
  141. /*
  142. if in_hptr.is_null() {
  143. return ZRFUErrNo::ProcCallInput_NullPointerHandle.get_return_code();
  144. }
  145. let in_h = unsafe { in_hptr.read() };
  146. let in_res = ZRFUBytesVec::do_with_object(in_h, |bv| {
  147. });
  148. */
  149. }