1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 use crate::c_adapter::basic_rust_types::{HashMapCffi, VectorCffi};
17 use crate::c_adapter::*;
18 use crate::ipc_conn;
19 use crate::service_impl::{asset_loader, cloud_db, cloud_service, types};
20 use std::collections::HashMap;
21 use std::ffi::{c_int, c_longlong, c_uchar, c_uint, c_ulonglong, c_void};
22 use std::ptr::{null, null_mut, slice_from_raw_parts};
23
24 /// CloudAssetBuilder defined in C struct. It will be used to build a Rust CloudAsset struct in use.
25 #[repr(C)]
26 pub struct OhCloudExtCloudAssetBuilder {
27 pub version: u64,
28 pub status: asset_loader::AssetStatus,
29 pub expires_time: u64,
30 pub id: *const c_uchar,
31 pub id_len: c_uint,
32 pub name: *const c_uchar,
33 pub name_len: c_uint,
34 pub uri: *const c_uchar,
35 pub uri_len: c_uint,
36 pub local_path: *const c_uchar,
37 pub local_path_len: c_uint,
38 pub create_time: *const c_uchar,
39 pub create_time_len: c_uint,
40 pub modify_time: *const c_uchar,
41 pub modify_time_len: c_uint,
42 pub size: *const c_uchar,
43 pub size_len: c_uint,
44 pub hash: *const c_uchar,
45 pub hash_len: c_uint,
46 }
47
48 /// Enumeration represents inner type of contents in Value enum.
49 #[repr(C)]
50 #[allow(non_camel_case_types, clippy::upper_case_acronyms)]
51 #[derive(Debug, Eq, PartialEq)]
52 pub enum OhCloudExtValueType {
53 EMPTY = 0,
54 INT,
55 FLOAT,
56 STRING,
57 BOOL,
58 BYTES,
59 ASSET,
60 ASSETS,
61 }
62
63 /// Value pointer passed to C side.
64 pub type OhCloudExtValue = SafeCffiWrapper<types::Value>;
65 /// CloudAsset pointer passed to C side.
66 pub type OhCloudExtCloudAsset = SafeCffiWrapper<ipc_conn::CloudAsset>;
67 /// Database pointer passed to C side.
68 pub type OhCloudExtDatabase = SafeCffiWrapper<types::Database>;
69 /// CloudInfo pointer passed to C side.
70 pub type OhCloudExtCloudInfo = SafeCffiWrapper<cloud_service::CloudInfo>;
71 /// AppInfo pointer passed to C side.
72 pub type OhCloudExtAppInfo = SafeCffiWrapper<cloud_service::AppInfo>;
73 /// Table pointer passed to C side.
74 pub type OhCloudExtTable = SafeCffiWrapper<types::Table>;
75 /// Field pointer passed to C side.
76 pub type OhCloudExtField = SafeCffiWrapper<types::Field>;
77 /// SchemaMeta pointer passed to C side.
78 pub type OhCloudExtSchemaMeta = SafeCffiWrapper<cloud_service::SchemaMeta>;
79 /// RelationSet pointer passed to C side.
80 pub type OhCloudExtRelationSet = SafeCffiWrapper<cloud_service::RelationSet>;
81 /// CloudDbData pointer passed to C side.
82 pub type OhCloudExtCloudDbData = SafeCffiWrapper<cloud_db::CloudDbData>;
83 /// ValueBucket pointer passed to C side.
84 pub type OhCloudExtValueBucket = SafeCffiWrapper<ipc_conn::ValueBucket>;
85
86 /// Create a Value instance according to ValueInnerType.
87 #[no_mangle]
OhCloudExtValueNew( typ: OhCloudExtValueType, content: *mut c_void, len: c_uint, ) -> *mut OhCloudExtValue88 pub unsafe extern "C" fn OhCloudExtValueNew(
89 typ: OhCloudExtValueType,
90 content: *mut c_void,
91 len: c_uint,
92 ) -> *mut OhCloudExtValue {
93 if typ != OhCloudExtValueType::EMPTY && content.is_null() {
94 return null_mut();
95 }
96
97 let val = match typ {
98 OhCloudExtValueType::EMPTY => types::Value::Empty,
99 OhCloudExtValueType::INT => {
100 let int = &*(content as *mut i64);
101 types::Value::Int(*int)
102 }
103 OhCloudExtValueType::FLOAT => {
104 let float = &*(content as *mut f64);
105 types::Value::Float(*float)
106 }
107 OhCloudExtValueType::BOOL => {
108 let bool = &*(content as *mut u8);
109 types::Value::Bool(c_bool_to_bool(*bool))
110 }
111 OhCloudExtValueType::STRING => {
112 let str = char_ptr_to_string(content as *const c_uchar, len);
113 types::Value::String(str)
114 }
115 OhCloudExtValueType::BYTES => {
116 let slice = &(*slice_from_raw_parts(content as *const u8, len as usize));
117 types::Value::Bytes(slice.to_vec())
118 }
119 OhCloudExtValueType::ASSET => {
120 let asset = match OhCloudExtCloudAsset::get_inner(
121 content as *mut OhCloudExtCloudAsset,
122 SafetyCheckId::CloudAsset,
123 ) {
124 None => return null_mut(),
125 Some(v) => v,
126 };
127 types::Value::Asset(asset)
128 }
129 OhCloudExtValueType::ASSETS => {
130 let assets = match OhCloudExtVector::get_inner(
131 content as *mut OhCloudExtVector,
132 SafetyCheckId::Vector,
133 ) {
134 None => return null_mut(),
135 Some(v) => v,
136 };
137 match assets {
138 VectorCffi::CloudAsset(v) => types::Value::Assets(v),
139 _ => return null_mut(),
140 }
141 }
142 };
143
144 OhCloudExtValue::new(val, SafetyCheckId::Value).into_ptr() as *mut OhCloudExtValue
145 }
146
147 /// Get content from a Value pointer.
148 ///
149 /// If the Value is Value::Assets or Value::Asset, the Vector pointer returned should be freed by
150 /// `VectorFree`.
151 #[no_mangle]
OhCloudExtValueGetContent( src: *mut OhCloudExtValue, typ: *mut OhCloudExtValueType, content: *mut *const c_void, len: *mut c_uint, ) -> c_int152 pub unsafe extern "C" fn OhCloudExtValueGetContent(
153 src: *mut OhCloudExtValue,
154 typ: *mut OhCloudExtValueType,
155 content: *mut *const c_void,
156 len: *mut c_uint,
157 ) -> c_int {
158 if src.is_null() || typ.is_null() || content.is_null() || len.is_null() {
159 return ERRNO_NULLPTR;
160 }
161
162 let value_struct = match OhCloudExtValue::get_inner_ref(src, SafetyCheckId::Value) {
163 None => return ERRNO_WRONG_TYPE,
164 Some(v) => v,
165 };
166 match value_struct {
167 types::Value::Empty => {
168 *typ = OhCloudExtValueType::EMPTY;
169 *content = null();
170 *len = 0;
171 }
172 types::Value::Int(c) => {
173 *typ = OhCloudExtValueType::INT;
174 *content = c as *const _ as *const c_void;
175 }
176 types::Value::Float(c) => {
177 *typ = OhCloudExtValueType::FLOAT;
178 *content = c as *const _ as *const c_void;
179 }
180 types::Value::String(c) => {
181 *typ = OhCloudExtValueType::STRING;
182 *content = c.as_ptr() as *const c_void;
183 *len = c.len() as c_uint;
184 }
185 types::Value::Bool(c) => {
186 *typ = OhCloudExtValueType::BOOL;
187 *content = c as *const _ as *const c_void;
188 }
189 types::Value::Bytes(c) => {
190 *typ = OhCloudExtValueType::BYTES;
191 *content = c.as_ptr() as *const c_void;
192 *len = c.len() as c_uint;
193 }
194 types::Value::Asset(c) => {
195 *typ = OhCloudExtValueType::ASSET;
196 *content = OhCloudExtCloudAsset::new(c.clone(), SafetyCheckId::CloudAsset).into_ptr()
197 as *mut c_void;
198 }
199 types::Value::Assets(c) => {
200 *typ = OhCloudExtValueType::ASSETS;
201 let vec = VectorCffi::CloudAsset(c.to_vec());
202 *content = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr() as *mut c_void;
203 *len = c.len() as c_uint;
204 }
205 }
206 ERRNO_SUCCESS
207 }
208
209 /// Free a Value pointer.
210 #[no_mangle]
OhCloudExtValueFree(src: *mut OhCloudExtValue)211 pub unsafe extern "C" fn OhCloudExtValueFree(src: *mut OhCloudExtValue) {
212 let _ = OhCloudExtValue::from_ptr(src, SafetyCheckId::Value);
213 }
214
get_cloud_asset(builder: *const OhCloudExtCloudAssetBuilder) -> ipc_conn::CloudAsset215 unsafe fn get_cloud_asset(builder: *const OhCloudExtCloudAssetBuilder) -> ipc_conn::CloudAsset {
216 let builder = &*builder;
217 let id = char_ptr_to_string(builder.id, builder.id_len);
218 let name = char_ptr_to_string(builder.name, builder.name_len);
219 let uri = char_ptr_to_string(builder.uri, builder.uri_len);
220 let local_path = char_ptr_to_string(builder.local_path, builder.local_path_len);
221 let create_time = char_ptr_to_string(builder.create_time, builder.create_time_len);
222 let modify_time = char_ptr_to_string(builder.modify_time, builder.modify_time_len);
223 let size = char_ptr_to_string(builder.size, builder.size_len);
224 let hash = char_ptr_to_string(builder.hash, builder.hash_len);
225 ipc_conn::CloudAsset {
226 asset_id: id,
227 status: builder.status.clone(),
228 asset_name: name,
229 hash,
230 uri,
231 sub_path: local_path,
232 create_time,
233 modify_time,
234 size,
235 }
236 }
237
238 /// Initialize an CloudAsset by the CloudAssetBuilder.
239 #[no_mangle]
OhCloudExtCloudAssetNew( builder: *const OhCloudExtCloudAssetBuilder, ) -> *mut OhCloudExtCloudAsset240 pub unsafe extern "C" fn OhCloudExtCloudAssetNew(
241 builder: *const OhCloudExtCloudAssetBuilder,
242 ) -> *mut OhCloudExtCloudAsset {
243 if builder.is_null() {
244 return null_mut();
245 }
246
247 let cloud_asset = get_cloud_asset(builder);
248 OhCloudExtCloudAsset::new(cloud_asset, SafetyCheckId::CloudAsset).into_ptr()
249 as *mut OhCloudExtCloudAsset
250 }
251
252 /// Get id from an CloudAsset pointer.
253 #[no_mangle]
OhCloudExtCloudAssetGetId( src: *const OhCloudExtCloudAsset, id: *mut *const c_uchar, len: *mut c_uint, ) -> c_int254 pub unsafe extern "C" fn OhCloudExtCloudAssetGetId(
255 src: *const OhCloudExtCloudAsset,
256 id: *mut *const c_uchar,
257 len: *mut c_uint,
258 ) -> c_int {
259 if src.is_null() || id.is_null() || len.is_null() {
260 return ERRNO_NULLPTR;
261 }
262
263 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
264 None => return ERRNO_WRONG_TYPE,
265 Some(v) => v,
266 };
267 *id = src_struct.id().as_ptr() as *const c_uchar;
268 *len = src_struct.id().len() as c_uint;
269 ERRNO_SUCCESS
270 }
271
272 /// Get name from an CloudAsset pointer.
273 #[no_mangle]
OhCloudExtCloudAssetGetName( src: *const OhCloudExtCloudAsset, name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int274 pub unsafe extern "C" fn OhCloudExtCloudAssetGetName(
275 src: *const OhCloudExtCloudAsset,
276 name: *mut *const c_uchar,
277 len: *mut c_uint,
278 ) -> c_int {
279 if src.is_null() || name.is_null() || len.is_null() {
280 return ERRNO_NULLPTR;
281 }
282
283 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
284 None => return ERRNO_WRONG_TYPE,
285 Some(v) => v,
286 };
287 *name = src_struct.name().as_ptr() as *const c_uchar;
288 *len = src_struct.name().len() as c_uint;
289 ERRNO_SUCCESS
290 }
291
292 /// Get uri from an CloudAsset pointer.
293 #[no_mangle]
OhCloudExtCloudAssetGetUri( src: *const OhCloudExtCloudAsset, uri: *mut *const c_uchar, len: *mut c_uint, ) -> c_int294 pub unsafe extern "C" fn OhCloudExtCloudAssetGetUri(
295 src: *const OhCloudExtCloudAsset,
296 uri: *mut *const c_uchar,
297 len: *mut c_uint,
298 ) -> c_int {
299 if src.is_null() || uri.is_null() || len.is_null() {
300 return ERRNO_NULLPTR;
301 }
302
303 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
304 None => return ERRNO_WRONG_TYPE,
305 Some(v) => v,
306 };
307 *uri = src_struct.uri().as_ptr() as *const c_uchar;
308 *len = src_struct.uri().len() as c_uint;
309 ERRNO_SUCCESS
310 }
311
312 /// Get local path from an CloudAsset pointer.
313 #[no_mangle]
OhCloudExtCloudAssetGetLocalPath( src: *const OhCloudExtCloudAsset, local_path: *mut *const c_uchar, len: *mut c_uint, ) -> c_int314 pub unsafe extern "C" fn OhCloudExtCloudAssetGetLocalPath(
315 src: *const OhCloudExtCloudAsset,
316 local_path: *mut *const c_uchar,
317 len: *mut c_uint,
318 ) -> c_int {
319 if src.is_null() || local_path.is_null() || len.is_null() {
320 return ERRNO_NULLPTR;
321 }
322
323 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
324 None => return ERRNO_WRONG_TYPE,
325 Some(v) => v,
326 };
327 *local_path = src_struct.local_path().as_ptr() as *const c_uchar;
328 *len = src_struct.local_path().len() as c_uint;
329 ERRNO_SUCCESS
330 }
331
332 /// Get create time from an CloudAsset pointer.
333 #[no_mangle]
OhCloudExtCloudAssetGetCreateTime( src: *const OhCloudExtCloudAsset, create_time: *mut *const c_uchar, len: *mut c_uint, ) -> c_int334 pub unsafe extern "C" fn OhCloudExtCloudAssetGetCreateTime(
335 src: *const OhCloudExtCloudAsset,
336 create_time: *mut *const c_uchar,
337 len: *mut c_uint,
338 ) -> c_int {
339 if src.is_null() || create_time.is_null() || len.is_null() {
340 return ERRNO_NULLPTR;
341 }
342
343 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
344 None => return ERRNO_WRONG_TYPE,
345 Some(v) => v,
346 };
347 *create_time = src_struct.create_time().as_ptr() as *const c_uchar;
348 *len = src_struct.create_time().len() as c_uint;
349 ERRNO_SUCCESS
350 }
351
352 /// Get modified time from an CloudAsset pointer.
353 #[no_mangle]
OhCloudExtCloudAssetGetModifiedTime( src: *const OhCloudExtCloudAsset, modify_time: *mut *const c_uchar, len: *mut c_uint, ) -> c_int354 pub unsafe extern "C" fn OhCloudExtCloudAssetGetModifiedTime(
355 src: *const OhCloudExtCloudAsset,
356 modify_time: *mut *const c_uchar,
357 len: *mut c_uint,
358 ) -> c_int {
359 if src.is_null() || modify_time.is_null() || len.is_null() {
360 return ERRNO_NULLPTR;
361 }
362
363 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
364 None => return ERRNO_WRONG_TYPE,
365 Some(v) => v,
366 };
367 *modify_time = src_struct.modify_time().as_ptr() as *const c_uchar;
368 *len = src_struct.modify_time().len() as c_uint;
369 ERRNO_SUCCESS
370 }
371
372 /// Get size from an CloudAsset pointer.
373 #[no_mangle]
OhCloudExtCloudAssetGetSize( src: *const OhCloudExtCloudAsset, size: *mut *const c_uchar, len: *mut c_uint, ) -> c_int374 pub unsafe extern "C" fn OhCloudExtCloudAssetGetSize(
375 src: *const OhCloudExtCloudAsset,
376 size: *mut *const c_uchar,
377 len: *mut c_uint,
378 ) -> c_int {
379 if src.is_null() || size.is_null() || len.is_null() {
380 return ERRNO_NULLPTR;
381 }
382
383 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
384 None => return ERRNO_WRONG_TYPE,
385 Some(v) => v,
386 };
387 *size = src_struct.size().as_ptr() as *const c_uchar;
388 *len = src_struct.size().len() as c_uint;
389 ERRNO_SUCCESS
390 }
391
392 /// Get hash from an CloudAsset pointer.
393 #[no_mangle]
OhCloudExtCloudAssetGetHash( src: *const OhCloudExtCloudAsset, hash: *mut *const c_uchar, len: *mut c_uint, ) -> c_int394 pub unsafe extern "C" fn OhCloudExtCloudAssetGetHash(
395 src: *const OhCloudExtCloudAsset,
396 hash: *mut *const c_uchar,
397 len: *mut c_uint,
398 ) -> c_int {
399 if src.is_null() || hash.is_null() || len.is_null() {
400 return ERRNO_NULLPTR;
401 }
402
403 let src_struct = match OhCloudExtCloudAsset::get_inner_ref(src, SafetyCheckId::CloudAsset) {
404 None => return ERRNO_WRONG_TYPE,
405 Some(v) => v,
406 };
407 *hash = src_struct.hash().as_ptr() as *const c_uchar;
408 *len = src_struct.hash().len() as c_uint;
409 ERRNO_SUCCESS
410 }
411
412 /// Free a CloudAsset pointer.
413 #[no_mangle]
OhCloudExtCloudAssetFree(src: *mut OhCloudExtCloudAsset)414 pub unsafe extern "C" fn OhCloudExtCloudAssetFree(src: *mut OhCloudExtCloudAsset) {
415 let _ = OhCloudExtCloudAsset::from_ptr(src, SafetyCheckId::CloudAsset);
416 }
417
418 /// Create a Database instance by database name, alias, and tables. Tables can be created by
419 /// basic_rust_types::HashMap, and its type should be HashMap<String, Table>. When passed in,
420 /// tables don't need to be freed again, because their management will be transferred to Database
421 /// instance.
422 #[no_mangle]
OhCloudExtDatabaseNew( name: *const c_uchar, name_len: c_uint, alias: *const c_uchar, alias_len: c_uint, tables: *mut OhCloudExtHashMap, ) -> *mut OhCloudExtDatabase423 pub unsafe extern "C" fn OhCloudExtDatabaseNew(
424 name: *const c_uchar,
425 name_len: c_uint,
426 alias: *const c_uchar,
427 alias_len: c_uint,
428 tables: *mut OhCloudExtHashMap,
429 ) -> *mut OhCloudExtDatabase {
430 let name = char_ptr_to_string(name, name_len);
431 let alias = char_ptr_to_string(alias, alias_len);
432
433 if tables.is_null() {
434 let t = HashMap::new();
435 let db = types::Database::new(name, alias, t);
436 OhCloudExtDatabase::new(db, SafetyCheckId::Database).into_ptr() as *mut OhCloudExtDatabase
437 } else {
438 let tables = match OhCloudExtHashMap::get_inner(tables, SafetyCheckId::HashMap) {
439 None => return null_mut(),
440 Some(t) => t,
441 };
442 match tables {
443 HashMapCffi::Table(t) => {
444 let db = types::Database::new(name, alias, t);
445 OhCloudExtDatabase::new(db, SafetyCheckId::Database).into_ptr()
446 as *mut OhCloudExtDatabase
447 }
448 _ => null_mut(),
449 }
450 }
451 }
452
453 /// Get name from a Database pointer.
454 #[no_mangle]
OhCloudExtDatabaseGetName( db: *const OhCloudExtDatabase, name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int455 pub unsafe extern "C" fn OhCloudExtDatabaseGetName(
456 db: *const OhCloudExtDatabase,
457 name: *mut *const c_uchar,
458 len: *mut c_uint,
459 ) -> c_int {
460 if db.is_null() || name.is_null() || len.is_null() {
461 return ERRNO_NULLPTR;
462 }
463
464 let db_struct = match OhCloudExtDatabase::get_inner_ref(db, SafetyCheckId::Database) {
465 None => return ERRNO_WRONG_TYPE,
466 Some(v) => v,
467 };
468 *name = db_struct.name.as_ptr() as *const c_uchar;
469 *len = db_struct.name.len() as c_uint;
470 ERRNO_SUCCESS
471 }
472
473 /// Get alias from a Database pointer.
474 #[no_mangle]
OhCloudExtDatabaseGetAlias( db: *const OhCloudExtDatabase, alias: *mut *const c_uchar, len: *mut c_uint, ) -> c_int475 pub unsafe extern "C" fn OhCloudExtDatabaseGetAlias(
476 db: *const OhCloudExtDatabase,
477 alias: *mut *const c_uchar,
478 len: *mut c_uint,
479 ) -> c_int {
480 if db.is_null() || alias.is_null() || len.is_null() {
481 return ERRNO_NULLPTR;
482 }
483
484 let db_struct = match OhCloudExtDatabase::get_inner_ref(db, SafetyCheckId::Database) {
485 None => return ERRNO_WRONG_TYPE,
486 Some(v) => v,
487 };
488 *alias = db_struct.alias.as_ptr() as *const c_uchar;
489 *len = db_struct.alias.len() as c_uint;
490 ERRNO_SUCCESS
491 }
492
493 /// Get hashmap of tables from a Database pointer. Parameter `tables` will be updated
494 /// to hold the output HashMap, and it should be freed by `HashMapFree`.
495 #[no_mangle]
OhCloudExtDatabaseGetTable( db: *const OhCloudExtDatabase, tables: *mut *const OhCloudExtHashMap, ) -> c_int496 pub unsafe extern "C" fn OhCloudExtDatabaseGetTable(
497 db: *const OhCloudExtDatabase,
498 tables: *mut *const OhCloudExtHashMap,
499 ) -> c_int {
500 if db.is_null() || tables.is_null() {
501 return ERRNO_NULLPTR;
502 }
503
504 let db_struct = match OhCloudExtDatabase::get_inner_ref(db, SafetyCheckId::Database) {
505 None => return ERRNO_WRONG_TYPE,
506 Some(v) => v,
507 };
508 let tb_hashmap = HashMapCffi::Table(db_struct.tables.clone());
509 *tables = OhCloudExtHashMap::new(tb_hashmap, SafetyCheckId::HashMap).into_ptr()
510 as *const OhCloudExtHashMap;
511 ERRNO_SUCCESS
512 }
513
514 /// Free a Database pointer.
515 #[no_mangle]
OhCloudExtDatabaseFree(src: *mut OhCloudExtDatabase)516 pub unsafe extern "C" fn OhCloudExtDatabaseFree(src: *mut OhCloudExtDatabase) {
517 let _ = OhCloudExtDatabase::from_ptr(src, SafetyCheckId::Database);
518 }
519
520 /// Create a Table instance by table name, table alias, and vector of fields. Fields can be created
521 /// by basic_rust_types::Vector, and its type should be Vec<Field>. When passed in, fields don't
522 /// need to be freed again, because their management will be transferred to Table instance.
523 #[no_mangle]
OhCloudExtTableNew( name: *const c_uchar, name_len: c_uint, alias: *const c_uchar, alias_len: c_uint, fields: *mut OhCloudExtVector, ) -> *mut OhCloudExtTable524 pub unsafe extern "C" fn OhCloudExtTableNew(
525 name: *const c_uchar,
526 name_len: c_uint,
527 alias: *const c_uchar,
528 alias_len: c_uint,
529 fields: *mut OhCloudExtVector,
530 ) -> *mut OhCloudExtTable {
531 let name = char_ptr_to_string(name, name_len);
532 let alias = char_ptr_to_string(alias, alias_len);
533
534 if fields.is_null() {
535 let f = vec![];
536 let tb = types::Table::new(name, alias, f);
537 OhCloudExtTable::new(tb, SafetyCheckId::Table).into_ptr() as *mut OhCloudExtTable
538 } else {
539 let fields = match OhCloudExtVector::get_inner(fields, SafetyCheckId::Vector) {
540 None => return null_mut(),
541 Some(v) => v,
542 };
543 match fields {
544 VectorCffi::Field(f) => {
545 let tb = types::Table::new(name, alias, f);
546 OhCloudExtTable::new(tb, SafetyCheckId::Table).into_ptr()
547 }
548 _ => null_mut(),
549 }
550 }
551 }
552
553 /// Get name from a Table pointer.
554 #[no_mangle]
OhCloudExtTableGetName( tb: *const OhCloudExtTable, name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int555 pub unsafe extern "C" fn OhCloudExtTableGetName(
556 tb: *const OhCloudExtTable,
557 name: *mut *const c_uchar,
558 len: *mut c_uint,
559 ) -> c_int {
560 if tb.is_null() || name.is_null() || len.is_null() {
561 return ERRNO_NULLPTR;
562 }
563
564 let tb_struct = match OhCloudExtTable::get_inner_ref(tb, SafetyCheckId::Table) {
565 None => return ERRNO_WRONG_TYPE,
566 Some(v) => v,
567 };
568 *name = tb_struct.name.as_ptr() as *const c_uchar;
569 *len = tb_struct.name.len() as c_uint;
570 ERRNO_SUCCESS
571 }
572
573 /// Get alias from a Table pointer.
574 #[no_mangle]
OhCloudExtTableGetAlias( tb: *const OhCloudExtTable, alias: *mut *const c_uchar, len: *mut c_uint, ) -> c_int575 pub unsafe extern "C" fn OhCloudExtTableGetAlias(
576 tb: *const OhCloudExtTable,
577 alias: *mut *const c_uchar,
578 len: *mut c_uint,
579 ) -> c_int {
580 if tb.is_null() || alias.is_null() || len.is_null() {
581 return ERRNO_NULLPTR;
582 }
583
584 let tb_struct = match OhCloudExtTable::get_inner_ref(tb, SafetyCheckId::Table) {
585 None => return ERRNO_WRONG_TYPE,
586 Some(v) => v,
587 };
588 *alias = tb_struct.alias.as_ptr() as *const c_uchar;
589 *len = tb_struct.alias.len() as c_uint;
590 ERRNO_SUCCESS
591 }
592
593 /// Get vector of fields from a Table pointer. Parameter `fields` be updated
594 /// to hold the output Vector, and it should be freed by `VectorFree`.
595 #[no_mangle]
OhCloudExtTableGetFields( tb: *const OhCloudExtTable, fields: *mut *const OhCloudExtVector, ) -> c_int596 pub unsafe extern "C" fn OhCloudExtTableGetFields(
597 tb: *const OhCloudExtTable,
598 fields: *mut *const OhCloudExtVector,
599 ) -> c_int {
600 if tb.is_null() || fields.is_null() {
601 return ERRNO_NULLPTR;
602 }
603
604 let tb_struct = match OhCloudExtTable::get_inner_ref(tb, SafetyCheckId::Table) {
605 None => return ERRNO_WRONG_TYPE,
606 Some(v) => v,
607 };
608 let vec = VectorCffi::Field(tb_struct.fields.clone());
609 *fields = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr();
610 ERRNO_SUCCESS
611 }
612
613 /// Free a Table pointer.
614 #[no_mangle]
OhCloudExtTableFree(src: *mut OhCloudExtTable)615 pub unsafe extern "C" fn OhCloudExtTableFree(src: *mut OhCloudExtTable) {
616 let _ = OhCloudExtTable::from_ptr(src, SafetyCheckId::Table);
617 }
618
619 #[inline]
c_bool_to_bool(src: u8) -> bool620 fn c_bool_to_bool(src: u8) -> bool {
621 src != 0
622 }
623
624 /// FieldBuilder providing necessary information when create a Field.
625 #[repr(C)]
626 pub struct OhCloudExtFieldBuilder {
627 col_name: *const c_uchar,
628 col_name_len: c_uint,
629 alias: *const c_uchar,
630 alias_len: c_uint,
631 typ: c_uint,
632 primary: u8,
633 nullable: u8,
634 }
635
636 /// Create a Field by column name, alias, type, primary, and nullable.
637 #[no_mangle]
OhCloudExtFieldNew( builder: *const OhCloudExtFieldBuilder, ) -> *mut OhCloudExtField638 pub unsafe extern "C" fn OhCloudExtFieldNew(
639 builder: *const OhCloudExtFieldBuilder,
640 ) -> *mut OhCloudExtField {
641 if builder.is_null() {
642 return null_mut();
643 }
644 let builder = &*builder;
645 let col_name = char_ptr_to_string(builder.col_name, builder.col_name_len);
646 let alias = char_ptr_to_string(builder.alias, builder.alias_len);
647 let typ = builder.typ as u8;
648 let primary = c_bool_to_bool(builder.primary);
649 let nullable = c_bool_to_bool(builder.nullable);
650 let fd = types::Field::new(col_name, alias, typ, primary, nullable);
651 OhCloudExtField::new(fd, SafetyCheckId::Field).into_ptr()
652 }
653
654 /// Get column name from a Field pointer.
655 #[no_mangle]
OhCloudExtFieldGetColName( fd: *const OhCloudExtField, name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int656 pub unsafe extern "C" fn OhCloudExtFieldGetColName(
657 fd: *const OhCloudExtField,
658 name: *mut *const c_uchar,
659 len: *mut c_uint,
660 ) -> c_int {
661 if fd.is_null() || name.is_null() || len.is_null() {
662 return ERRNO_NULLPTR;
663 }
664
665 let fd_struct = match OhCloudExtField::get_inner_ref(fd, SafetyCheckId::Field) {
666 None => return ERRNO_WRONG_TYPE,
667 Some(v) => v,
668 };
669 *name = fd_struct.col_name.as_ptr() as *const c_uchar;
670 *len = fd_struct.col_name.len() as c_uint;
671 ERRNO_SUCCESS
672 }
673
674 /// Get alias from a Field pointer.
675 #[no_mangle]
OhCloudExtFieldGetAlias( fd: *const OhCloudExtField, alias: *mut *const c_uchar, len: *mut c_uint, ) -> c_int676 pub unsafe extern "C" fn OhCloudExtFieldGetAlias(
677 fd: *const OhCloudExtField,
678 alias: *mut *const c_uchar,
679 len: *mut c_uint,
680 ) -> c_int {
681 if fd.is_null() || alias.is_null() || len.is_null() {
682 return ERRNO_NULLPTR;
683 }
684
685 let fd_struct = match OhCloudExtField::get_inner_ref(fd, SafetyCheckId::Field) {
686 None => return ERRNO_WRONG_TYPE,
687 Some(v) => v,
688 };
689 *alias = fd_struct.alias.as_ptr() as *const c_uchar;
690 *len = fd_struct.alias.len() as c_uint;
691 ERRNO_SUCCESS
692 }
693
694 /// Get type from a Field pointer.
695 #[no_mangle]
OhCloudExtFieldGetTyp( fd: *const OhCloudExtField, typ: *mut c_uint, ) -> c_int696 pub unsafe extern "C" fn OhCloudExtFieldGetTyp(
697 fd: *const OhCloudExtField,
698 typ: *mut c_uint,
699 ) -> c_int {
700 if fd.is_null() || typ.is_null() {
701 return ERRNO_NULLPTR;
702 }
703
704 let fd_struct = match OhCloudExtField::get_inner_ref(fd, SafetyCheckId::Field) {
705 None => return ERRNO_WRONG_TYPE,
706 Some(v) => v,
707 };
708 *typ = fd_struct.typ as c_uint;
709 ERRNO_SUCCESS
710 }
711
712 /// Check whether the Field is primary.
713 #[no_mangle]
OhCloudExtFieldGetPrimary( fd: *const OhCloudExtField, primary: *mut u8, ) -> c_int714 pub unsafe extern "C" fn OhCloudExtFieldGetPrimary(
715 fd: *const OhCloudExtField,
716 primary: *mut u8,
717 ) -> c_int {
718 if fd.is_null() || primary.is_null() {
719 return ERRNO_NULLPTR;
720 }
721
722 let fd_struct = match OhCloudExtField::get_inner_ref(fd, SafetyCheckId::Field) {
723 None => return ERRNO_WRONG_TYPE,
724 Some(v) => v,
725 };
726 *primary = fd_struct.primary as u8;
727 ERRNO_SUCCESS
728 }
729
730 /// Check whether the Field is nullable.
731 #[no_mangle]
OhCloudExtFieldGetNullable( fd: *const OhCloudExtField, nullable: *mut u8, ) -> c_int732 pub unsafe extern "C" fn OhCloudExtFieldGetNullable(
733 fd: *const OhCloudExtField,
734 nullable: *mut u8,
735 ) -> c_int {
736 if fd.is_null() || nullable.is_null() {
737 return ERRNO_NULLPTR;
738 }
739
740 let fd_struct = match OhCloudExtField::get_inner_ref(fd, SafetyCheckId::Field) {
741 None => return ERRNO_WRONG_TYPE,
742 Some(v) => v,
743 };
744 *nullable = fd_struct.nullable as u8;
745 ERRNO_SUCCESS
746 }
747
748 /// Free a Field pointer.
749 #[no_mangle]
OhCloudExtFieldFree(src: *mut OhCloudExtField)750 pub unsafe extern "C" fn OhCloudExtFieldFree(src: *mut OhCloudExtField) {
751 let _ = OhCloudExtField::from_ptr(src, SafetyCheckId::Field);
752 }
753
754 /// Get user from a CloudInfo pointer.
755 #[no_mangle]
OhCloudExtCloudInfoGetUser( info: *const OhCloudExtCloudInfo, user: *mut c_int, ) -> c_int756 pub unsafe extern "C" fn OhCloudExtCloudInfoGetUser(
757 info: *const OhCloudExtCloudInfo,
758 user: *mut c_int,
759 ) -> c_int {
760 if info.is_null() || user.is_null() {
761 return ERRNO_NULLPTR;
762 }
763
764 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
765 None => return ERRNO_WRONG_TYPE,
766 Some(v) => v,
767 };
768 *user = info_struct.user;
769 ERRNO_SUCCESS
770 }
771
772 /// Get id from a CloudInfo pointer.
773 #[no_mangle]
OhCloudExtCloudInfoGetId( info: *const OhCloudExtCloudInfo, id: *mut *const c_uchar, id_len: *mut c_uint, ) -> c_int774 pub unsafe extern "C" fn OhCloudExtCloudInfoGetId(
775 info: *const OhCloudExtCloudInfo,
776 id: *mut *const c_uchar,
777 id_len: *mut c_uint,
778 ) -> c_int {
779 if info.is_null() || id.is_null() || id_len.is_null() {
780 return ERRNO_NULLPTR;
781 }
782
783 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
784 None => return ERRNO_WRONG_TYPE,
785 Some(v) => v,
786 };
787 *id = info_struct.id.as_ptr() as *const c_uchar;
788 *id_len = info_struct.id.len() as c_uint;
789 ERRNO_SUCCESS
790 }
791
792 /// Get total space from a CloudInfo pointer.
793 #[no_mangle]
OhCloudExtCloudInfoGetTotalSpace( info: *const OhCloudExtCloudInfo, total_space: *mut c_ulonglong, ) -> c_int794 pub unsafe extern "C" fn OhCloudExtCloudInfoGetTotalSpace(
795 info: *const OhCloudExtCloudInfo,
796 total_space: *mut c_ulonglong,
797 ) -> c_int {
798 if info.is_null() || total_space.is_null() {
799 return ERRNO_NULLPTR;
800 }
801
802 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
803 None => return ERRNO_WRONG_TYPE,
804 Some(v) => v,
805 };
806 *total_space = info_struct.total_space as c_ulonglong;
807 ERRNO_SUCCESS
808 }
809
810 /// Get remain space from a CloudInfo pointer.
811 #[no_mangle]
OhCloudExtCloudInfoGetRemainSpace( info: *const OhCloudExtCloudInfo, remain_space: *mut c_ulonglong, ) -> c_int812 pub unsafe extern "C" fn OhCloudExtCloudInfoGetRemainSpace(
813 info: *const OhCloudExtCloudInfo,
814 remain_space: *mut c_ulonglong,
815 ) -> c_int {
816 if info.is_null() || remain_space.is_null() {
817 return ERRNO_NULLPTR;
818 }
819
820 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
821 None => return ERRNO_WRONG_TYPE,
822 Some(v) => v,
823 };
824 *remain_space = info_struct.remain_space as c_ulonglong;
825 ERRNO_SUCCESS
826 }
827
828 /// Check whether a CloudInfo enables cloud sync.
829 #[no_mangle]
OhCloudExtCloudInfoEnabled( info: *const OhCloudExtCloudInfo, enable: *mut u8, ) -> c_int830 pub unsafe extern "C" fn OhCloudExtCloudInfoEnabled(
831 info: *const OhCloudExtCloudInfo,
832 enable: *mut u8,
833 ) -> c_int {
834 if info.is_null() || enable.is_null() {
835 return ERRNO_NULLPTR;
836 }
837
838 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
839 None => return ERRNO_WRONG_TYPE,
840 Some(v) => v,
841 };
842 *enable = info_struct.enable_cloud as u8;
843 ERRNO_SUCCESS
844 }
845
846 /// Get hashmap of AppInfo from a CloudInfo pointer. Parameter `app_info` will be updated
847 /// to hold the output HashMap, and it should be freed by `HashMapFree`.
848 #[no_mangle]
OhCloudExtCloudInfoGetAppInfo( info: *const OhCloudExtCloudInfo, app_info: *mut *const OhCloudExtHashMap, ) -> c_int849 pub unsafe extern "C" fn OhCloudExtCloudInfoGetAppInfo(
850 info: *const OhCloudExtCloudInfo,
851 app_info: *mut *const OhCloudExtHashMap,
852 ) -> c_int {
853 if info.is_null() || app_info.is_null() {
854 return ERRNO_NULLPTR;
855 }
856
857 let info_struct = match OhCloudExtCloudInfo::get_inner_ref(info, SafetyCheckId::CloudInfo) {
858 None => return ERRNO_WRONG_TYPE,
859 Some(v) => v,
860 };
861 let apps = HashMapCffi::AppInfo(info_struct.apps.clone());
862 *app_info = OhCloudExtHashMap::new(apps, SafetyCheckId::HashMap).into_ptr();
863 ERRNO_SUCCESS
864 }
865
866 /// Free a CloudInfo pointer.
867 #[no_mangle]
OhCloudExtCloudInfoFree(info: *mut OhCloudExtCloudInfo)868 pub unsafe extern "C" fn OhCloudExtCloudInfoFree(info: *mut OhCloudExtCloudInfo) {
869 let _ = OhCloudExtCloudInfo::from_ptr(info, SafetyCheckId::CloudInfo);
870 }
871
872 /// Get app id from an AppInfo pointer.
873 #[no_mangle]
OhCloudExtAppInfoGetAppId( info: *const OhCloudExtAppInfo, id: *mut *const c_uchar, id_len: *mut c_uint, ) -> c_int874 pub unsafe extern "C" fn OhCloudExtAppInfoGetAppId(
875 info: *const OhCloudExtAppInfo,
876 id: *mut *const c_uchar,
877 id_len: *mut c_uint,
878 ) -> c_int {
879 if info.is_null() || id.is_null() || id_len.is_null() {
880 return ERRNO_NULLPTR;
881 }
882
883 let info_struct = match OhCloudExtAppInfo::get_inner_ref(info, SafetyCheckId::AppInfo) {
884 None => return ERRNO_WRONG_TYPE,
885 Some(v) => v,
886 };
887 *id = info_struct.app_id.as_ptr() as *const c_uchar;
888 *id_len = info_struct.app_id.len() as c_uint;
889 ERRNO_SUCCESS
890 }
891
892 /// Get bundle name from an AppInfo pointer.
893 #[no_mangle]
OhCloudExtAppInfoGetBundleName( info: *const OhCloudExtAppInfo, id: *mut *const c_uchar, id_len: *mut c_uint, ) -> c_int894 pub unsafe extern "C" fn OhCloudExtAppInfoGetBundleName(
895 info: *const OhCloudExtAppInfo,
896 id: *mut *const c_uchar,
897 id_len: *mut c_uint,
898 ) -> c_int {
899 if info.is_null() || id.is_null() || id_len.is_null() {
900 return ERRNO_NULLPTR;
901 }
902
903 let info_struct = match OhCloudExtAppInfo::get_inner_ref(info, SafetyCheckId::AppInfo) {
904 None => return ERRNO_WRONG_TYPE,
905 Some(v) => v,
906 };
907 *id = info_struct.bundle_name.as_ptr() as *const c_uchar;
908 *id_len = info_struct.bundle_name.len() as c_uint;
909 ERRNO_SUCCESS
910 }
911
912 /// Check whether an AppInfo pointer allows cloud switch.
913 #[no_mangle]
OhCloudExtAppInfoGetCloudSwitch( info: *const OhCloudExtAppInfo, switch: *mut u8, ) -> c_int914 pub unsafe extern "C" fn OhCloudExtAppInfoGetCloudSwitch(
915 info: *const OhCloudExtAppInfo,
916 switch: *mut u8,
917 ) -> c_int {
918 if info.is_null() || switch.is_null() {
919 return ERRNO_NULLPTR;
920 }
921
922 let info_struct = match OhCloudExtAppInfo::get_inner_ref(info, SafetyCheckId::AppInfo) {
923 None => return ERRNO_WRONG_TYPE,
924 Some(v) => v,
925 };
926 *switch = info_struct.cloud_switch as u8;
927 ERRNO_SUCCESS
928 }
929
930 /// Get instance id from an AppInfo pointer.
931 #[no_mangle]
OhCloudExtAppInfoGetInstanceId( info: *const OhCloudExtAppInfo, id: *mut c_int, ) -> c_int932 pub unsafe extern "C" fn OhCloudExtAppInfoGetInstanceId(
933 info: *const OhCloudExtAppInfo,
934 id: *mut c_int,
935 ) -> c_int {
936 if info.is_null() || id.is_null() {
937 return ERRNO_NULLPTR;
938 }
939
940 let info_struct = match OhCloudExtAppInfo::get_inner_ref(info, SafetyCheckId::AppInfo) {
941 None => return ERRNO_WRONG_TYPE,
942 Some(v) => v,
943 };
944 *id = info_struct.instance_id;
945 ERRNO_SUCCESS
946 }
947
948 /// Free a AppInfo ptr.
949 #[no_mangle]
OhCloudExtAppInfoFree(info: *mut OhCloudExtAppInfo)950 pub unsafe extern "C" fn OhCloudExtAppInfoFree(info: *mut OhCloudExtAppInfo) {
951 let _ = OhCloudExtAppInfo::from_ptr(info, SafetyCheckId::AppInfo);
952 }
953
954 /// Get version from a SchemaMeta pointer.
955 #[no_mangle]
OhCloudExtSchemaMetaGetVersion( schema: *mut OhCloudExtSchemaMeta, version: *mut c_int, ) -> c_int956 pub unsafe extern "C" fn OhCloudExtSchemaMetaGetVersion(
957 schema: *mut OhCloudExtSchemaMeta,
958 version: *mut c_int,
959 ) -> c_int {
960 if schema.is_null() || version.is_null() {
961 return ERRNO_NULLPTR;
962 }
963
964 let schema_struct = match OhCloudExtSchemaMeta::get_inner_ref(schema, SafetyCheckId::SchemaMeta)
965 {
966 None => return ERRNO_WRONG_TYPE,
967 Some(v) => v,
968 };
969 *version = schema_struct.version();
970 ERRNO_SUCCESS
971 }
972
973 /// Get bundle name from a SchemaMeta pointer.
974 #[no_mangle]
OhCloudExtSchemaMetaGetBundleName( schema: *mut OhCloudExtSchemaMeta, name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int975 pub unsafe extern "C" fn OhCloudExtSchemaMetaGetBundleName(
976 schema: *mut OhCloudExtSchemaMeta,
977 name: *mut *const c_uchar,
978 len: *mut c_uint,
979 ) -> c_int {
980 if schema.is_null() || name.is_null() || len.is_null() {
981 return ERRNO_NULLPTR;
982 }
983
984 let schema_struct = match OhCloudExtSchemaMeta::get_inner_ref(schema, SafetyCheckId::SchemaMeta)
985 {
986 None => return ERRNO_WRONG_TYPE,
987 Some(v) => v,
988 };
989 *name = schema_struct.bundle_name().as_ptr() as *const c_uchar;
990 *len = schema_struct.bundle_name().len() as c_uint;
991 ERRNO_SUCCESS
992 }
993
994 /// Get a vector of databases from a SchemaMeta pointer. Parameter `dbs` be updated
995 /// to hold the output Vector, and it should be freed by `VectorFree`.
996 #[no_mangle]
OhCloudExtSchemaMetaGetDatabases( schema: *mut OhCloudExtSchemaMeta, dbs: *mut *const OhCloudExtVector, ) -> c_int997 pub unsafe extern "C" fn OhCloudExtSchemaMetaGetDatabases(
998 schema: *mut OhCloudExtSchemaMeta,
999 dbs: *mut *const OhCloudExtVector,
1000 ) -> c_int {
1001 if schema.is_null() || dbs.is_null() {
1002 return ERRNO_NULLPTR;
1003 }
1004
1005 let schema_struct = match OhCloudExtSchemaMeta::get_inner_ref(schema, SafetyCheckId::SchemaMeta)
1006 {
1007 None => return ERRNO_WRONG_TYPE,
1008 Some(v) => v,
1009 };
1010 let databases = schema_struct.databases();
1011 let vec = VectorCffi::Database(databases.to_vec());
1012 *dbs = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr();
1013 ERRNO_SUCCESS
1014 }
1015
1016 /// Free a SchemaMeta pointer.
1017 #[no_mangle]
OhCloudExtSchemaMetaFree(schema: *mut OhCloudExtSchemaMeta)1018 pub unsafe extern "C" fn OhCloudExtSchemaMetaFree(schema: *mut OhCloudExtSchemaMeta) {
1019 let _ = OhCloudExtSchemaMeta::from_ptr(schema, SafetyCheckId::SchemaMeta);
1020 }
1021
1022 /// Create a RelationSet instance by bundle name, and relations. Relations can be created by
1023 /// basic_rust_types::HashMap, and its type should be HashMap<String, (u32, u32)>. When passed in,
1024 /// tables don't need to be freed again, because their management will be transferred to RelationSet
1025 /// instance.
1026 #[no_mangle]
OhCloudExtRelationSetNew( bundle_name: *const c_uchar, len: c_uint, expire_time: c_longlong, relations: *mut OhCloudExtHashMap, ) -> *mut OhCloudExtRelationSet1027 pub unsafe extern "C" fn OhCloudExtRelationSetNew(
1028 bundle_name: *const c_uchar,
1029 len: c_uint,
1030 expire_time: c_longlong,
1031 relations: *mut OhCloudExtHashMap,
1032 ) -> *mut OhCloudExtRelationSet {
1033 let name = char_ptr_to_string(bundle_name, len);
1034
1035 if relations.is_null() {
1036 let re = HashMap::default();
1037 let relation = cloud_service::RelationSet::new(name, expire_time, re);
1038 OhCloudExtRelationSet::new(relation, SafetyCheckId::RelationSet).into_ptr()
1039 } else {
1040 let relations = match OhCloudExtHashMap::get_inner(relations, SafetyCheckId::HashMap) {
1041 None => return null_mut(),
1042 Some(v) => v,
1043 };
1044 match relations {
1045 HashMapCffi::String(re) => {
1046 let relation = cloud_service::RelationSet::new(name, expire_time, re);
1047 OhCloudExtRelationSet::new(relation, SafetyCheckId::RelationSet).into_ptr()
1048 }
1049 _ => null_mut(),
1050 }
1051 }
1052 }
1053
1054 /// Get bundle name from a RelationSet pointer.
1055 #[no_mangle]
OhCloudExtRelationSetGetBundleName( relation: *mut OhCloudExtRelationSet, bundle_name: *mut *const c_uchar, len: *mut c_uint, ) -> c_int1056 pub unsafe extern "C" fn OhCloudExtRelationSetGetBundleName(
1057 relation: *mut OhCloudExtRelationSet,
1058 bundle_name: *mut *const c_uchar,
1059 len: *mut c_uint,
1060 ) -> c_int {
1061 if relation.is_null() || bundle_name.is_null() || len.is_null() {
1062 return ERRNO_NULLPTR;
1063 }
1064
1065 let relation_struct =
1066 match OhCloudExtRelationSet::get_inner_ref(relation, SafetyCheckId::RelationSet) {
1067 None => return ERRNO_WRONG_TYPE,
1068 Some(v) => v,
1069 };
1070 *bundle_name = relation_struct.bundle_name.as_ptr() as *const c_uchar;
1071 *len = relation_struct.bundle_name.len() as c_uint;
1072 ERRNO_SUCCESS
1073 }
1074
1075 /// Get expire time from a RelationSet pointer.
1076 #[no_mangle]
OhCloudExtRelationSetGetExpireTime( relation: *mut OhCloudExtRelationSet, expire_time: *mut c_ulonglong, ) -> c_int1077 pub unsafe extern "C" fn OhCloudExtRelationSetGetExpireTime(
1078 relation: *mut OhCloudExtRelationSet,
1079 expire_time: *mut c_ulonglong,
1080 ) -> c_int {
1081 if relation.is_null() || expire_time.is_null() {
1082 return ERRNO_NULLPTR;
1083 }
1084
1085 let relation_struct =
1086 match OhCloudExtRelationSet::get_inner_ref(relation, SafetyCheckId::RelationSet) {
1087 None => return ERRNO_WRONG_TYPE,
1088 Some(v) => v,
1089 };
1090 *expire_time = relation_struct.expire_time as c_ulonglong;
1091 ERRNO_SUCCESS
1092 }
1093
1094 /// Get relations from a RelationSet pointer. Parameter `relations` be updated
1095 /// to hold the output HashMap, and it should be freed by `HashMapFree`.
1096 #[no_mangle]
OhCloudExtRelationSetGetRelations( relation: *mut OhCloudExtRelationSet, relations: *mut *const OhCloudExtHashMap, ) -> c_int1097 pub unsafe extern "C" fn OhCloudExtRelationSetGetRelations(
1098 relation: *mut OhCloudExtRelationSet,
1099 relations: *mut *const OhCloudExtHashMap,
1100 ) -> c_int {
1101 if relation.is_null() || relations.is_null() {
1102 return ERRNO_NULLPTR;
1103 }
1104
1105 let relation_struct =
1106 match OhCloudExtRelationSet::get_inner_ref(relation, SafetyCheckId::RelationSet) {
1107 None => return ERRNO_WRONG_TYPE,
1108 Some(v) => v,
1109 };
1110 let res = relation_struct.relations();
1111 let hashmap = HashMapCffi::String(res.clone());
1112 *relations = OhCloudExtHashMap::new(hashmap, SafetyCheckId::HashMap).into_ptr();
1113 ERRNO_SUCCESS
1114 }
1115
1116 /// Free a RelationSet pointer.
1117 #[no_mangle]
OhCloudExtRelationSetFree(re: *mut OhCloudExtRelationSet)1118 pub unsafe extern "C" fn OhCloudExtRelationSetFree(re: *mut OhCloudExtRelationSet) {
1119 let _ = OhCloudExtRelationSet::from_ptr(re, SafetyCheckId::RelationSet);
1120 }
1121
1122 /// Get the next cursor from a CloudDbData pointer.
1123 #[no_mangle]
OhCloudExtCloudDbDataGetNextCursor( data: *mut OhCloudExtCloudDbData, cursor: *mut *const c_uchar, len: *mut c_uint, ) -> c_int1124 pub unsafe extern "C" fn OhCloudExtCloudDbDataGetNextCursor(
1125 data: *mut OhCloudExtCloudDbData,
1126 cursor: *mut *const c_uchar,
1127 len: *mut c_uint,
1128 ) -> c_int {
1129 if data.is_null() || cursor.is_null() || len.is_null() {
1130 return ERRNO_NULLPTR;
1131 }
1132
1133 let data_struct = match OhCloudExtCloudDbData::get_inner_ref(data, SafetyCheckId::CloudDbData) {
1134 None => return ERRNO_WRONG_TYPE,
1135 Some(v) => v,
1136 };
1137 *cursor = data_struct.next_cursor.as_ptr() as *const c_uchar;
1138 *len = data_struct.next_cursor.len() as c_uint;
1139 ERRNO_SUCCESS
1140 }
1141
1142 /// Check whether a CloudDbData has more data.
1143 #[no_mangle]
OhCloudExtCloudDbDataGetHasMore( data: *mut OhCloudExtCloudDbData, has_more: *mut u8, ) -> c_int1144 pub unsafe extern "C" fn OhCloudExtCloudDbDataGetHasMore(
1145 data: *mut OhCloudExtCloudDbData,
1146 has_more: *mut u8,
1147 ) -> c_int {
1148 if data.is_null() || has_more.is_null() {
1149 return ERRNO_NULLPTR;
1150 }
1151
1152 let data_struct = match OhCloudExtCloudDbData::get_inner_ref(data, SafetyCheckId::CloudDbData) {
1153 None => return ERRNO_WRONG_TYPE,
1154 Some(v) => v,
1155 };
1156 *has_more = data_struct.has_more as u8;
1157 ERRNO_SUCCESS
1158 }
1159
1160 /// Get vector of values from a CloudDbData pointer. Parameter `values` will be updated
1161 /// to hold the output Vec<ValueBucket>, and it should be freed by `VectorFree`.
1162 #[no_mangle]
OhCloudExtCloudDbDataGetValues( data: *mut OhCloudExtCloudDbData, values: *mut *const OhCloudExtVector, ) -> c_int1163 pub unsafe extern "C" fn OhCloudExtCloudDbDataGetValues(
1164 data: *mut OhCloudExtCloudDbData,
1165 values: *mut *const OhCloudExtVector,
1166 ) -> c_int {
1167 if data.is_null() || values.is_null() {
1168 return ERRNO_NULLPTR;
1169 }
1170
1171 let data_struct = match OhCloudExtCloudDbData::get_inner_ref(data, SafetyCheckId::CloudDbData) {
1172 None => return ERRNO_WRONG_TYPE,
1173 Some(v) => v,
1174 };
1175 let vec = VectorCffi::ValueBucket(data_struct.values.clone());
1176 *values = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr();
1177 ERRNO_SUCCESS
1178 }
1179
1180 /// Free a CloudDbData pointer.
1181 #[no_mangle]
OhCloudExtCloudDbDataFree(src: *mut OhCloudExtCloudDbData)1182 pub unsafe extern "C" fn OhCloudExtCloudDbDataFree(src: *mut OhCloudExtCloudDbData) {
1183 let _ = OhCloudExtCloudDbData::from_ptr(src, SafetyCheckId::CloudDbData);
1184 }
1185
1186 #[repr(C)]
1187 pub struct OhCloudExtKeyName {
1188 key: *const c_uchar,
1189 key_len: c_uint,
1190 }
1191
1192 #[no_mangle]
OhCloudExtKeyNameNew(key: *const c_uchar, key_len: c_uint) -> OhCloudExtKeyName1193 pub unsafe extern "C" fn OhCloudExtKeyNameNew(key: *const c_uchar, key_len: c_uint) -> OhCloudExtKeyName {
1194 let key_name = OhCloudExtKeyName { key, key_len };
1195 key_name
1196 }
1197
1198 /// Get keys from a ValueBucket pointer.
1199 #[no_mangle]
OhCloudExtValueBucketGetKeys( vb: *mut OhCloudExtValueBucket, keys: *mut *const OhCloudExtVector, keys_len: *mut c_uint, ) -> c_int1200 pub unsafe extern "C" fn OhCloudExtValueBucketGetKeys(
1201 vb: *mut OhCloudExtValueBucket,
1202 keys: *mut *const OhCloudExtVector,
1203 keys_len: *mut c_uint,
1204 ) -> c_int {
1205 if vb.is_null() || keys.is_null() || keys_len.is_null() {
1206 return ERRNO_NULLPTR;
1207 }
1208
1209 let vb_struct = match OhCloudExtValueBucket::get_inner_ref(vb, SafetyCheckId::ValueBucket) {
1210 None => return ERRNO_WRONG_TYPE,
1211 Some(v) => v,
1212 };
1213
1214 let keys_vec = vb_struct.0.clone().into_keys().collect::<Vec<String>>();
1215 *keys_len = keys_vec.len() as c_uint;
1216 let vec = VectorCffi::String(keys_vec);
1217 *keys = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr();
1218 ERRNO_SUCCESS
1219 }
1220
1221 /// Gets Value from a ValueBucket pointer.
1222 #[no_mangle]
OhCloudExtValueBucketGetValue( vb: *mut OhCloudExtValueBucket, key_name: OhCloudExtKeyName, typ: *mut OhCloudExtValueType, content: *mut *const c_void, len: *mut c_uint, ) -> c_int1223 pub unsafe extern "C" fn OhCloudExtValueBucketGetValue(
1224 vb: *mut OhCloudExtValueBucket,
1225 key_name: OhCloudExtKeyName,
1226 typ: *mut OhCloudExtValueType,
1227 content: *mut *const c_void,
1228 len: *mut c_uint,
1229 ) -> c_int {
1230 let key = key_name.key;
1231 let key_len = key_name.key_len;
1232
1233 if vb.is_null() || key.is_null() || typ.is_null() || content.is_null() || len.is_null() {
1234 return ERRNO_NULLPTR;
1235 }
1236
1237 let name = char_ptr_to_string(key, key_len);
1238
1239 let vb_struct = match OhCloudExtValueBucket::get_inner_ref(vb, SafetyCheckId::ValueBucket) {
1240 None => return ERRNO_WRONG_TYPE,
1241 Some(v) => v,
1242 };
1243
1244 let value_struct = match vb_struct.0.get(&name) {
1245 None => return ERRNO_INVALID_KEY,
1246 Some(v) => v,
1247 };
1248
1249 match value_struct {
1250 ipc_conn::FieldRaw::Null => {
1251 *typ = OhCloudExtValueType::EMPTY;
1252 *content = null();
1253 *len = 0;
1254 }
1255 ipc_conn::FieldRaw::Number(i) => {
1256 *typ = OhCloudExtValueType::INT;
1257 *content = i as *const i64 as *const c_void;
1258 }
1259 ipc_conn::FieldRaw::Real(f) => {
1260 *typ = OhCloudExtValueType::FLOAT;
1261 *content = f as *const f64 as *const c_void;
1262 }
1263 ipc_conn::FieldRaw::Text(s) => {
1264 *typ = OhCloudExtValueType::STRING;
1265 *content = s.as_ptr() as *const c_void;
1266 *len = s.len() as c_uint;
1267 }
1268 ipc_conn::FieldRaw::Bool(b) => {
1269 *typ = OhCloudExtValueType::BOOL;
1270 *content = b as *const bool as *const c_void;
1271 }
1272 ipc_conn::FieldRaw::Blob(b) => {
1273 *typ = OhCloudExtValueType::BYTES;
1274 *content = b.as_ptr() as *const c_void;
1275 *len = b.len() as c_uint;
1276 }
1277 ipc_conn::FieldRaw::Asset(a) => {
1278 *typ = OhCloudExtValueType::ASSET;
1279 *content = OhCloudExtCloudAsset::new(a.clone(), SafetyCheckId::CloudAsset).into_ptr()
1280 as *mut c_void;
1281 }
1282 ipc_conn::FieldRaw::Assets(a) => {
1283 *typ = OhCloudExtValueType::ASSETS;
1284 let vec = VectorCffi::CloudAsset(a.0.to_vec());
1285 *content = OhCloudExtVector::new(vec, SafetyCheckId::Vector).into_ptr() as *mut c_void;
1286 *len = a.0.len() as c_uint;
1287 }
1288 }
1289
1290 ERRNO_SUCCESS
1291 }
1292
1293 /// Free a ValueBucket ptr.
1294 #[no_mangle]
OhCloudExtValueBucketFree(info: *mut OhCloudExtValueBucket)1295 pub unsafe extern "C" fn OhCloudExtValueBucketFree(info: *mut OhCloudExtValueBucket) {
1296 let _ = OhCloudExtValueBucket::from_ptr(info, SafetyCheckId::ValueBucket);
1297 }
1298
1299 #[cfg(test)]
1300 mod test {
1301 use crate::c_adapter::basic_rust_types::{
1302 OhCloudExtHashMap, OhCloudExtRustType, OhCloudExtVector, OhCloudExtVectorNew,
1303 OhCloudExtVectorPush,
1304 };
1305 use crate::c_adapter::cloud_ext_types::*;
1306
1307 /// UT test for Value creation and destruction.
1308 ///
1309 /// # Title
1310 /// ut_value_int
1311 ///
1312 /// # Brief
1313 /// 1. Create a Value::Int.
1314 /// 2. Get values from it.
1315 /// 3. Free the value ptr.
1316 /// 4. No error and memory leak should happen.
1317 #[test]
ut_value_int()1318 fn ut_value_int() {
1319 unsafe {
1320 let mut src = 1_i64;
1321 let value = OhCloudExtValueNew(
1322 OhCloudExtValueType::INT,
1323 &mut src as *mut _ as *mut c_void,
1324 0,
1325 );
1326 assert!(!value.is_null());
1327
1328 let mut typ = OhCloudExtValueType::EMPTY;
1329 let mut val: *mut c_uint = null_mut();
1330 let mut length = 1 as c_uint;
1331 assert_eq!(
1332 OhCloudExtValueGetContent(
1333 value,
1334 &mut typ as *mut OhCloudExtValueType,
1335 &mut val as *mut _ as *mut *const c_void,
1336 &mut length as *mut _ as *mut c_uint
1337 ),
1338 ERRNO_SUCCESS
1339 );
1340 assert_eq!(*val as i64, src);
1341 assert_eq!(typ, OhCloudExtValueType::INT);
1342 OhCloudExtValueFree(value);
1343 }
1344 }
1345
get_asset_ptr() -> *mut OhCloudExtCloudAsset1346 unsafe fn get_asset_ptr() -> *mut OhCloudExtCloudAsset {
1347 let temp = "temp";
1348 let mut builder = OhCloudExtCloudAssetBuilder {
1349 version: 0,
1350 status: asset_loader::AssetStatus::Normal,
1351 expires_time: 0,
1352 id: temp.as_ptr() as *const c_uchar,
1353 id_len: 4,
1354 name: temp.as_ptr() as *const c_uchar,
1355 name_len: 4,
1356 uri: temp.as_ptr() as *const c_uchar,
1357 uri_len: 4,
1358 local_path: temp.as_ptr() as *const c_uchar,
1359 local_path_len: 4,
1360 create_time: temp.as_ptr() as *const c_uchar,
1361 create_time_len: 4,
1362 modify_time: temp.as_ptr() as *const c_uchar,
1363 modify_time_len: 4,
1364 size: temp.as_ptr() as *const c_uchar,
1365 size_len: 4,
1366 hash: temp.as_ptr() as *const c_uchar,
1367 hash_len: 4,
1368 };
1369 let asset = OhCloudExtCloudAssetNew(&mut builder as *mut OhCloudExtCloudAssetBuilder);
1370 assert!(!asset.is_null());
1371 asset
1372 }
1373
1374 /// UT test for Value creation and destruction.
1375 ///
1376 /// # Title
1377 /// ut_value_asset
1378 ///
1379 /// # Brief
1380 /// 1. Create a Value::Asset.
1381 /// 2. Get values from it.
1382 /// 3. Free the value ptr.
1383 /// 4. No error and memory leak should happen.
1384 #[test]
ut_value_asset()1385 fn ut_value_asset() {
1386 unsafe {
1387 let asset = get_asset_ptr();
1388 let value = OhCloudExtValueNew(OhCloudExtValueType::ASSET, asset as *mut c_void, 0);
1389 assert!(!value.is_null());
1390
1391 let mut typ = OhCloudExtValueType::EMPTY;
1392 let mut val: *mut OhCloudExtCloudAsset = null_mut();
1393 let mut length = 1 as c_uint;
1394 assert_eq!(
1395 OhCloudExtValueGetContent(
1396 value,
1397 &mut typ as *mut OhCloudExtValueType,
1398 &mut val as *mut _ as *mut *const c_void,
1399 &mut length as *mut _ as *mut c_uint
1400 ),
1401 ERRNO_SUCCESS
1402 );
1403 assert!(!val.is_null());
1404 assert_eq!(typ, OhCloudExtValueType::ASSET);
1405 OhCloudExtValueFree(value);
1406 }
1407 }
1408
1409 /// UT test for Value creation and destruction.
1410 ///
1411 /// # Title
1412 /// ut_value_assets
1413 ///
1414 /// # Brief
1415 /// 1. Create a Value::Assets.
1416 /// 2. Get values from it.
1417 /// 3. Free the value ptr.
1418 /// 4. No error and memory leak should happen.
1419 #[test]
ut_value_assets()1420 fn ut_value_assets() {
1421 unsafe {
1422 let asset = get_asset_ptr();
1423 let vec = OhCloudExtVectorNew(OhCloudExtRustType::CLOUD_ASSET);
1424 assert!(!vec.is_null());
1425 assert_eq!(
1426 OhCloudExtVectorPush(vec, asset as *mut c_void, 0),
1427 ERRNO_SUCCESS
1428 );
1429 let value = OhCloudExtValueNew(OhCloudExtValueType::ASSETS, vec as *mut c_void, 0);
1430 assert!(!value.is_null());
1431
1432 let mut typ = OhCloudExtValueType::EMPTY;
1433 let mut val: *mut OhCloudExtCloudAsset = null_mut();
1434 let mut length = 1 as c_uint;
1435 assert_eq!(
1436 OhCloudExtValueGetContent(
1437 value,
1438 &mut typ as *mut OhCloudExtValueType,
1439 &mut val as *mut _ as *mut *const c_void,
1440 &mut length as *mut _ as *mut c_uint
1441 ),
1442 ERRNO_SUCCESS
1443 );
1444 assert!(!val.is_null());
1445 assert_eq!(typ, OhCloudExtValueType::ASSETS);
1446 let assets_struct =
1447 OhCloudExtVector::get_inner(val as *mut OhCloudExtVector, SafetyCheckId::Vector)
1448 .unwrap();
1449 match assets_struct {
1450 VectorCffi::CloudAsset(v) => {
1451 assert_eq!(v.len(), 1);
1452 }
1453 _ => panic!("Value typ mismatches with Assets"),
1454 }
1455 OhCloudExtValueFree(value);
1456 }
1457 }
1458
1459 /// UT test for Database creation and destruction.
1460 ///
1461 /// # Title
1462 /// ut_database
1463 ///
1464 /// # Brief
1465 /// 1. Create a Database.
1466 /// 2. Get tables and name from it.
1467 /// 3. Free the Database ptr.
1468 /// 4. No error and memory leak should happen.
1469 #[test]
ut_database()1470 fn ut_database() {
1471 unsafe {
1472 let temp = "temp";
1473 let db = OhCloudExtDatabaseNew(
1474 temp.as_ptr() as *const c_uchar,
1475 temp.len() as c_uint,
1476 null_mut(),
1477 0,
1478 null_mut(),
1479 );
1480 assert!(!db.is_null());
1481 let mut name: *mut c_uchar = null_mut();
1482 let mut length = 1 as c_uint;
1483 assert_eq!(
1484 OhCloudExtDatabaseGetAlias(
1485 db,
1486 &mut name as *mut _ as *mut *const c_uchar,
1487 &mut length as *mut _ as *mut c_uint
1488 ),
1489 ERRNO_SUCCESS
1490 );
1491 let id = &*slice_from_raw_parts(name as *const u8, length as usize);
1492 assert!(id.is_empty());
1493 assert_eq!(length, 0);
1494 let mut map: *mut OhCloudExtHashMap = null_mut();
1495 assert_eq!(
1496 OhCloudExtDatabaseGetTable(db, &mut map as *mut _ as *mut *const OhCloudExtHashMap),
1497 ERRNO_SUCCESS
1498 );
1499 assert!(!map.is_null());
1500 let map_struct = OhCloudExtHashMap::get_inner(map, SafetyCheckId::HashMap).unwrap();
1501 match map_struct {
1502 HashMapCffi::Table(h) => {
1503 assert!(h.is_empty());
1504 }
1505 _ => panic!("Db Table Map mismatches with Table"),
1506 }
1507 OhCloudExtDatabaseFree(db);
1508 }
1509 }
1510
1511 /// UT test for Table creation and destruction.
1512 ///
1513 /// # Title
1514 /// ut_table
1515 ///
1516 /// # Brief
1517 /// 1. Create a Table.
1518 /// 2. Get fields and table name from it.
1519 /// 3. Free the Table ptr.
1520 /// 4. No error and memory leak should happen.
1521 #[test]
ut_table()1522 fn ut_table() {
1523 unsafe {
1524 let temp = "temp";
1525 let tb = OhCloudExtTableNew(
1526 temp.as_ptr() as *const c_uchar,
1527 temp.len() as c_uint,
1528 null_mut(),
1529 0,
1530 null_mut(),
1531 );
1532 assert!(!tb.is_null());
1533 let mut name: *mut c_uchar = null_mut();
1534 let mut length = 1 as c_uint;
1535 assert_eq!(
1536 OhCloudExtTableGetName(
1537 tb,
1538 &mut name as *mut _ as *mut *const c_uchar,
1539 &mut length as *mut _ as *mut c_uint
1540 ),
1541 ERRNO_SUCCESS
1542 );
1543 let tb_name = &*slice_from_raw_parts(name as *const u8, length as usize);
1544 assert_eq!(tb_name, temp.as_bytes());
1545 assert_eq!(length as usize, temp.len());
1546 let mut vec: *mut OhCloudExtVector = null_mut();
1547 assert_eq!(
1548 OhCloudExtTableGetFields(tb, &mut vec as *mut _ as *mut *const OhCloudExtVector),
1549 ERRNO_SUCCESS
1550 );
1551 assert!(!vec.is_null());
1552 let vec_struct = OhCloudExtVector::get_inner(vec, SafetyCheckId::Vector).unwrap();
1553 match vec_struct {
1554 VectorCffi::Field(f) => {
1555 assert!(f.is_empty());
1556 }
1557 _ => panic!("Table fields mismatches with Vec<Field>"),
1558 }
1559 OhCloudExtTableFree(tb);
1560 }
1561 }
1562
1563 /// UT test for Field creation and destruction.
1564 ///
1565 /// # Title
1566 /// ut_field
1567 ///
1568 /// # Brief
1569 /// 1. Create a Field.
1570 /// 2. Get name from it.
1571 /// 3. Free the Field ptr.
1572 /// 4. No error and memory leak should happen.
1573 #[test]
ut_field()1574 fn ut_field() {
1575 unsafe {
1576 let temp = "temp";
1577 let fd = OhCloudExtFieldNew(null_mut());
1578 assert!(fd.is_null());
1579 let builder = OhCloudExtFieldBuilder {
1580 col_name: temp.as_ptr() as *const c_uchar,
1581 col_name_len: temp.len() as c_uint,
1582 alias: temp.as_ptr() as *const c_uchar,
1583 alias_len: temp.len() as c_uint,
1584 typ: 0,
1585 primary: 0,
1586 nullable: 0,
1587 };
1588 let fd = OhCloudExtFieldNew(&builder as *const OhCloudExtFieldBuilder);
1589 assert!(!fd.is_null());
1590
1591 let mut name: *mut c_uchar = null_mut();
1592 let mut length = 1 as c_uint;
1593 assert_eq!(
1594 OhCloudExtFieldGetAlias(
1595 fd,
1596 &mut name as *mut _ as *mut *const c_uchar,
1597 &mut length as *mut _ as *mut c_uint
1598 ),
1599 ERRNO_SUCCESS
1600 );
1601 let fd_alias = &*slice_from_raw_parts(name as *const u8, length as usize);
1602 assert_eq!(fd_alias, temp.as_bytes());
1603 assert_eq!(length as usize, temp.len());
1604 let mut bool = true;
1605 assert_eq!(
1606 OhCloudExtFieldGetNullable(fd, &mut bool as *mut _ as *mut u8),
1607 ERRNO_SUCCESS
1608 );
1609 assert!(!bool);
1610 OhCloudExtFieldFree(fd);
1611 }
1612 }
1613
1614 /// UT test for RelationSet creation and destruction.
1615 ///
1616 /// # Title
1617 /// ut_relation_set
1618 ///
1619 /// # Brief
1620 /// 1. Create a RelationSet.
1621 /// 2. Get name from it.
1622 /// 3. Free the RelationSet ptr.
1623 /// 4. No error and memory leak should happen.
1624 #[test]
ut_relation_set()1625 fn ut_relation_set() {
1626 unsafe {
1627 let temp = "temp";
1628 let set = OhCloudExtRelationSetNew(
1629 temp.as_ptr() as *const c_uchar,
1630 temp.len() as c_uint,
1631 64,
1632 null_mut(),
1633 );
1634 assert!(!set.is_null());
1635
1636 let mut name: *mut c_uchar = null_mut();
1637 let mut length = 1 as c_uint;
1638 assert_eq!(
1639 OhCloudExtRelationSetGetBundleName(
1640 set,
1641 &mut name as *mut _ as *mut *const c_uchar,
1642 &mut length as *mut _ as *mut c_uint
1643 ),
1644 ERRNO_SUCCESS
1645 );
1646 let bundle_name = &*slice_from_raw_parts(name as *const u8, length as usize);
1647 assert_eq!(bundle_name, temp.as_bytes());
1648 assert_eq!(length as usize, temp.len());
1649 OhCloudExtRelationSetFree(set);
1650 }
1651 }
1652 }
1653