• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::ffi::c_char;
15 use std::slice;
16 
17 use crate::utils::form_item::{FileSpec, FormItem};
18 
19 #[derive(Clone, Debug)]
20 #[repr(C)]
21 pub(crate) struct CStringWrapper {
22     c_str: *const c_char,
23     len: u32,
24 }
25 
26 impl From<&str> for CStringWrapper {
from(value: &str) -> Self27     fn from(value: &str) -> Self {
28         let c_str = value.as_ptr() as *const c_char;
29         let len = value.len() as u32;
30         CStringWrapper { c_str, len }
31     }
32 }
33 
34 impl From<&String> for CStringWrapper {
from(value: &String) -> Self35     fn from(value: &String) -> Self {
36         Self::from(value.as_str())
37     }
38 }
39 
40 impl ToString for CStringWrapper {
to_string(&self) -> String41     fn to_string(&self) -> String {
42         if self.c_str.is_null() || self.len == 0 {
43             #[cfg(feature = "oh")]
44             unsafe {
45                 DeleteChar(self.c_str)
46             };
47             return String::new();
48         }
49         let bytes = unsafe { slice::from_raw_parts(self.c_str as *const u8, self.len as usize) };
50         let str = unsafe { String::from_utf8_unchecked(bytes.to_vec()) };
51         #[cfg(feature = "oh")]
52         unsafe {
53             DeleteChar(self.c_str)
54         };
55         str
56     }
57 }
58 
59 #[repr(C)]
60 pub(crate) struct CFileSpec {
61     pub(crate) name: CStringWrapper,
62     pub(crate) path: CStringWrapper,
63     pub(crate) file_name: CStringWrapper,
64     pub(crate) mime_type: CStringWrapper,
65     pub(crate) is_user_file: bool,
66 }
67 
68 impl FileSpec {
to_c_struct(&self) -> CFileSpec69     pub(crate) fn to_c_struct(&self) -> CFileSpec {
70         CFileSpec {
71             name: CStringWrapper::from(&self.name),
72             path: CStringWrapper::from(&self.path),
73             file_name: CStringWrapper::from(&self.file_name),
74             mime_type: CStringWrapper::from(&self.mime_type),
75             is_user_file: self.is_user_file,
76         }
77     }
78 
from_c_struct(c_struct: &CFileSpec) -> Self79     pub(crate) fn from_c_struct(c_struct: &CFileSpec) -> Self {
80         FileSpec {
81             name: c_struct.name.to_string(),
82             path: c_struct.path.to_string(),
83             file_name: c_struct.file_name.to_string(),
84             mime_type: c_struct.mime_type.to_string(),
85             is_user_file: c_struct.is_user_file,
86             fd: None,
87         }
88     }
89 }
90 
91 #[repr(C)]
92 pub(crate) struct CFormItem {
93     pub(crate) name: CStringWrapper,
94     pub(crate) value: CStringWrapper,
95 }
96 
97 impl FormItem {
to_c_struct(&self) -> CFormItem98     pub(crate) fn to_c_struct(&self) -> CFormItem {
99         CFormItem {
100             name: CStringWrapper::from(&self.name),
101             value: CStringWrapper::from(&self.value),
102         }
103     }
104 
from_c_struct(c_struct: &CFormItem) -> Self105     pub(crate) fn from_c_struct(c_struct: &CFormItem) -> Self {
106         FormItem {
107             name: c_struct.name.to_string(),
108             value: c_struct.value.to_string(),
109         }
110     }
111 }
112 
113 #[cfg(feature = "oh")]
114 extern "C" {
DeleteChar(ptr: *const c_char)115     pub(crate) fn DeleteChar(ptr: *const c_char);
DeleteCFormItem(ptr: *const CFormItem)116     pub(crate) fn DeleteCFormItem(ptr: *const CFormItem);
DeleteCFileSpec(ptr: *const CFileSpec)117     pub(crate) fn DeleteCFileSpec(ptr: *const CFileSpec);
DeleteCStringPtr(ptr: *const CStringWrapper)118     pub(crate) fn DeleteCStringPtr(ptr: *const CStringWrapper);
119 }
120