BuildRequires: rust-glib-sys
BuildRequires: rust-mockall
BuildRequires: rust-mockall_double
-BuildRequires: zip
%if 0%{?gcov:1}
BuildRequires: lcov
+BuildRequires: zip
%endif
%description
GTest for tizen-shared-queue
#################################################
-# rust-tizen-base
+# rust-tizen-bundle
+#################################################
+%package -n rust-tizen-bundle
+Summary: Bundle Library for Tizen rust applications
+Group: Development/Libraries
+
+%description -n rust-tizen-bundle
+Bundle Library for Tizen rust applications
+
+#################################################
+# rust-tizen-parcel
#################################################
-%package -n rust-tizen-base
-Summary: Library for Tizen rust applications
+%package -n rust-tizen-parcel
+Summary: Parcel Library for Tizen rust applications
Group: Development/Libraries
-%description -n rust-tizen-base
-Libraries for Tizen rust applications
+%description -n rust-tizen-parcel
+parcel Library for Tizen rust applications
%prep
%setup -q -n %{name}-%{version}
cp %{SOURCE1001} .
cp %{SOURCE1002} .
-cp %{SOURCE1001} ./rust-tizen-base.manifest
+cp %{SOURCE1001} ./rust-tizen-bundle.manifest
+cp %{SOURCE1001} ./rust-tizen-parcel.manifest
%build
%if 0%{?gcov:1}
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%cmake -DFULLVER=%{version} \
-DMAJORVER=${MAJORVER} \
- -DRUST_LIBDIR=%{_rust_libdir} \
- -DRUST_DYLIBDIR=%{_rust_dylibdir} \
- -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \
.
%__make %{?_smp_mflags}
%{rustc_std_build} --crate-type=dylib \
- --crate-name=tizen_base \
- -L native="./src/parcel" \
+ --crate-name=tizen_bundle \
-L native="./src/bundle" \
%{?rustc_edition:--edition=%{rustc_edition}} \
%rust_dylib_extern libc \
- src/rust-tizen-base/src/lib.rs
+ src/rust-tizen-bundle/src/lib.rs
%{rustc_std_build} --test --crate-type=bin \
- --crate-name=tizen_base_unittests \
- -L native="./src/parcel" \
+ --crate-name=tizen_bundle_unittests \
-L native="./src/bundle" \
%{?rustc_edition:--edition=%{rustc_edition}} \
%rust_dylib_extern libc \
%rust_dylib_extern mockall \
%rust_dylib_extern mockall_double \
- src/rust-tizen-base/src/lib.rs
+ src/rust-tizen-bundle/src/lib.rs
+
+%{rustc_std_build} --crate-type=dylib \
+ --crate-name=tizen_parcel \
+ -L native="./src/parcel" \
+ %{?rustc_edition:--edition=%{rustc_edition}} \
+ %rust_dylib_extern libc \
+ src/rust-tizen-parcel/src/lib.rs
+
+%{rustc_std_build} --test --crate-type=bin \
+ --crate-name=tizen_parcel_unittests \
+ -L native="./src/parcel" \
+ %{?rustc_edition:--edition=%{rustc_edition}} \
+ %rust_dylib_extern libc \
+ %rust_dylib_extern mockall \
+ %rust_dylib_extern mockall_double \
+ src/rust-tizen-parcel/src/lib.rs
%check
export LD_LIBRARY_PATH="../../src/bundle:../../src/parcel"
ctest --verbose %{?_smp_mflags}
-export LD_LIBRARY_PATH="%{_rust_dylibdir}:./src/parcel:./src/bundle"
-RUST_BACKTRACE=1 RUST_TEST_THREADS=1 ./tizen_base_unittests
+export LD_LIBRARY_PATH="%{_rust_dylibdir}:./src/bundle"
+RUST_BACKTRACE=1 RUST_TEST_THREADS=1 ./tizen_bundle_unittests
+
+export LD_LIBRARY_PATH="%{_rust_dylibdir}:./src/parcel:"
+RUST_BACKTRACE=1 RUST_TEST_THREADS=1 ./tizen_parcel_unittests
%if 0%{?gcov:1}
lcov -c --ignore-errors mismatch,graph,unused --no-external -b . -d . -o %{name}.info
sed -i -e 's/<NAME>/tizen-shared-queue/g' %{buildroot}%{_bindir}/tizen-unittests/tizen-shared-queue/run-unittest.sh
install -d -m 0755 %{buildroot}%{_rust_dylibdir}
-install -m 0644 libtizen_base.so %{buildroot}/%{_rust_dylibdir}/libtizen_base.so
-strip -s -N .rustc %{buildroot}/%{_rust_dylibdir}/libtizen_base.so
+install -m 0644 libtizen_bundle.so %{buildroot}/%{_rust_dylibdir}/libtizen_bundle.so
+strip -s -N .rustc %{buildroot}/%{_rust_dylibdir}/libtizen_bundle.so
+
+install -m 0644 libtizen_parcel.so %{buildroot}/%{_rust_dylibdir}/libtizen_parcel.so
+strip -s -N .rustc %{buildroot}/%{_rust_dylibdir}/libtizen_parcel.so
%post -p /sbin/ldconfig
%{_bindir}/bundle_unittests
%endif
-%post -n rust-tizen-base
+%post -n rust-tizen-bundle
/sbin/ldconfig
-unzip %{_rust_dylibdir}/libtizen_base.zip -d %{_rust_dylibdir}/
-rm %{_rust_dylibdir}/libtizen_base.zip
+%postun -n rust-tizen-bundle
+/sbin/ldconfig
+
+%post -n rust-tizen-parcel
+/sbin/ldconfig
-%postun -n rust-tizen-base
+%postun -n rust-tizen-parcel
/sbin/ldconfig
%files
%{_bindir}/tizen-unittests/tizen-shared-queue/run-unittest.sh
#################################################
-# rust-tizen-base
+# rust-tizen-bundle
+#################################################
+%files -n rust-tizen-bundle
+%manifest rust-tizen-bundle.manifest
+%license LICENSE
+%{_rust_dylibdir}/libtizen_bundle.so
+
+#################################################
+# rust-tizen-parcel
#################################################
-%files -n rust-tizen-base
-%manifest rust-tizen-base.manifest
+%files -n rust-tizen-parcel
+%manifest rust-tizen-parcel.manifest
%license LICENSE
-%{_rust_dylibdir}/libtizen_base.so
+%{_rust_dylibdir}/libtizen_parcel.so
+++ /dev/null
-[package]
-name = "rust-tizen-base"
-version = "0.1.0"
-edition = "2021"
-
-[lib]
-crate-type = [ "dylib" ]
-crate-name = [ "tizen_base" ]
+++ /dev/null
-extern crate libc;
-
-use self::libc::{EINVAL, ENOKEY, ENOMEM};
-use std::collections::VecDeque;
-use std::ffi::{c_char, c_int, c_uchar, c_uint, c_void, CStr, CString};
-use std::ptr;
-
-const TIZEN_ERROR_BUNDLE: i32 = -0x01180000;
-const BUNDLE_ERROR_NONE: i32 = 0;
-const BUNDLE_ERROR_OUT_OF_MEMORY: i32 = -ENOMEM;
-const BUNDLE_ERROR_INVALID_PARAMETER: i32 = -EINVAL;
-const BUNDLE_ERROR_KEY_NOT_AVAILABLE: i32 = -ENOKEY;
-const BUNDLE_ERROR_KEY_EXISTS: i32 = TIZEN_ERROR_BUNDLE | 0x01;
-const BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS: i32 = TIZEN_ERROR_BUNDLE | 0x02;
-
-const BUNDLE_TYPE_ARRAY: i32 = 0x0100;
-const BUNDLE_TYPE_MEASURABLE: i32 = 0x0400;
-const BUNDLE_TYPE_NONE: i32 = -1;
-const BUNDLE_TYPE_ANY: i32 = 0;
-const BUNDLE_TYPE_STR: i32 = 1 | BUNDLE_TYPE_MEASURABLE;
-const BUNDLE_TYPE_STR_ARRAY: i32 = BUNDLE_TYPE_STR | BUNDLE_TYPE_ARRAY | BUNDLE_TYPE_MEASURABLE;
-const BUNDLE_TYPE_BYTE: i32 = 2;
-const BUNDLE_TYPE_BYTE_ARRAY: i32 = BUNDLE_TYPE_BYTE | BUNDLE_TYPE_ARRAY;
-
-#[link(name = "bundle")]
-extern "C" {
- fn bundle_create() -> *mut c_void;
- fn bundle_free(b: *mut c_void) -> c_int;
- fn bundle_add_str_array(
- b: *mut c_void,
- key: *const c_char,
- array: *const *const c_char,
- len: c_int,
- ) -> c_int;
- fn bundle_del(b: *mut c_void, key: *const c_char) -> c_int;
- fn bundle_get_str_array(
- b: *mut c_void,
- key: *const c_char,
- len: *mut c_int,
- ) -> *const *const c_char;
- fn bundle_get_count(b: *mut c_void) -> c_int;
- fn bundle_get_type(b: *mut c_void, key: *const c_char) -> c_int;
- fn bundle_dup(b: *mut c_void) -> *mut c_void;
- fn bundle_foreach(
- b: *mut c_void,
- callback: extern "C" fn(*const c_char, c_int, *const c_void, *mut c_void),
- user_data: *mut c_void,
- ) -> c_int;
- fn bundle_encode(b: *mut c_void, r: *mut *mut c_char, len: *mut c_int) -> c_int;
- fn bundle_decode(r: *const c_char, len: c_int) -> *mut c_void;
- fn bundle_add_str(b: *mut c_void, key: *const c_char, value: *const c_char) -> c_int;
- fn bundle_add_byte(
- b: *mut c_void,
- key: *const c_char,
- bytes: *const c_uchar,
- size: c_uint,
- ) -> c_int;
- fn bundle_get_str(b: *mut c_void, key: *const c_char, val: *mut *mut c_char) -> c_int;
- fn bundle_get_byte(
- b: *mut c_void,
- key: *const c_char,
- bytes: *mut *mut c_void,
- size: *mut c_uint,
- ) -> c_int;
- fn bundle_add_byte_array(b: *mut c_void, key: *const c_char, len: c_uint) -> c_int;
- fn bundle_set_byte_array_element(
- b: *mut c_void,
- key: *const c_char,
- idx: c_uint,
- bytes: *const c_void,
- size: c_uint,
- ) -> c_int;
- fn bundle_get_byte_array(
- b: *mut c_void,
- key: *const c_char,
- byte_array: *mut *mut *mut c_void,
- len: *mut c_uint,
- array_element_size: *mut *mut c_uint,
- ) -> c_int;
- fn bundle_keyval_get_basic_val(
- kv: *mut c_void,
- val: *mut *mut c_void,
- size: *mut c_uint,
- ) -> c_int;
- fn bundle_keyval_get_array_val(
- kv: *mut c_void,
- array_val: *mut *mut *mut c_void,
- array_len: *mut c_uint,
- array_element_size: *mut *mut c_uint,
- ) -> c_int;
-}
-
-#[link(name = "capi-base-common")]
-extern "C" {
- fn get_last_result() -> c_int;
-}
-
-/// Represents a value of a bundle.
-#[derive(Debug)]
-pub enum BundleValue {
- /// A string value.
- String(String),
- /// A vector of strings.
- StringVector(Vec<String>),
- /// A byte vector.
- Bytes(Vec<u8>),
- /// A vector of byte vectors.
- BytesVector(Vec<Vec<u8>>),
-}
-
-/// Represents an error that can occur when working with a `Bundle`.
-#[derive(Debug, PartialEq)]
-pub enum BundleError {
- /// Out of memory.
- /// There is not enough memory to complete the operation. This error occurs when the memory allocation fails.
- OutOfMemory,
- /// Invalid parameter.
- /// The input parameter is invalid. This error occurs when the input parameter is out of range.
- InvalidParameter,
- /// Key not available.
- /// The key does not exist in the bundle. This error occurs when you try to get a value with a non-existent key.
- KeyNotAvailable,
- /// Key exists.
- /// The key already exists in the bundle. This error occurs when you try to add a key that already exists.
- KeyExists,
- /// The index is out of bounds of the array.
- ArrayIndexOutOfBounds,
- /// No ownership.
- /// The bundle does not own the data. This error occurs when you try to detach the data that was not allocated by the bundle.
- NoOwnership,
-}
-
-impl BundleError {
- fn from_c_int(result: c_int) -> BundleError {
- match result {
- BUNDLE_ERROR_OUT_OF_MEMORY => BundleError::OutOfMemory,
- BUNDLE_ERROR_INVALID_PARAMETER => BundleError::InvalidParameter,
- BUNDLE_ERROR_KEY_NOT_AVAILABLE => BundleError::KeyNotAvailable,
- BUNDLE_ERROR_KEY_EXISTS => BundleError::KeyExists,
- BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS => BundleError::ArrayIndexOutOfBounds,
- _ => panic!("Unexpected error code {}", result),
- }
- }
-}
-
-/// Represents a type of a bundle key.
-#[derive(Debug, PartialEq)]
-pub enum BundleType {
- /// None.
- None,
- /// Any type.
- Any,
- /// A string type.
- String,
- /// A vector of strings.
- StringVector,
- /// Bytes type.
- Bytes,
- /// A vector of bytes.
- BytesVector,
-}
-
-impl BundleType {
- fn from_c_int(key_type: c_int) -> BundleType {
- match key_type {
- BUNDLE_TYPE_NONE => BundleType::None,
- BUNDLE_TYPE_ANY => BundleType::Any,
- BUNDLE_TYPE_STR => BundleType::String,
- BUNDLE_TYPE_STR_ARRAY => BundleType::StringVector,
- BUNDLE_TYPE_BYTE => BundleType::Bytes,
- BUNDLE_TYPE_BYTE_ARRAY => BundleType::BytesVector,
- _ => panic!("Unexpected type code: {}", key_type),
- }
- }
-}
-
-/// A representation of a Bundle, which is a key-value pair container.
-#[derive(Debug)]
-pub struct Bundle {
- handle: *mut c_void,
- ownership: bool,
-}
-
-impl Clone for Bundle {
- fn clone(&self) -> Self {
- let handle = unsafe { bundle_dup(self.handle) };
- Self { handle, ownership: true }
- }
-}
-
-impl Drop for Bundle {
- fn drop(&mut self) {
- if self.ownership && !self.handle.is_null() {
- unsafe {
- bundle_free(self.handle);
- }
- }
- }
-}
-
-impl Default for Bundle {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl Bundle {
- /// Creates a new `Bundle` instance.
- ///
- /// # Panics
- ///
- /// This function will panic if the creation of a `Bundle` fails.
- pub fn new() -> Self {
- let handle = unsafe { bundle_create() };
- if handle.is_null() {
- panic!("Failed to create bundle");
- }
- Self { handle, ownership: true }
- }
-
- /// Creates a new `Bundle` instance from a raw handle.
- ///
- /// # Arguments
- ///
- /// * `b`: The raw handle to the bundle.
- /// * `ownership`: Whether or not the `Bundle` should take ownership of the raw handle. If `false`, the caller retains ownership and the `Bundle` will not free the handle when it is dropped.
- ///
- /// # Panics
- ///
- /// This function panics if the provided handle is null.
- pub fn from_raw_handle(b: *mut c_void, ownership: bool) -> Self {
- if b.is_null() {
- panic!("Bundle pointer is null");
- }
- Self { handle: b, ownership }
- }
-
- /// Gets a raw handle from the `Bundle`.
- ///
- /// # Returns
- ///
- /// A raw handle of the `Bundle`.
- pub fn get_raw_handle(&self) -> *mut c_void {
- self.handle
- }
-
- /// Detaches the raw handle from the `Bundle` and returns it.
- ///
- /// # Returns
- ///
- /// Returns `Ok(*mut c_void)` on success, or an appropriate `Err(BundleError)` on failure.
- /// If the `Bundle` does not own the raw handle, this function returns `Err(BundleError)`. Otherwise,
- pub fn detach(&mut self) -> Result<*mut c_void, BundleError> {
- if self.ownership {
- let handle = self.handle;
- self.handle = std::ptr::null_mut();
- self.ownership = false;
- Ok(handle)
- } else {
- Err(BundleError::NoOwnership)
- }
- }
-
- /// Deletes a value associated with the given key.
- ///
- /// # Arguements
- ///
- /// * `key` - The key to be deleted. It must be a valid UTF-8 string. If not, this function will return an error.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failrue.
- pub fn delete(&mut self, key: &str) -> Result<(), BundleError> {
- let c_key = CString::new(key).unwrap();
- let result = unsafe { bundle_del(self.handle, c_key.as_ptr()) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Gets the number of elements in the `Bundle`.
- ///
- /// # Returns
- ///
- /// The number of elements.
- pub fn count(&self) -> i32 {
- (unsafe { bundle_get_count(self.handle) }) as i32
- }
-
- /// Adds a string to the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key of the element.
- /// * `value` - The value of the element. This must be a valid UTF-8 encoded string.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn add_str(&mut self, key: &str, value: &str) -> Result<(), BundleError> {
- let c_key = CString::new(key).unwrap();
- let c_value = CString::new(value).unwrap();
- let result = unsafe { bundle_add_str(self.handle, c_key.as_ptr(), c_value.as_ptr()) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Gets a string with the given key from the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key to retrieve the value for.
- ///
- /// # Returns
- ///
- /// Returns `Ok(String)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn get_str(&self, key: &str) -> Result<String, BundleError> {
- let c_key = CString::new(key).unwrap();
- let mut c_val: *mut c_char = ptr::null_mut();
- let result = unsafe { bundle_get_str(self.handle, c_key.as_ptr(), &mut c_val) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- let c_str = unsafe { CStr::from_ptr(c_val) };
- Ok(c_str.to_string_lossy().into_owned())
- }
- }
-
- /// Adds a vector of strings to the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key of the element.
- /// * `value` - The vector of strings.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn add_str_vec(&mut self, key: &str, values: &[&str]) -> Result<(), BundleError> {
- let c_key = CString::new(key).unwrap();
- let c_array: Vec<CString> = values.iter().map(|&s| CString::new(s).unwrap()).collect();
- let c_ptr_array: Vec<*const c_char> = c_array.iter().map(|s| s.as_ptr()).collect();
- let result = unsafe {
- bundle_add_str_array(
- self.handle,
- c_key.as_ptr(),
- c_ptr_array.as_ptr(),
- c_array.len() as c_int,
- )
- };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Gets a vector of strings with the given key from the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key to retrieve the value for.
- ///
- /// # Returns
- ///
- /// Returns `Ok(Vec<String>)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn get_str_vec(&self, key: &str) -> Result<Vec<String>, BundleError> {
- let c_key = CString::new(key).unwrap();
- let mut len: c_int = 0;
- let c_array_ptr = unsafe { bundle_get_str_array(self.handle, c_key.as_ptr(), &mut len) };
- if c_array_ptr.is_null() {
- return Err(BundleError::from_c_int(unsafe { get_last_result() }));
- }
-
- let mut result = Vec::with_capacity(len as usize);
- for i in 0..len {
- let c_str_ptr = unsafe { *c_array_ptr.add(i as usize) };
- let c_str = unsafe { CStr::from_ptr(c_str_ptr) };
- result.push(c_str.to_string_lossy().into_owned());
- }
- Ok(result)
- }
-
- /// Adds bytes to the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key of the element.
- /// * `value` - The bytes of the element.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn add_bytes(&mut self, key: &str, bytes: &[u8]) -> Result<(), BundleError> {
- let c_key = CString::new(key).unwrap();
- let result = unsafe {
- bundle_add_byte(
- self.handle,
- c_key.as_ptr(),
- bytes.as_ptr(),
- bytes.len() as c_uint,
- )
- };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Gets bytes with the given key from the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key to retrieve the value for.
- ///
- /// # Returns
- ///
- /// Returns `Ok(Vec<u8>)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn get_bytes(&self, key: &str) -> Result<Vec<u8>, BundleError> {
- let c_key = CString::new(key).unwrap();
- let mut bytes_ptr: *mut c_void = ptr::null_mut();
- let mut size: c_uint = 0;
- let result =
- unsafe { bundle_get_byte(self.handle, c_key.as_ptr(), &mut bytes_ptr, &mut size) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(unsafe {
- std::slice::from_raw_parts(bytes_ptr as *const u8, size as usize).to_vec()
- })
- }
- }
-
- /// Adds a vector of bytes to the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key of the element.
- /// * `value` - The vector of bytes.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn add_bytes_vec(&mut self, key: &str, elements: &[&[u8]]) -> Result<(), BundleError> {
- let c_key = CString::new(key).unwrap();
- let array_len = elements.len() as c_uint;
- let result = unsafe { bundle_add_byte_array(self.handle, c_key.as_ptr(), array_len) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- for (idx, element) in elements.iter().enumerate() {
- let result = unsafe {
- bundle_set_byte_array_element(
- self.handle,
- c_key.as_ptr(),
- idx as c_uint,
- element.as_ptr() as *const c_void,
- element.len() as c_uint,
- )
- };
- if result != 0 {
- return Err(BundleError::from_c_int(result));
- }
- }
- Ok(())
- }
- }
-
- /// Gets a vector of bytes with the given key from the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key to retrieve the value for.
- ///
- /// # Returns
- ///
- /// Returns `Ok(Vec<Vec<u8>>)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn get_bytes_vec(&self, key: &str) -> Result<Vec<Vec<u8>>, BundleError> {
- let c_key = CString::new(key).unwrap();
- let mut byte_array_ptr: *mut *mut c_void = ptr::null_mut();
- let mut len: c_uint = 0;
- let mut array_element_size: *mut c_uint = ptr::null_mut();
- let result = unsafe {
- bundle_get_byte_array(
- self.handle,
- c_key.as_ptr(),
- &mut byte_array_ptr,
- &mut len,
- &mut array_element_size,
- )
- };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- let byte_array = unsafe { std::slice::from_raw_parts(byte_array_ptr, len as usize) };
- let element_sizes =
- unsafe { std::slice::from_raw_parts(array_element_size, len as usize) };
- let mut bytes = Vec::with_capacity(len as usize);
- for i in 0..len as usize {
- let element_size = element_sizes[i] as usize;
- let element =
- unsafe { std::slice::from_raw_parts(byte_array[i] as *const u8, element_size) };
- bytes.push(element.to_vec());
- }
-
- Ok(bytes)
- }
- }
-
- /// Gets the type of a given key in the `Bundle`.
- ///
- /// # Arguments
- ///
- /// * `key` - The key to retrieve the value type for.
- ///
- /// # Returns
- ///
- /// Returns `Ok(BundleType)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn get_type(&self, key: &str) -> Result<BundleType, BundleError> {
- let c_key = CString::new(key).unwrap();
- let result = unsafe { bundle_get_type(self.handle, c_key.as_ptr()) };
- if result < BUNDLE_TYPE_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(BundleType::from_c_int(result))
- }
- }
-
- /// Encode the bundle to a string.(uses base64 format).
- ///
- /// # Returns
- ///
- /// Returns `Ok(String)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn encode(&self) -> Result<String, BundleError> {
- let mut raw: *mut c_char = std::ptr::null_mut();
- let mut len: c_int = 0;
- let result = unsafe { bundle_encode(self.handle, &mut raw, &mut len) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(unsafe { CStr::from_ptr(raw as *const c_char) }
- .to_string_lossy()
- .into_owned())
- }
- }
-
- /// Creates a new `Bundle` from the given encoded string.
- /// The string must be in the format returned by `encode`. If the string is invalid, an error will be returned.
- ///
- /// # Arguments
- ///
- /// * `raw` - The encoded string to decode. This must be in the format returned by `encode`.
- ///
- /// # Returns
- ///
- /// Returns `Ok(Bundle)` on success, or an appropriate `Err(BundleError)` on failure.
- pub fn decode(raw: &str) -> Result<Bundle, BundleError> {
- let c_raw = CString::new(raw).unwrap();
- let handle = unsafe { bundle_decode(c_raw.as_ptr() as *const c_char, raw.len() as c_int) };
- if handle.is_null() {
- Err(BundleError::from_c_int(unsafe { get_last_result() }))
- } else {
- Ok(Bundle { handle, ownership: true })
- }
- }
-
- /// Iterates over the keys and values of the `Bundle`.
- ///
- /// # Returns
- ///
- /// An iterator over the keys and values of the `Bundle`.
- pub fn iter(&self) -> BundleIter {
- let mut bundle_iter = BundleIter {
- bundle: self,
- items: VecDeque::new(),
- };
- bundle_iter.populate_items();
- bundle_iter
- }
-}
-
-#[derive(Debug)]
-struct KeyInfo {
- key: String,
- key_type: BundleType,
- handle: *mut c_void,
-}
-
-impl KeyInfo {
- fn new(key: &str, key_type: BundleType, handle: *mut c_void) -> Self {
- KeyInfo {
- key: key.to_string(),
- key_type,
- handle,
- }
- }
-
- fn get_str(&self) -> Result<String, BundleError> {
- let mut val: *mut c_void = std::ptr::null_mut();
- let mut size: c_uint = 0;
- let result = unsafe { bundle_keyval_get_basic_val(self.handle, &mut val, &mut size) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(unsafe {
- CStr::from_ptr(val as *const c_char)
- .to_string_lossy()
- .into_owned()
- })
- }
- }
-
- fn get_str_vec(&self) -> Result<Vec<String>, BundleError> {
- let mut array_val: *mut *mut c_void = std::ptr::null_mut();
- let mut array_len: c_uint = 0;
- let mut array_element_size: *mut c_uint = std::ptr::null_mut();
- let result = unsafe {
- bundle_keyval_get_array_val(
- self.handle,
- &mut array_val,
- &mut array_len,
- &mut array_element_size,
- )
- };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- let mut values = Vec::with_capacity(array_len as usize);
- for i in 0..array_len {
- let c_str_ptr = unsafe { *array_val.add(i as usize) };
- let c_str = unsafe { CStr::from_ptr(c_str_ptr as *const c_char) };
- values.push(c_str.to_string_lossy().into_owned());
- }
- Ok(values)
- }
- }
-
- fn get_bytes(&self) -> Result<Vec<u8>, BundleError> {
- let mut val: *mut c_void = std::ptr::null_mut();
- let mut size: c_uint = 0;
- let result = unsafe { bundle_keyval_get_basic_val(self.handle, &mut val, &mut size) };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- Ok(unsafe { std::slice::from_raw_parts(val as *const u8, size as usize).to_vec() })
- }
- }
-
- fn get_bytes_vec(&self) -> Result<Vec<Vec<u8>>, BundleError> {
- let mut array_val: *mut *mut c_void = std::ptr::null_mut();
- let mut array_len: c_uint = 0;
- let mut array_element_size: *mut c_uint = std::ptr::null_mut();
- let result = unsafe {
- bundle_keyval_get_array_val(
- self.handle,
- &mut array_val,
- &mut array_len,
- &mut array_element_size,
- )
- };
- if result != BUNDLE_ERROR_NONE {
- Err(BundleError::from_c_int(result))
- } else {
- let byte_array = unsafe { std::slice::from_raw_parts(array_val, array_len as usize) };
- let element_sizes =
- unsafe { std::slice::from_raw_parts(array_element_size, array_len as usize) };
- let mut bytes_vec = Vec::with_capacity(array_len as usize);
- for i in 0..array_len as usize {
- let element_size = element_sizes[i] as usize;
- let element =
- unsafe { std::slice::from_raw_parts(byte_array[i] as *const u8, element_size) };
- bytes_vec.push(element.to_vec());
- }
- Ok(bytes_vec)
- }
- }
-
- fn get_item(&self) -> Result<(String, BundleValue), BundleError> {
- match self.key_type {
- BundleType::String => {
- let value = self.get_str();
- match value {
- Ok(v) => Ok((self.key.clone(), BundleValue::String(v))),
- Err(err) => Err(err),
- }
- }
- BundleType::StringVector => {
- let value = self.get_str_vec();
- match value {
- Ok(v) => Ok((self.key.clone(), BundleValue::StringVector(v))),
- Err(err) => Err(err),
- }
- }
- BundleType::Bytes => {
- let value = self.get_bytes();
- match value {
- Ok(v) => Ok((self.key.clone(), BundleValue::Bytes(v))),
- Err(err) => Err(err),
- }
- }
- BundleType::BytesVector => {
- let value = self.get_bytes_vec();
- match value {
- Ok(v) => Ok((self.key.clone(), BundleValue::BytesVector(v))),
- Err(err) => Err(err),
- }
- }
- _ => Err(BundleError::KeyNotAvailable),
- }
- }
-}
-
-extern "C" fn foreach_callback(
- key: *const c_char,
- key_type: c_int,
- key_value: *const c_void,
- user_data: *mut c_void,
-) {
- let items: &mut VecDeque<(String, BundleValue)> =
- unsafe { &mut *(user_data as *mut VecDeque<(String, BundleValue)>) };
- let key_str = unsafe { CStr::from_ptr(key).to_str().unwrap().to_string() };
- let key_info = KeyInfo::new(
- &key_str,
- BundleType::from_c_int(key_type),
- key_value as *mut c_void,
- );
- let item = key_info.get_item();
- match item {
- Ok(i) => items.push_back(i),
- Err(err) => println!(
- "Error while creating key info: {:?}, error: {:?}",
- key_info, err
- ),
- }
-}
-
-/// Iterator for Bundle. Iterates over all the keys and values in a bundle.
-pub struct BundleIter<'a> {
- bundle: &'a Bundle,
- items: VecDeque<(String, BundleValue)>,
-}
-
-impl<'a> BundleIter<'a> {
- fn populate_items(&mut self) {
- let user_data: *mut VecDeque<(String, BundleValue)> = &mut self.items;
- unsafe {
- bundle_foreach(
- self.bundle.handle,
- foreach_callback,
- user_data as *mut c_void,
- );
- }
- }
-}
-
-impl<'a> Iterator for BundleIter<'a> {
- type Item = (String, BundleValue);
-
- fn next(&mut self) -> Option<Self::Item> {
- self.items.pop_front()
- }
-}
-
-impl<'a> IntoIterator for &'a Bundle {
- type Item = (String, BundleValue);
- type IntoIter = BundleIter<'a>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl IntoIterator for Bundle {
- type Item = (String, BundleValue);
- type IntoIter = BundleIntoIter;
-
- fn into_iter(self) -> Self::IntoIter {
- let mut iter = BundleIntoIter {
- bundle: self,
- items: VecDeque::new(),
- };
- iter.populate_items();
- iter
- }
-}
-
-/// IntoIterator for Bundle.
-pub struct BundleIntoIter {
- bundle: Bundle,
- items: VecDeque<(String, BundleValue)>,
-}
-
-impl BundleIntoIter {
- fn populate_items(&mut self) {
- let user_data: *mut VecDeque<(String, BundleValue)> = &mut self.items;
- unsafe {
- bundle_foreach(
- self.bundle.handle,
- foreach_callback,
- user_data as *mut c_void,
- );
- }
- }
-}
-
-impl Iterator for BundleIntoIter {
- type Item = (String, BundleValue);
-
- fn next(&mut self) -> Option<Self::Item> {
- self.items.pop_front()
- }
-}
+++ /dev/null
-pub mod parcel;
-pub mod bundle;
-
-pub use crate::parcel::{Parcel};
-pub use crate::bundle::{Bundle};
-
-mod tests;
+++ /dev/null
-extern crate libc;
-
-use self::libc::{EILSEQ, EINVAL, ENODATA, ENOMEM};
-use std::ffi::{
- c_char, c_double, c_float, c_int, c_longlong, c_short, c_uchar, c_uint, c_ulonglong, c_ushort,
- c_void, CString,
-};
-use std::ptr;
-
-const PARCEL_ERROR_NONE: i32 = 0;
-const PARCEL_ERROR_ILLEGAL_BYTE_SEQ: i32 = -EILSEQ;
-const PARCEL_ERROR_INVALID_PARAMETER: i32 = -EINVAL;
-const PARCEL_ERROR_NO_DATA: i32 = -ENODATA;
-const PARCEL_ERROR_OUT_OF_MEMORY: i32 = -ENOMEM;
-
-#[link(name = "parcel")]
-extern "C" {
- fn parcel_create(parcel: *mut *mut c_void) -> c_int;
- fn parcel_destroy(parcel: *mut c_void) -> c_int;
- fn parcel_clone(parcel: *const c_void, clone: *mut *mut c_void) -> c_int;
- fn parcel_burst_write(parcel: *mut c_void, buf: *const c_uchar, size: usize) -> c_int;
- fn parcel_burst_read(parcel: *mut c_void, buf: *mut c_uchar, size: usize) -> c_int;
- fn parcel_write_bool(parcel: *mut c_void, val: c_int) -> c_int;
- fn parcel_write_byte(parcel: *mut c_void, val: c_char) -> c_int;
- fn parcel_write_uint16(parcel: *mut c_void, val: c_ushort) -> c_int;
- fn parcel_write_uint32(parcel: *mut c_void, val: c_uint) -> c_int;
- fn parcel_write_uint64(parcel: *mut c_void, val: c_ulonglong) -> c_int;
- fn parcel_write_int16(parcel: *mut c_void, val: c_short) -> c_int;
- fn parcel_write_int32(parcel: *mut c_void, val: c_int) -> c_int;
- fn parcel_write_int64(parcel: *mut c_void, val: c_longlong) -> c_int;
- fn parcel_write_float(parcle: *mut c_void, val: c_float) -> c_int;
- fn parcel_write_double(parcel: *mut c_void, val: c_double) -> c_int;
- fn parcel_write_string(parcel: *mut c_void, val: *const c_char) -> c_int;
- fn parcel_read_bool(parcel: *mut c_void, val: *mut c_int) -> c_int;
- fn parcel_read_byte(parcel: *mut c_void, val: *mut c_char) -> c_int;
- fn parcel_read_uint16(parcel: *mut c_void, val: *mut c_ushort) -> c_int;
- fn parcel_read_uint32(parcel: *mut c_void, val: *mut c_uint) -> c_int;
- fn parcel_read_uint64(parcel: *mut c_void, val: *mut c_ulonglong) -> c_int;
- fn parcel_read_int16(parcel: *mut c_void, val: *mut c_short) -> c_int;
- fn parcel_read_int32(parcel: *mut c_void, val: *mut c_int) -> c_int;
- fn parcel_read_int64(parcel: *mut c_void, val: *mut c_longlong) -> c_int;
- fn parcel_read_float(parcel: *mut c_void, val: *mut c_float) -> c_int;
- fn parcel_read_double(parcel: *mut c_void, val: *mut c_double) -> c_int;
- fn parcel_read_string(parcel: *mut c_void, val: *mut *mut c_char) -> c_int;
- fn parcel_reset_reader(parcel: *mut c_void) -> c_int;
- fn parcel_clear(parcel: *mut c_void) -> c_int;
- fn parcel_reset(parcel: *mut c_void, buf: *const c_void, size: c_uint) -> c_int;
- fn parcel_get_raw(parcel: *mut c_void, buf: *mut *mut c_void, size: *mut c_uint) -> c_int;
-}
-
-/// Represents errors that can occur when working with a `Parcel`.
-#[derive(Debug, PartialEq)]
-pub enum ParcelError {
- /// Illegal byte sequence.
- /// The data in the parcel is not valid.
- /// This error occurs when the data is not encoded properly or the data is corrupted.
- IllegalByteSeq,
- /// Invalid parameter.
- /// The input parameter is invalid. This error occurs when the input parameter is out of range.
- InvalidParameter,
- /// No data available.
- /// There is no data to read. This error occurs when there is no more data to read from the parcel.
- NoData,
- /// Out of memory.
- /// There is not enough memory to complete the operation. This error occurs when the memory allocation fails.
- OutOfMemory,
-}
-
-impl ParcelError {
- fn from_c_int(result: c_int) -> ParcelError {
- match result {
- PARCEL_ERROR_ILLEGAL_BYTE_SEQ => ParcelError::IllegalByteSeq,
- PARCEL_ERROR_INVALID_PARAMETER => ParcelError::InvalidParameter,
- PARCEL_ERROR_NO_DATA => ParcelError::NoData,
- PARCEL_ERROR_OUT_OF_MEMORY => ParcelError::OutOfMemory,
- _ => panic!("Unexpected error code {}", result),
- }
- }
-}
-
-/// A representation of a Parcel, which is used for serializing and deserializing data.
-#[derive(Debug)]
-pub struct Parcel {
- handle: *mut c_void,
-}
-
-/// A trait that defines how a type can be serialized to and deserialized from a Parcel.
-pub trait Parcelable<T> {
- fn to_parcel(&self) -> Parcel;
- fn from_parcel(parcel: &mut Parcel) -> T;
-}
-
-impl Clone for Parcel {
- fn clone(&self) -> Self {
- let mut clone_handle: *mut c_void = ptr::null_mut();
- unsafe {
- let result = parcel_clone(self.handle, &mut clone_handle);
- assert!(result == PARCEL_ERROR_NONE, "Failed to clone a parcel")
- };
- Self {
- handle: clone_handle,
- }
- }
-}
-
-impl Drop for Parcel {
- fn drop(&mut self) {
- unsafe {
- parcel_destroy(self.handle);
- }
- }
-}
-
-impl Default for Parcel {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl Parcel {
- /// Creates a new `Parcel` instance.
- ///
- /// # Panics
- ///
- /// This function will panic if the creation of a `Parcel` fails.
- pub fn new() -> Self {
- let mut handle: *mut c_void = ptr::null_mut();
- unsafe {
- let result = parcel_create(&mut handle);
- assert!(result == PARCEL_ERROR_NONE, "Failed to create a parcel");
- }
- Self { handle }
- }
-
- /// Writes a byte slice to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `data` - A slice of bytes to be written to the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write(&mut self, data: &[u8]) -> Result<(), ParcelError> {
- let result = unsafe {
- parcel_burst_write(self.handle, data.as_ptr(), data.len())
- };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Reads a byte slice from the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `size` - The number of bytes to read from the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns a `Vec<u8>` containing the data read on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read(&mut self, size: usize) -> Result<Vec<u8>, ParcelError> {
- let mut data = vec![0; size];
- let result = unsafe { parcel_burst_read(self.handle, data.as_mut_ptr(), data.len()) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(data)
- }
- }
-
- /// Gets the raw data from the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns a `Vec<u8>` containing the raw data on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn get_raw_data(&self) -> Result<Vec<u8>, ParcelError> {
- let mut size = 0;
- let mut raw: *mut c_void = ptr::null_mut();
- let result = unsafe { parcel_get_raw(self.handle, &mut raw, &mut size) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- let mut data = vec![0; size as usize];
- unsafe {
- std::ptr::copy(raw as *const u8, data.as_mut_ptr(), size as usize);
- }
- Ok(data)
- }
- }
-
- /// Resets the reader position of the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn reset_reader(&mut self) -> Result<(), ParcelError> {
- let result = unsafe { parcel_reset_reader(self.handle) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Clears the contents of the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn clear(&mut self) -> Result<(), ParcelError> {
- let result = unsafe { parcel_clear(self.handle) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Resets the `Parcel` with the provided data.
- ///
- /// # Arguments
- ///
- /// * `data` - The slice of bytes to reset the `Parcel`.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn reset(&mut self, data: &[u8]) -> Result<(), ParcelError> {
- let result = unsafe {
- parcel_reset(
- self.handle,
- data.as_ptr() as *const c_void,
- data.len() as c_uint,
- )
- };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a boolean value to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The boolean value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_bool(&mut self, val: bool) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_bool(self.handle, val as c_int) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 8-bit integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 8-bit integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_i8(&mut self, val: i8) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_byte(self.handle, val as c_char) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 16-bit integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 16-bit integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_i16(&mut self, val: i16) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_int16(self.handle, val as c_short) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 32-bit integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 32-bit integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_i32(&mut self, val: i32) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_int32(self.handle, val as c_int) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 64-bit integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 64-bit integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_i64(&mut self, val: i64) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_int64(self.handle, val as c_longlong) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 16-bit unsigned integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 16-bit unsigned integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_u16(&mut self, val: u16) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_uint16(self.handle, val as c_ushort) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 32-bit unsigned integer to the `Parcel`.
- ///
- /// # Arguments
- ///
- /// * `val` - The 32-bit unsigned integer value to be written.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_u32(&mut self, val: u32) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_uint32(self.handle, val as c_uint) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 64-bit unsigned integer to the parcel.
- ///
- /// # Arguments
- ///
- /// * `val` - The 64-bit unsigned integer value to write.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_u64(&mut self, val: u64) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_uint64(self.handle, val as c_ulonglong) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 32-bit floating point to the parcel.
- ///
- /// # Arguments
- ///
- /// * `val` - The 32-bit floating point value to write.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_f32(&mut self, val: f32) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_float(self.handle, val) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a 64-bit floating point to the parcel.
- ///
- /// # Arguments
- ///
- /// * `val` - The 64-bit floating point value to write.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_f64(&mut self, val: f64) -> Result<(), ParcelError> {
- let result = unsafe { parcel_write_double(self.handle, val) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Writes a string to the parcel.
- ///
- /// # Arguments
- ///
- /// * `val` - The string value to write.
- ///
- /// # Returns
- ///
- /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn write_string(&mut self, val: &str) -> Result<(), ParcelError> {
- let ptr = CString::new(val).unwrap();
- let result = unsafe { parcel_write_string(self.handle, ptr.as_ptr() as *const c_char) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(())
- }
- }
-
- /// Reads a boolean from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(bool)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_bool(&mut self) -> Result<bool, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_bool(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value != 0)
- }
- }
-
- /// Reads a 8-bit interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(i8)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_i8(&mut self) -> Result<i8, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_byte(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value as i8)
- }
- }
-
- /// Reads a 16-bit interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(i16)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_i16(&mut self) -> Result<i16, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_int16(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 32-bit interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(i32)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_i32(&mut self) -> Result<i32, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_int32(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 64-bit interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(i64)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_i64(&mut self) -> Result<i64, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_int64(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 16-bit unsigned interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(u16)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_u16(&mut self) -> Result<u16, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_uint16(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 32-bit unsigned interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(u32)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_u32(&mut self) -> Result<u32, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_uint32(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 64-bit unsigned interger from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(u64)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_u64(&mut self) -> Result<u64, ParcelError> {
- let mut value = 0;
- let result = unsafe { parcel_read_uint64(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 32-bit floating point from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(f32)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_f32(&mut self) -> Result<f32, ParcelError> {
- let mut value = 0.0;
- let result = unsafe { parcel_read_float(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a 64-bit floating point from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(f64)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_f64(&mut self) -> Result<f64, ParcelError> {
- let mut value = 0.0;
- let result = unsafe { parcel_read_double(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(value)
- }
- }
-
- /// Reads a string from the parcel.
- ///
- /// # Returns
- ///
- /// Returns `Ok(String)` on success, or an appropriate `Err(ParcelError)` on failure.
- pub fn read_string(&mut self) -> Result<String, ParcelError> {
- let mut value: *mut c_char = ptr::null_mut();
- let result = unsafe { parcel_read_string(self.handle, &mut value) };
- if result != PARCEL_ERROR_NONE {
- Err(ParcelError::from_c_int(result))
- } else {
- Ok(unsafe { CString::from_raw(value).into_string().unwrap() })
- }
- }
-}
+++ /dev/null
-use bundle;
-
-#[warn(unused_imports)]
-use bundle::{Bundle, BundleError, BundleType, BundleIter, BundleValue};
-
-#[test]
-fn test_bundle_new_and_get_raw_handle() {
- let b = Bundle::new();
- let native = b.get_raw_handle();
- assert!(!native.is_null());
-}
-
-#[test]
-fn test_bundle_add_str_and_get_str() {
- let mut b = Bundle::new();
- b.add_str("key", "value").unwrap();
- assert_eq!(b.get_str("key").unwrap(), "value");
-}
-
-#[test]
-fn test_bundle_add_bytes_and_get_bytes() {
- let mut b = Bundle::new();
- b.add_bytes("key", &[1, 2, 3]).unwrap();
- assert_eq!(b.get_bytes("key").unwrap(), &[1, 2, 3]);
-}
-
-#[test]
-fn test_bundle_add_str_vec_and_get_str_vec() {
- let mut b = Bundle::new();
- b.add_str_vec("key", &["value1", "value2"]).unwrap();
- assert_eq!(b.get_str_vec("key").unwrap(), &["value1", "value2"]);
-}
-
-#[test]
-fn test_bundle_add_bytes_vec_and_get_bytes_vec() {
- let mut b = Bundle::new();
- b.add_bytes_vec("key", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
- assert_eq!(b.get_bytes_vec("key").unwrap(), &[&[1, 2, 3], &[4, 5, 6]]);
-}
-
-#[test]
-fn test_bundle_count() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- b.add_str("key2", "value2").unwrap();
- assert_eq!(b.count(), 2);
- b.add_str("key3", "value3").unwrap();
- assert_eq!(b.count(), 3);
-}
-
-#[test]
-fn test_bundle_get_type() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- assert_eq!(b.get_type("key1").unwrap(), BundleType::String);
- b.add_str_vec("key2", &["value1", "value2"]).unwrap();
- assert_eq!(b.get_type("key2").unwrap(), BundleType::StringVector);
- b.add_bytes("key3", &[1, 2, 3]).unwrap();
- assert_eq!(b.get_type("key3").unwrap(), BundleType::Bytes);
- b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
- assert_eq!(b.get_type("key4").unwrap(), BundleType::BytesVector);
-}
-
-#[test]
-fn test_bundle_clone() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- b.add_str_vec("key2", &["value1", "value2"]).unwrap();
- let mut cloned_b = b.clone();
- assert_eq!(b.get_str("key1").unwrap(), cloned_b.get_str("key1").unwrap());
- assert_eq!(b.get_str_vec("key2").unwrap(), cloned_b.get_str_vec("key2").unwrap());
-}
-
-#[test]
-fn test_bundle_default() {
- let mut b = Bundle::default();
- b.add_str("key1", "value1").unwrap();
- assert_eq!(b.get_str("key1").unwrap(), "value1");
-}
-
-#[test]
-fn test_bundle_delete() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- assert_eq!(b.get_str("key1").unwrap(), "value1");
- b.delete("key1").unwrap();
- let ret = b.get_str("key1");
- match (ret) {
- Err(err) => assert_eq!(err, BundleError::KeyNotAvailable),
- _ => panic!("Unexpected error"),
- };
-}
-
-#[test]
-fn test_bundle_iter() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- b.add_str_vec("key2", &["value1", "value2"]).unwrap();
- b.add_bytes("key3", &[1, 2, 3]).unwrap();
- b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
-
- for (key, val) in b.iter() {
- match val {
- BundleValue::String(value) => {
- assert_eq!(key, "key1");
- assert_eq!(value, "value1");
- }
- BundleValue::StringVector(value) => {
- assert_eq!(key, "key2");
- assert_eq!(value, &["value1", "value2"]);
- }
- BundleValue::Bytes(value) => {
- assert_eq!(key, "key3");
- assert_eq!(value, &[1, 2, 3]);
- }
- BundleValue::BytesVector(value) => {
- assert_eq!(key, "key4");
- assert_eq!(value, &[&[1, 2, 3], &[4, 5, 6]]);
- }
- _ => assert!(false),
- }
- }
-}
-
-#[test]
-fn test_bundle_into_iter() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- b.add_str_vec("key2", &["value1", "value2"]).unwrap();
- b.add_bytes("key3", &[1, 2, 3]).unwrap();
- b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
-
- for (key, val) in b {
- match val {
- BundleValue::String(value) => {
- assert_eq!(key, "key1");
- assert_eq!(value, "value1");
- }
- BundleValue::StringVector(value) => {
- assert_eq!(key, "key2");
- assert_eq!(value, &["value1", "value2"]);
- }
- BundleValue::Bytes(value) => {
- assert_eq!(key, "key3");
- assert_eq!(value, &[1, 2, 3]);
- }
- BundleValue::BytesVector(value) => {
- assert_eq!(key, "key4");
- assert_eq!(value, &[&[1, 2, 3], &[4, 5, 6]]);
- }
- _ => assert!(false),
- }
- }
-}
-
-#[test]
-fn test_bundle_encode_and_decode() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- let mut encoded_str = b.encode().unwrap();
- let mut decoded_b = Bundle::decode(&encoded_str).unwrap();
- assert_eq!(b.get_str("key1").unwrap(), decoded_b.get_str("key1").unwrap());
-}
-
-#[test]
-fn test_bundle_detach() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- let result = b.detach();
- match result {
- Ok(handle) => assert!(!handle.is_null()),
- Err(err) => panic!("Failed to detach bundle. err: {:?}", err),
- }
- let handle = b.get_raw_handle();
- assert!(handle.is_null());
-}
-
-#[test]
-fn test_bundle_from_raw_handle() {
- let mut b = Bundle::new();
- b.add_str("key1", "value1").unwrap();
- let result = b.detach();
- match result {
- Ok(handle) => {
- assert!(!handle.is_null());
- let mut b2 = Bundle::from_raw_handle(handle, true);
- assert_eq!(b2.get_str("key1").unwrap(), "value1");
- },
- Err(err) => panic!("Failed to detach bundle. err: {:?}", err),
- }
-}
+++ /dev/null
-#[cfg(test)]
-pub mod parcel_tests;
-#[cfg(test)]
-pub mod bundle_tests;
+++ /dev/null
-use parcel;
-
-#[warn(unused_imports)]
-use parcel::{Parcel, ParcelError};
-
-#[test]
-fn test_parcel_write_bool_and_read_bool() {
- let mut parcel = Parcel::new();
- parcel.write_bool(true);
- let result = parcel.read_bool().unwrap();
- assert_eq!(result, true);
-}
-
-#[test]
-fn test_parcel_write_i8_and_read_i8() {
- let mut parcel = Parcel::new();
- parcel.write_i8(1);
- let result = parcel.read_i8().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_i16_and_read_i16() {
- let mut parcel = Parcel::new();
- parcel.write_i16(1);
- let result = parcel.read_i16().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_i32_and_read_i32() {
- let mut parcel = Parcel::new();
- parcel.write_i32(1);
- let result = parcel.read_i32().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_i64_and_read_i64() {
- let mut parcel = Parcel::new();
- parcel.write_i64(1);
- let result = parcel.read_i64().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_u16_and_read_u16() {
- let mut parcel = Parcel::new();
- parcel.write_u16(1);
- let result = parcel.read_u16().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_u32_and_read_u32() {
- let mut parcel = Parcel::new();
- parcel.write_u32(1);
- let result = parcel.read_u32().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_u64_and_read_u64() {
- let mut parcel = Parcel::new();
- parcel.write_u64(1);
- let result = parcel.read_u64().unwrap();
- assert_eq!(result, 1);
-}
-
-#[test]
-fn test_parcel_write_f32_and_read_f32() {
- let mut parcel = Parcel::new();
- parcel.write_f32(1.0);
- let result = parcel.read_f32().unwrap();
- assert_eq!(result, 1.0);
-}
-
-#[test]
-fn test_parcel_write_f64_and_read_f64() {
- let mut parcel = Parcel::new();
- parcel.write_f64(1.0);
- let result = parcel.read_f64().unwrap();
- assert_eq!(result, 1.0);
-}
-
-#[test]
-fn test_parcel_write_string_and_read_string() {
- let mut parcel = Parcel::new();
- parcel.write_string("test");
- let result = parcel.read_string().unwrap();
- assert_eq!(result, "test");
-}
-
-#[test]
-fn test_parcel_reset_reader() {
- let mut parcel = Parcel::new();
- parcel.write_i32(1);
- parcel.write_i32(2);
- assert_eq!(parcel.read_i32().unwrap(), 1);
- parcel.reset_reader();
- assert_eq!(parcel.read_i32().unwrap(), 1);
- assert_eq!(parcel.read_i32().unwrap(), 2);
-}
-
-#[test]
-fn test_parcel_clear() {
- let mut parcel = Parcel::new();
- parcel.write_i32(1);
- parcel.clear();
- match parcel.read_i32() {
- Err(err) => {
- assert_eq!(err, ParcelError::NoData);
- },
- _ => panic!("Expected error"),
- };
-}
-
-#[test]
-fn test_parcel_reset() {
- let mut parcel = Parcel::new();
- parcel.reset(&[b'P']);
- let res = parcel.read(1).unwrap();
- assert_eq!(res, [b'P']);
-}
-
-#[test]
-fn test_parcel_get_raw_data() {
- let mut parcel = Parcel::new();
- parcel.write_i32(1);
- parcel.write_i32(2);
- let data = parcel.get_raw_data().unwrap();
- assert_ne!(data.len(), 0);
- assert_eq!(data, vec![1, 0, 0, 0, 2, 0, 0, 0]);
-}
--- /dev/null
+[package]
+name = "rust-tizen-bundle"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = [ "dylib" ]
+crate-name = [ "tizen_bundle" ]
\ No newline at end of file
--- /dev/null
+pub mod tizen_bundle;
+
+pub use crate::tizen_bundle::{Bundle};
+
+mod tests;
--- /dev/null
+#[cfg(test)]
+pub mod tizen_bundle_tests;
--- /dev/null
+use tizen_bundle;
+
+#[warn(unused_imports)]
+use tizen_bundle::{Bundle, BundleError, BundleType, BundleIter, BundleValue};
+
+#[test]
+fn test_bundle_new_and_get_raw_handle() {
+ let b = Bundle::new();
+ let native = b.get_raw_handle();
+ assert!(!native.is_null());
+}
+
+#[test]
+fn test_bundle_add_str_and_get_str() {
+ let mut b = Bundle::new();
+ b.add_str("key", "value").unwrap();
+ assert_eq!(b.get_str("key").unwrap(), "value");
+}
+
+#[test]
+fn test_bundle_add_bytes_and_get_bytes() {
+ let mut b = Bundle::new();
+ b.add_bytes("key", &[1, 2, 3]).unwrap();
+ assert_eq!(b.get_bytes("key").unwrap(), &[1, 2, 3]);
+}
+
+#[test]
+fn test_bundle_add_str_vec_and_get_str_vec() {
+ let mut b = Bundle::new();
+ b.add_str_vec("key", &["value1", "value2"]).unwrap();
+ assert_eq!(b.get_str_vec("key").unwrap(), &["value1", "value2"]);
+}
+
+#[test]
+fn test_bundle_add_bytes_vec_and_get_bytes_vec() {
+ let mut b = Bundle::new();
+ b.add_bytes_vec("key", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
+ assert_eq!(b.get_bytes_vec("key").unwrap(), &[&[1, 2, 3], &[4, 5, 6]]);
+}
+
+#[test]
+fn test_bundle_count() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ b.add_str("key2", "value2").unwrap();
+ assert_eq!(b.count(), 2);
+ b.add_str("key3", "value3").unwrap();
+ assert_eq!(b.count(), 3);
+}
+
+#[test]
+fn test_bundle_get_type() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ assert_eq!(b.get_type("key1").unwrap(), BundleType::String);
+ b.add_str_vec("key2", &["value1", "value2"]).unwrap();
+ assert_eq!(b.get_type("key2").unwrap(), BundleType::StringVector);
+ b.add_bytes("key3", &[1, 2, 3]).unwrap();
+ assert_eq!(b.get_type("key3").unwrap(), BundleType::Bytes);
+ b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
+ assert_eq!(b.get_type("key4").unwrap(), BundleType::BytesVector);
+}
+
+#[test]
+fn test_bundle_clone() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ b.add_str_vec("key2", &["value1", "value2"]).unwrap();
+ let mut cloned_b = b.clone();
+ assert_eq!(b.get_str("key1").unwrap(), cloned_b.get_str("key1").unwrap());
+ assert_eq!(b.get_str_vec("key2").unwrap(), cloned_b.get_str_vec("key2").unwrap());
+}
+
+#[test]
+fn test_bundle_default() {
+ let mut b = Bundle::default();
+ b.add_str("key1", "value1").unwrap();
+ assert_eq!(b.get_str("key1").unwrap(), "value1");
+}
+
+#[test]
+fn test_bundle_delete() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ assert_eq!(b.get_str("key1").unwrap(), "value1");
+ b.delete("key1").unwrap();
+ let ret = b.get_str("key1");
+ match (ret) {
+ Err(err) => assert_eq!(err, BundleError::KeyNotAvailable),
+ _ => panic!("Unexpected error"),
+ };
+}
+
+#[test]
+fn test_bundle_iter() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ b.add_str_vec("key2", &["value1", "value2"]).unwrap();
+ b.add_bytes("key3", &[1, 2, 3]).unwrap();
+ b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
+
+ for (key, val) in b.iter() {
+ match val {
+ BundleValue::String(value) => {
+ assert_eq!(key, "key1");
+ assert_eq!(value, "value1");
+ }
+ BundleValue::StringVector(value) => {
+ assert_eq!(key, "key2");
+ assert_eq!(value, &["value1", "value2"]);
+ }
+ BundleValue::Bytes(value) => {
+ assert_eq!(key, "key3");
+ assert_eq!(value, &[1, 2, 3]);
+ }
+ BundleValue::BytesVector(value) => {
+ assert_eq!(key, "key4");
+ assert_eq!(value, &[&[1, 2, 3], &[4, 5, 6]]);
+ }
+ _ => assert!(false),
+ }
+ }
+}
+
+#[test]
+fn test_bundle_into_iter() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ b.add_str_vec("key2", &["value1", "value2"]).unwrap();
+ b.add_bytes("key3", &[1, 2, 3]).unwrap();
+ b.add_bytes_vec("key4", &[&[1, 2, 3], &[4, 5, 6]]).unwrap();
+
+ for (key, val) in b {
+ match val {
+ BundleValue::String(value) => {
+ assert_eq!(key, "key1");
+ assert_eq!(value, "value1");
+ }
+ BundleValue::StringVector(value) => {
+ assert_eq!(key, "key2");
+ assert_eq!(value, &["value1", "value2"]);
+ }
+ BundleValue::Bytes(value) => {
+ assert_eq!(key, "key3");
+ assert_eq!(value, &[1, 2, 3]);
+ }
+ BundleValue::BytesVector(value) => {
+ assert_eq!(key, "key4");
+ assert_eq!(value, &[&[1, 2, 3], &[4, 5, 6]]);
+ }
+ _ => assert!(false),
+ }
+ }
+}
+
+#[test]
+fn test_bundle_encode_and_decode() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ let mut encoded_str = b.encode().unwrap();
+ let mut decoded_b = Bundle::decode(&encoded_str).unwrap();
+ assert_eq!(b.get_str("key1").unwrap(), decoded_b.get_str("key1").unwrap());
+}
+
+#[test]
+fn test_bundle_detach() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ let result = b.detach();
+ match result {
+ Ok(handle) => assert!(!handle.is_null()),
+ Err(err) => panic!("Failed to detach bundle. err: {:?}", err),
+ }
+ let handle = b.get_raw_handle();
+ assert!(handle.is_null());
+}
+
+#[test]
+fn test_bundle_from_raw_handle() {
+ let mut b = Bundle::new();
+ b.add_str("key1", "value1").unwrap();
+ let result = b.detach();
+ match result {
+ Ok(handle) => {
+ assert!(!handle.is_null());
+ let mut b2 = Bundle::from_raw_handle(handle, true);
+ assert_eq!(b2.get_str("key1").unwrap(), "value1");
+ },
+ Err(err) => panic!("Failed to detach bundle. err: {:?}", err),
+ }
+}
--- /dev/null
+extern crate libc;
+
+use self::libc::{EINVAL, ENOKEY, ENOMEM};
+use std::collections::VecDeque;
+use std::ffi::{c_char, c_int, c_uchar, c_uint, c_void, CStr, CString};
+use std::ptr;
+
+const TIZEN_ERROR_BUNDLE: i32 = -0x01180000;
+const BUNDLE_ERROR_NONE: i32 = 0;
+const BUNDLE_ERROR_OUT_OF_MEMORY: i32 = -ENOMEM;
+const BUNDLE_ERROR_INVALID_PARAMETER: i32 = -EINVAL;
+const BUNDLE_ERROR_KEY_NOT_AVAILABLE: i32 = -ENOKEY;
+const BUNDLE_ERROR_KEY_EXISTS: i32 = TIZEN_ERROR_BUNDLE | 0x01;
+const BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS: i32 = TIZEN_ERROR_BUNDLE | 0x02;
+
+const BUNDLE_TYPE_ARRAY: i32 = 0x0100;
+const BUNDLE_TYPE_MEASURABLE: i32 = 0x0400;
+const BUNDLE_TYPE_NONE: i32 = -1;
+const BUNDLE_TYPE_ANY: i32 = 0;
+const BUNDLE_TYPE_STR: i32 = 1 | BUNDLE_TYPE_MEASURABLE;
+const BUNDLE_TYPE_STR_ARRAY: i32 = BUNDLE_TYPE_STR | BUNDLE_TYPE_ARRAY | BUNDLE_TYPE_MEASURABLE;
+const BUNDLE_TYPE_BYTE: i32 = 2;
+const BUNDLE_TYPE_BYTE_ARRAY: i32 = BUNDLE_TYPE_BYTE | BUNDLE_TYPE_ARRAY;
+
+#[link(name = "bundle")]
+extern "C" {
+ fn bundle_create() -> *mut c_void;
+ fn bundle_free(b: *mut c_void) -> c_int;
+ fn bundle_add_str_array(
+ b: *mut c_void,
+ key: *const c_char,
+ array: *const *const c_char,
+ len: c_int,
+ ) -> c_int;
+ fn bundle_del(b: *mut c_void, key: *const c_char) -> c_int;
+ fn bundle_get_str_array(
+ b: *mut c_void,
+ key: *const c_char,
+ len: *mut c_int,
+ ) -> *const *const c_char;
+ fn bundle_get_count(b: *mut c_void) -> c_int;
+ fn bundle_get_type(b: *mut c_void, key: *const c_char) -> c_int;
+ fn bundle_dup(b: *mut c_void) -> *mut c_void;
+ fn bundle_foreach(
+ b: *mut c_void,
+ callback: extern "C" fn(*const c_char, c_int, *const c_void, *mut c_void),
+ user_data: *mut c_void,
+ ) -> c_int;
+ fn bundle_encode(b: *mut c_void, r: *mut *mut c_char, len: *mut c_int) -> c_int;
+ fn bundle_decode(r: *const c_char, len: c_int) -> *mut c_void;
+ fn bundle_add_str(b: *mut c_void, key: *const c_char, value: *const c_char) -> c_int;
+ fn bundle_add_byte(
+ b: *mut c_void,
+ key: *const c_char,
+ bytes: *const c_uchar,
+ size: c_uint,
+ ) -> c_int;
+ fn bundle_get_str(b: *mut c_void, key: *const c_char, val: *mut *mut c_char) -> c_int;
+ fn bundle_get_byte(
+ b: *mut c_void,
+ key: *const c_char,
+ bytes: *mut *mut c_void,
+ size: *mut c_uint,
+ ) -> c_int;
+ fn bundle_add_byte_array(b: *mut c_void, key: *const c_char, len: c_uint) -> c_int;
+ fn bundle_set_byte_array_element(
+ b: *mut c_void,
+ key: *const c_char,
+ idx: c_uint,
+ bytes: *const c_void,
+ size: c_uint,
+ ) -> c_int;
+ fn bundle_get_byte_array(
+ b: *mut c_void,
+ key: *const c_char,
+ byte_array: *mut *mut *mut c_void,
+ len: *mut c_uint,
+ array_element_size: *mut *mut c_uint,
+ ) -> c_int;
+ fn bundle_keyval_get_basic_val(
+ kv: *mut c_void,
+ val: *mut *mut c_void,
+ size: *mut c_uint,
+ ) -> c_int;
+ fn bundle_keyval_get_array_val(
+ kv: *mut c_void,
+ array_val: *mut *mut *mut c_void,
+ array_len: *mut c_uint,
+ array_element_size: *mut *mut c_uint,
+ ) -> c_int;
+}
+
+#[link(name = "capi-base-common")]
+extern "C" {
+ fn get_last_result() -> c_int;
+}
+
+/// Represents a value of a bundle.
+#[derive(Debug)]
+pub enum BundleValue {
+ /// A string value.
+ String(String),
+ /// A vector of strings.
+ StringVector(Vec<String>),
+ /// A byte vector.
+ Bytes(Vec<u8>),
+ /// A vector of byte vectors.
+ BytesVector(Vec<Vec<u8>>),
+}
+
+/// Represents an error that can occur when working with a `Bundle`.
+#[derive(Debug, PartialEq)]
+pub enum BundleError {
+ /// Out of memory.
+ /// There is not enough memory to complete the operation. This error occurs when the memory allocation fails.
+ OutOfMemory,
+ /// Invalid parameter.
+ /// The input parameter is invalid. This error occurs when the input parameter is out of range.
+ InvalidParameter,
+ /// Key not available.
+ /// The key does not exist in the bundle. This error occurs when you try to get a value with a non-existent key.
+ KeyNotAvailable,
+ /// Key exists.
+ /// The key already exists in the bundle. This error occurs when you try to add a key that already exists.
+ KeyExists,
+ /// The index is out of bounds of the array.
+ ArrayIndexOutOfBounds,
+ /// No ownership.
+ /// The bundle does not own the data. This error occurs when you try to detach the data that was not allocated by the bundle.
+ NoOwnership,
+}
+
+impl BundleError {
+ fn from_c_int(result: c_int) -> BundleError {
+ match result {
+ BUNDLE_ERROR_OUT_OF_MEMORY => BundleError::OutOfMemory,
+ BUNDLE_ERROR_INVALID_PARAMETER => BundleError::InvalidParameter,
+ BUNDLE_ERROR_KEY_NOT_AVAILABLE => BundleError::KeyNotAvailable,
+ BUNDLE_ERROR_KEY_EXISTS => BundleError::KeyExists,
+ BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS => BundleError::ArrayIndexOutOfBounds,
+ _ => panic!("Unexpected error code {}", result),
+ }
+ }
+}
+
+/// Represents a type of a bundle key.
+#[derive(Debug, PartialEq)]
+pub enum BundleType {
+ /// None.
+ None,
+ /// Any type.
+ Any,
+ /// A string type.
+ String,
+ /// A vector of strings.
+ StringVector,
+ /// Bytes type.
+ Bytes,
+ /// A vector of bytes.
+ BytesVector,
+}
+
+impl BundleType {
+ fn from_c_int(key_type: c_int) -> BundleType {
+ match key_type {
+ BUNDLE_TYPE_NONE => BundleType::None,
+ BUNDLE_TYPE_ANY => BundleType::Any,
+ BUNDLE_TYPE_STR => BundleType::String,
+ BUNDLE_TYPE_STR_ARRAY => BundleType::StringVector,
+ BUNDLE_TYPE_BYTE => BundleType::Bytes,
+ BUNDLE_TYPE_BYTE_ARRAY => BundleType::BytesVector,
+ _ => panic!("Unexpected type code: {}", key_type),
+ }
+ }
+}
+
+/// A representation of a Bundle, which is a key-value pair container.
+#[derive(Debug)]
+pub struct Bundle {
+ handle: *mut c_void,
+ ownership: bool,
+}
+
+impl Clone for Bundle {
+ fn clone(&self) -> Self {
+ let handle = unsafe { bundle_dup(self.handle) };
+ Self { handle, ownership: true }
+ }
+}
+
+impl Drop for Bundle {
+ fn drop(&mut self) {
+ if self.ownership && !self.handle.is_null() {
+ unsafe {
+ bundle_free(self.handle);
+ }
+ }
+ }
+}
+
+impl Default for Bundle {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Bundle {
+ /// Creates a new `Bundle` instance.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the creation of a `Bundle` fails.
+ pub fn new() -> Self {
+ let handle = unsafe { bundle_create() };
+ if handle.is_null() {
+ panic!("Failed to create bundle");
+ }
+ Self { handle, ownership: true }
+ }
+
+ /// Creates a new `Bundle` instance from a raw handle.
+ ///
+ /// # Arguments
+ ///
+ /// * `b`: The raw handle to the bundle.
+ /// * `ownership`: Whether or not the `Bundle` should take ownership of the raw handle. If `false`, the caller retains ownership and the `Bundle` will not free the handle when it is dropped.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if the provided handle is null.
+ pub fn from_raw_handle(b: *mut c_void, ownership: bool) -> Self {
+ if b.is_null() {
+ panic!("Bundle pointer is null");
+ }
+ Self { handle: b, ownership }
+ }
+
+ /// Gets a raw handle from the `Bundle`.
+ ///
+ /// # Returns
+ ///
+ /// A raw handle of the `Bundle`.
+ pub fn get_raw_handle(&self) -> *mut c_void {
+ self.handle
+ }
+
+ /// Detaches the raw handle from the `Bundle` and returns it.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(*mut c_void)` on success, or an appropriate `Err(BundleError)` on failure.
+ /// If the `Bundle` does not own the raw handle, this function returns `Err(BundleError)`. Otherwise,
+ pub fn detach(&mut self) -> Result<*mut c_void, BundleError> {
+ if self.ownership {
+ let handle = self.handle;
+ self.handle = std::ptr::null_mut();
+ self.ownership = false;
+ Ok(handle)
+ } else {
+ Err(BundleError::NoOwnership)
+ }
+ }
+
+ /// Deletes a value associated with the given key.
+ ///
+ /// # Arguements
+ ///
+ /// * `key` - The key to be deleted. It must be a valid UTF-8 string. If not, this function will return an error.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failrue.
+ pub fn delete(&mut self, key: &str) -> Result<(), BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let result = unsafe { bundle_del(self.handle, c_key.as_ptr()) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Gets the number of elements in the `Bundle`.
+ ///
+ /// # Returns
+ ///
+ /// The number of elements.
+ pub fn count(&self) -> i32 {
+ (unsafe { bundle_get_count(self.handle) }) as i32
+ }
+
+ /// Adds a string to the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key of the element.
+ /// * `value` - The value of the element. This must be a valid UTF-8 encoded string.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn add_str(&mut self, key: &str, value: &str) -> Result<(), BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let c_value = CString::new(value).unwrap();
+ let result = unsafe { bundle_add_str(self.handle, c_key.as_ptr(), c_value.as_ptr()) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Gets a string with the given key from the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key to retrieve the value for.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(String)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn get_str(&self, key: &str) -> Result<String, BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let mut c_val: *mut c_char = ptr::null_mut();
+ let result = unsafe { bundle_get_str(self.handle, c_key.as_ptr(), &mut c_val) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ let c_str = unsafe { CStr::from_ptr(c_val) };
+ Ok(c_str.to_string_lossy().into_owned())
+ }
+ }
+
+ /// Adds a vector of strings to the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key of the element.
+ /// * `value` - The vector of strings.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn add_str_vec(&mut self, key: &str, values: &[&str]) -> Result<(), BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let c_array: Vec<CString> = values.iter().map(|&s| CString::new(s).unwrap()).collect();
+ let c_ptr_array: Vec<*const c_char> = c_array.iter().map(|s| s.as_ptr()).collect();
+ let result = unsafe {
+ bundle_add_str_array(
+ self.handle,
+ c_key.as_ptr(),
+ c_ptr_array.as_ptr(),
+ c_array.len() as c_int,
+ )
+ };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Gets a vector of strings with the given key from the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key to retrieve the value for.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(Vec<String>)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn get_str_vec(&self, key: &str) -> Result<Vec<String>, BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let mut len: c_int = 0;
+ let c_array_ptr = unsafe { bundle_get_str_array(self.handle, c_key.as_ptr(), &mut len) };
+ if c_array_ptr.is_null() {
+ return Err(BundleError::from_c_int(unsafe { get_last_result() }));
+ }
+
+ let mut result = Vec::with_capacity(len as usize);
+ for i in 0..len {
+ let c_str_ptr = unsafe { *c_array_ptr.add(i as usize) };
+ let c_str = unsafe { CStr::from_ptr(c_str_ptr) };
+ result.push(c_str.to_string_lossy().into_owned());
+ }
+ Ok(result)
+ }
+
+ /// Adds bytes to the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key of the element.
+ /// * `value` - The bytes of the element.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn add_bytes(&mut self, key: &str, bytes: &[u8]) -> Result<(), BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let result = unsafe {
+ bundle_add_byte(
+ self.handle,
+ c_key.as_ptr(),
+ bytes.as_ptr(),
+ bytes.len() as c_uint,
+ )
+ };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Gets bytes with the given key from the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key to retrieve the value for.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(Vec<u8>)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn get_bytes(&self, key: &str) -> Result<Vec<u8>, BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let mut bytes_ptr: *mut c_void = ptr::null_mut();
+ let mut size: c_uint = 0;
+ let result =
+ unsafe { bundle_get_byte(self.handle, c_key.as_ptr(), &mut bytes_ptr, &mut size) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(unsafe {
+ std::slice::from_raw_parts(bytes_ptr as *const u8, size as usize).to_vec()
+ })
+ }
+ }
+
+ /// Adds a vector of bytes to the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key of the element.
+ /// * `value` - The vector of bytes.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn add_bytes_vec(&mut self, key: &str, elements: &[&[u8]]) -> Result<(), BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let array_len = elements.len() as c_uint;
+ let result = unsafe { bundle_add_byte_array(self.handle, c_key.as_ptr(), array_len) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ for (idx, element) in elements.iter().enumerate() {
+ let result = unsafe {
+ bundle_set_byte_array_element(
+ self.handle,
+ c_key.as_ptr(),
+ idx as c_uint,
+ element.as_ptr() as *const c_void,
+ element.len() as c_uint,
+ )
+ };
+ if result != 0 {
+ return Err(BundleError::from_c_int(result));
+ }
+ }
+ Ok(())
+ }
+ }
+
+ /// Gets a vector of bytes with the given key from the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key to retrieve the value for.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(Vec<Vec<u8>>)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn get_bytes_vec(&self, key: &str) -> Result<Vec<Vec<u8>>, BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let mut byte_array_ptr: *mut *mut c_void = ptr::null_mut();
+ let mut len: c_uint = 0;
+ let mut array_element_size: *mut c_uint = ptr::null_mut();
+ let result = unsafe {
+ bundle_get_byte_array(
+ self.handle,
+ c_key.as_ptr(),
+ &mut byte_array_ptr,
+ &mut len,
+ &mut array_element_size,
+ )
+ };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ let byte_array = unsafe { std::slice::from_raw_parts(byte_array_ptr, len as usize) };
+ let element_sizes =
+ unsafe { std::slice::from_raw_parts(array_element_size, len as usize) };
+ let mut bytes = Vec::with_capacity(len as usize);
+ for i in 0..len as usize {
+ let element_size = element_sizes[i] as usize;
+ let element =
+ unsafe { std::slice::from_raw_parts(byte_array[i] as *const u8, element_size) };
+ bytes.push(element.to_vec());
+ }
+
+ Ok(bytes)
+ }
+ }
+
+ /// Gets the type of a given key in the `Bundle`.
+ ///
+ /// # Arguments
+ ///
+ /// * `key` - The key to retrieve the value type for.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(BundleType)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn get_type(&self, key: &str) -> Result<BundleType, BundleError> {
+ let c_key = CString::new(key).unwrap();
+ let result = unsafe { bundle_get_type(self.handle, c_key.as_ptr()) };
+ if result < BUNDLE_TYPE_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(BundleType::from_c_int(result))
+ }
+ }
+
+ /// Encode the bundle to a string.(uses base64 format).
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(String)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn encode(&self) -> Result<String, BundleError> {
+ let mut raw: *mut c_char = std::ptr::null_mut();
+ let mut len: c_int = 0;
+ let result = unsafe { bundle_encode(self.handle, &mut raw, &mut len) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(unsafe { CStr::from_ptr(raw as *const c_char) }
+ .to_string_lossy()
+ .into_owned())
+ }
+ }
+
+ /// Creates a new `Bundle` from the given encoded string.
+ /// The string must be in the format returned by `encode`. If the string is invalid, an error will be returned.
+ ///
+ /// # Arguments
+ ///
+ /// * `raw` - The encoded string to decode. This must be in the format returned by `encode`.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(Bundle)` on success, or an appropriate `Err(BundleError)` on failure.
+ pub fn decode(raw: &str) -> Result<Bundle, BundleError> {
+ let c_raw = CString::new(raw).unwrap();
+ let handle = unsafe { bundle_decode(c_raw.as_ptr() as *const c_char, raw.len() as c_int) };
+ if handle.is_null() {
+ Err(BundleError::from_c_int(unsafe { get_last_result() }))
+ } else {
+ Ok(Bundle { handle, ownership: true })
+ }
+ }
+
+ /// Iterates over the keys and values of the `Bundle`.
+ ///
+ /// # Returns
+ ///
+ /// An iterator over the keys and values of the `Bundle`.
+ pub fn iter(&self) -> BundleIter {
+ let mut bundle_iter = BundleIter {
+ bundle: self,
+ items: VecDeque::new(),
+ };
+ bundle_iter.populate_items();
+ bundle_iter
+ }
+}
+
+#[derive(Debug)]
+struct KeyInfo {
+ key: String,
+ key_type: BundleType,
+ handle: *mut c_void,
+}
+
+impl KeyInfo {
+ fn new(key: &str, key_type: BundleType, handle: *mut c_void) -> Self {
+ KeyInfo {
+ key: key.to_string(),
+ key_type,
+ handle,
+ }
+ }
+
+ fn get_str(&self) -> Result<String, BundleError> {
+ let mut val: *mut c_void = std::ptr::null_mut();
+ let mut size: c_uint = 0;
+ let result = unsafe { bundle_keyval_get_basic_val(self.handle, &mut val, &mut size) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(unsafe {
+ CStr::from_ptr(val as *const c_char)
+ .to_string_lossy()
+ .into_owned()
+ })
+ }
+ }
+
+ fn get_str_vec(&self) -> Result<Vec<String>, BundleError> {
+ let mut array_val: *mut *mut c_void = std::ptr::null_mut();
+ let mut array_len: c_uint = 0;
+ let mut array_element_size: *mut c_uint = std::ptr::null_mut();
+ let result = unsafe {
+ bundle_keyval_get_array_val(
+ self.handle,
+ &mut array_val,
+ &mut array_len,
+ &mut array_element_size,
+ )
+ };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ let mut values = Vec::with_capacity(array_len as usize);
+ for i in 0..array_len {
+ let c_str_ptr = unsafe { *array_val.add(i as usize) };
+ let c_str = unsafe { CStr::from_ptr(c_str_ptr as *const c_char) };
+ values.push(c_str.to_string_lossy().into_owned());
+ }
+ Ok(values)
+ }
+ }
+
+ fn get_bytes(&self) -> Result<Vec<u8>, BundleError> {
+ let mut val: *mut c_void = std::ptr::null_mut();
+ let mut size: c_uint = 0;
+ let result = unsafe { bundle_keyval_get_basic_val(self.handle, &mut val, &mut size) };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ Ok(unsafe { std::slice::from_raw_parts(val as *const u8, size as usize).to_vec() })
+ }
+ }
+
+ fn get_bytes_vec(&self) -> Result<Vec<Vec<u8>>, BundleError> {
+ let mut array_val: *mut *mut c_void = std::ptr::null_mut();
+ let mut array_len: c_uint = 0;
+ let mut array_element_size: *mut c_uint = std::ptr::null_mut();
+ let result = unsafe {
+ bundle_keyval_get_array_val(
+ self.handle,
+ &mut array_val,
+ &mut array_len,
+ &mut array_element_size,
+ )
+ };
+ if result != BUNDLE_ERROR_NONE {
+ Err(BundleError::from_c_int(result))
+ } else {
+ let byte_array = unsafe { std::slice::from_raw_parts(array_val, array_len as usize) };
+ let element_sizes =
+ unsafe { std::slice::from_raw_parts(array_element_size, array_len as usize) };
+ let mut bytes_vec = Vec::with_capacity(array_len as usize);
+ for i in 0..array_len as usize {
+ let element_size = element_sizes[i] as usize;
+ let element =
+ unsafe { std::slice::from_raw_parts(byte_array[i] as *const u8, element_size) };
+ bytes_vec.push(element.to_vec());
+ }
+ Ok(bytes_vec)
+ }
+ }
+
+ fn get_item(&self) -> Result<(String, BundleValue), BundleError> {
+ match self.key_type {
+ BundleType::String => {
+ let value = self.get_str();
+ match value {
+ Ok(v) => Ok((self.key.clone(), BundleValue::String(v))),
+ Err(err) => Err(err),
+ }
+ }
+ BundleType::StringVector => {
+ let value = self.get_str_vec();
+ match value {
+ Ok(v) => Ok((self.key.clone(), BundleValue::StringVector(v))),
+ Err(err) => Err(err),
+ }
+ }
+ BundleType::Bytes => {
+ let value = self.get_bytes();
+ match value {
+ Ok(v) => Ok((self.key.clone(), BundleValue::Bytes(v))),
+ Err(err) => Err(err),
+ }
+ }
+ BundleType::BytesVector => {
+ let value = self.get_bytes_vec();
+ match value {
+ Ok(v) => Ok((self.key.clone(), BundleValue::BytesVector(v))),
+ Err(err) => Err(err),
+ }
+ }
+ _ => Err(BundleError::KeyNotAvailable),
+ }
+ }
+}
+
+extern "C" fn foreach_callback(
+ key: *const c_char,
+ key_type: c_int,
+ key_value: *const c_void,
+ user_data: *mut c_void,
+) {
+ let items: &mut VecDeque<(String, BundleValue)> =
+ unsafe { &mut *(user_data as *mut VecDeque<(String, BundleValue)>) };
+ let key_str = unsafe { CStr::from_ptr(key).to_str().unwrap().to_string() };
+ let key_info = KeyInfo::new(
+ &key_str,
+ BundleType::from_c_int(key_type),
+ key_value as *mut c_void,
+ );
+ let item = key_info.get_item();
+ match item {
+ Ok(i) => items.push_back(i),
+ Err(err) => println!(
+ "Error while creating key info: {:?}, error: {:?}",
+ key_info, err
+ ),
+ }
+}
+
+/// Iterator for Bundle. Iterates over all the keys and values in a bundle.
+pub struct BundleIter<'a> {
+ bundle: &'a Bundle,
+ items: VecDeque<(String, BundleValue)>,
+}
+
+impl<'a> BundleIter<'a> {
+ fn populate_items(&mut self) {
+ let user_data: *mut VecDeque<(String, BundleValue)> = &mut self.items;
+ unsafe {
+ bundle_foreach(
+ self.bundle.handle,
+ foreach_callback,
+ user_data as *mut c_void,
+ );
+ }
+ }
+}
+
+impl<'a> Iterator for BundleIter<'a> {
+ type Item = (String, BundleValue);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.items.pop_front()
+ }
+}
+
+impl<'a> IntoIterator for &'a Bundle {
+ type Item = (String, BundleValue);
+ type IntoIter = BundleIter<'a>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl IntoIterator for Bundle {
+ type Item = (String, BundleValue);
+ type IntoIter = BundleIntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ let mut iter = BundleIntoIter {
+ bundle: self,
+ items: VecDeque::new(),
+ };
+ iter.populate_items();
+ iter
+ }
+}
+
+/// IntoIterator for Bundle.
+pub struct BundleIntoIter {
+ bundle: Bundle,
+ items: VecDeque<(String, BundleValue)>,
+}
+
+impl BundleIntoIter {
+ fn populate_items(&mut self) {
+ let user_data: *mut VecDeque<(String, BundleValue)> = &mut self.items;
+ unsafe {
+ bundle_foreach(
+ self.bundle.handle,
+ foreach_callback,
+ user_data as *mut c_void,
+ );
+ }
+ }
+}
+
+impl Iterator for BundleIntoIter {
+ type Item = (String, BundleValue);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.items.pop_front()
+ }
+}
--- /dev/null
+[package]
+name = "rust-parcel"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = [ "dylib" ]
+crate-name = [ "parcel" ]
--- /dev/null
+pub mod tizen_parcel;
+
+pub use crate::tizen_parcel::{Parcel};
+
+mod tests;
--- /dev/null
+#[cfg(test)]
+pub mod tizen_parcel_tests;
--- /dev/null
+use tizen_parcel;
+
+#[warn(unused_imports)]
+use tizen_parcel::{Parcel, ParcelError};
+
+#[test]
+fn test_parcel_write_bool_and_read_bool() {
+ let mut parcel = Parcel::new();
+ parcel.write_bool(true);
+ let result = parcel.read_bool().unwrap();
+ assert_eq!(result, true);
+}
+
+#[test]
+fn test_parcel_write_i8_and_read_i8() {
+ let mut parcel = Parcel::new();
+ parcel.write_i8(1);
+ let result = parcel.read_i8().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_i16_and_read_i16() {
+ let mut parcel = Parcel::new();
+ parcel.write_i16(1);
+ let result = parcel.read_i16().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_i32_and_read_i32() {
+ let mut parcel = Parcel::new();
+ parcel.write_i32(1);
+ let result = parcel.read_i32().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_i64_and_read_i64() {
+ let mut parcel = Parcel::new();
+ parcel.write_i64(1);
+ let result = parcel.read_i64().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_u16_and_read_u16() {
+ let mut parcel = Parcel::new();
+ parcel.write_u16(1);
+ let result = parcel.read_u16().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_u32_and_read_u32() {
+ let mut parcel = Parcel::new();
+ parcel.write_u32(1);
+ let result = parcel.read_u32().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_u64_and_read_u64() {
+ let mut parcel = Parcel::new();
+ parcel.write_u64(1);
+ let result = parcel.read_u64().unwrap();
+ assert_eq!(result, 1);
+}
+
+#[test]
+fn test_parcel_write_f32_and_read_f32() {
+ let mut parcel = Parcel::new();
+ parcel.write_f32(1.0);
+ let result = parcel.read_f32().unwrap();
+ assert_eq!(result, 1.0);
+}
+
+#[test]
+fn test_parcel_write_f64_and_read_f64() {
+ let mut parcel = Parcel::new();
+ parcel.write_f64(1.0);
+ let result = parcel.read_f64().unwrap();
+ assert_eq!(result, 1.0);
+}
+
+#[test]
+fn test_parcel_write_string_and_read_string() {
+ let mut parcel = Parcel::new();
+ parcel.write_string("test");
+ let result = parcel.read_string().unwrap();
+ assert_eq!(result, "test");
+}
+
+#[test]
+fn test_parcel_reset_reader() {
+ let mut parcel = Parcel::new();
+ parcel.write_i32(1);
+ parcel.write_i32(2);
+ assert_eq!(parcel.read_i32().unwrap(), 1);
+ parcel.reset_reader();
+ assert_eq!(parcel.read_i32().unwrap(), 1);
+ assert_eq!(parcel.read_i32().unwrap(), 2);
+}
+
+#[test]
+fn test_parcel_clear() {
+ let mut parcel = Parcel::new();
+ parcel.write_i32(1);
+ parcel.clear();
+ match parcel.read_i32() {
+ Err(err) => {
+ assert_eq!(err, ParcelError::NoData);
+ },
+ _ => panic!("Expected error"),
+ };
+}
+
+#[test]
+fn test_parcel_reset() {
+ let mut parcel = Parcel::new();
+ parcel.reset(&[b'P']);
+ let res = parcel.read(1).unwrap();
+ assert_eq!(res, [b'P']);
+}
+
+#[test]
+fn test_parcel_get_raw_data() {
+ let mut parcel = Parcel::new();
+ parcel.write_i32(1);
+ parcel.write_i32(2);
+ let data = parcel.get_raw_data().unwrap();
+ assert_ne!(data.len(), 0);
+ assert_eq!(data, vec![1, 0, 0, 0, 2, 0, 0, 0]);
+}
--- /dev/null
+extern crate libc;
+
+use self::libc::{EILSEQ, EINVAL, ENODATA, ENOMEM};
+use std::ffi::{
+ c_char, c_double, c_float, c_int, c_longlong, c_short, c_uchar, c_uint, c_ulonglong, c_ushort,
+ c_void, CString,
+};
+use std::ptr;
+
+const PARCEL_ERROR_NONE: i32 = 0;
+const PARCEL_ERROR_ILLEGAL_BYTE_SEQ: i32 = -EILSEQ;
+const PARCEL_ERROR_INVALID_PARAMETER: i32 = -EINVAL;
+const PARCEL_ERROR_NO_DATA: i32 = -ENODATA;
+const PARCEL_ERROR_OUT_OF_MEMORY: i32 = -ENOMEM;
+
+#[link(name = "parcel")]
+extern "C" {
+ fn parcel_create(parcel: *mut *mut c_void) -> c_int;
+ fn parcel_destroy(parcel: *mut c_void) -> c_int;
+ fn parcel_clone(parcel: *const c_void, clone: *mut *mut c_void) -> c_int;
+ fn parcel_burst_write(parcel: *mut c_void, buf: *const c_uchar, size: usize) -> c_int;
+ fn parcel_burst_read(parcel: *mut c_void, buf: *mut c_uchar, size: usize) -> c_int;
+ fn parcel_write_bool(parcel: *mut c_void, val: c_int) -> c_int;
+ fn parcel_write_byte(parcel: *mut c_void, val: c_char) -> c_int;
+ fn parcel_write_uint16(parcel: *mut c_void, val: c_ushort) -> c_int;
+ fn parcel_write_uint32(parcel: *mut c_void, val: c_uint) -> c_int;
+ fn parcel_write_uint64(parcel: *mut c_void, val: c_ulonglong) -> c_int;
+ fn parcel_write_int16(parcel: *mut c_void, val: c_short) -> c_int;
+ fn parcel_write_int32(parcel: *mut c_void, val: c_int) -> c_int;
+ fn parcel_write_int64(parcel: *mut c_void, val: c_longlong) -> c_int;
+ fn parcel_write_float(parcle: *mut c_void, val: c_float) -> c_int;
+ fn parcel_write_double(parcel: *mut c_void, val: c_double) -> c_int;
+ fn parcel_write_string(parcel: *mut c_void, val: *const c_char) -> c_int;
+ fn parcel_read_bool(parcel: *mut c_void, val: *mut c_int) -> c_int;
+ fn parcel_read_byte(parcel: *mut c_void, val: *mut c_char) -> c_int;
+ fn parcel_read_uint16(parcel: *mut c_void, val: *mut c_ushort) -> c_int;
+ fn parcel_read_uint32(parcel: *mut c_void, val: *mut c_uint) -> c_int;
+ fn parcel_read_uint64(parcel: *mut c_void, val: *mut c_ulonglong) -> c_int;
+ fn parcel_read_int16(parcel: *mut c_void, val: *mut c_short) -> c_int;
+ fn parcel_read_int32(parcel: *mut c_void, val: *mut c_int) -> c_int;
+ fn parcel_read_int64(parcel: *mut c_void, val: *mut c_longlong) -> c_int;
+ fn parcel_read_float(parcel: *mut c_void, val: *mut c_float) -> c_int;
+ fn parcel_read_double(parcel: *mut c_void, val: *mut c_double) -> c_int;
+ fn parcel_read_string(parcel: *mut c_void, val: *mut *mut c_char) -> c_int;
+ fn parcel_reset_reader(parcel: *mut c_void) -> c_int;
+ fn parcel_clear(parcel: *mut c_void) -> c_int;
+ fn parcel_reset(parcel: *mut c_void, buf: *const c_void, size: c_uint) -> c_int;
+ fn parcel_get_raw(parcel: *mut c_void, buf: *mut *mut c_void, size: *mut c_uint) -> c_int;
+}
+
+/// Represents errors that can occur when working with a `Parcel`.
+#[derive(Debug, PartialEq)]
+pub enum ParcelError {
+ /// Illegal byte sequence.
+ /// The data in the parcel is not valid.
+ /// This error occurs when the data is not encoded properly or the data is corrupted.
+ IllegalByteSeq,
+ /// Invalid parameter.
+ /// The input parameter is invalid. This error occurs when the input parameter is out of range.
+ InvalidParameter,
+ /// No data available.
+ /// There is no data to read. This error occurs when there is no more data to read from the parcel.
+ NoData,
+ /// Out of memory.
+ /// There is not enough memory to complete the operation. This error occurs when the memory allocation fails.
+ OutOfMemory,
+}
+
+impl ParcelError {
+ fn from_c_int(result: c_int) -> ParcelError {
+ match result {
+ PARCEL_ERROR_ILLEGAL_BYTE_SEQ => ParcelError::IllegalByteSeq,
+ PARCEL_ERROR_INVALID_PARAMETER => ParcelError::InvalidParameter,
+ PARCEL_ERROR_NO_DATA => ParcelError::NoData,
+ PARCEL_ERROR_OUT_OF_MEMORY => ParcelError::OutOfMemory,
+ _ => panic!("Unexpected error code {}", result),
+ }
+ }
+}
+
+/// A representation of a Parcel, which is used for serializing and deserializing data.
+#[derive(Debug)]
+pub struct Parcel {
+ handle: *mut c_void,
+}
+
+/// A trait that defines how a type can be serialized to and deserialized from a Parcel.
+pub trait Parcelable<T> {
+ fn to_parcel(&self) -> Parcel;
+ fn from_parcel(parcel: &mut Parcel) -> T;
+}
+
+impl Clone for Parcel {
+ fn clone(&self) -> Self {
+ let mut clone_handle: *mut c_void = ptr::null_mut();
+ unsafe {
+ let result = parcel_clone(self.handle, &mut clone_handle);
+ assert!(result == PARCEL_ERROR_NONE, "Failed to clone a parcel")
+ };
+ Self {
+ handle: clone_handle,
+ }
+ }
+}
+
+impl Drop for Parcel {
+ fn drop(&mut self) {
+ unsafe {
+ parcel_destroy(self.handle);
+ }
+ }
+}
+
+impl Default for Parcel {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Parcel {
+ /// Creates a new `Parcel` instance.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the creation of a `Parcel` fails.
+ pub fn new() -> Self {
+ let mut handle: *mut c_void = ptr::null_mut();
+ unsafe {
+ let result = parcel_create(&mut handle);
+ assert!(result == PARCEL_ERROR_NONE, "Failed to create a parcel");
+ }
+ Self { handle }
+ }
+
+ /// Writes a byte slice to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `data` - A slice of bytes to be written to the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write(&mut self, data: &[u8]) -> Result<(), ParcelError> {
+ let result = unsafe {
+ parcel_burst_write(self.handle, data.as_ptr(), data.len())
+ };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Reads a byte slice from the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `size` - The number of bytes to read from the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns a `Vec<u8>` containing the data read on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read(&mut self, size: usize) -> Result<Vec<u8>, ParcelError> {
+ let mut data = vec![0; size];
+ let result = unsafe { parcel_burst_read(self.handle, data.as_mut_ptr(), data.len()) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(data)
+ }
+ }
+
+ /// Gets the raw data from the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns a `Vec<u8>` containing the raw data on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn get_raw_data(&self) -> Result<Vec<u8>, ParcelError> {
+ let mut size = 0;
+ let mut raw: *mut c_void = ptr::null_mut();
+ let result = unsafe { parcel_get_raw(self.handle, &mut raw, &mut size) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ let mut data = vec![0; size as usize];
+ unsafe {
+ std::ptr::copy(raw as *const u8, data.as_mut_ptr(), size as usize);
+ }
+ Ok(data)
+ }
+ }
+
+ /// Resets the reader position of the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn reset_reader(&mut self) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_reset_reader(self.handle) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Clears the contents of the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn clear(&mut self) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_clear(self.handle) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Resets the `Parcel` with the provided data.
+ ///
+ /// # Arguments
+ ///
+ /// * `data` - The slice of bytes to reset the `Parcel`.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn reset(&mut self, data: &[u8]) -> Result<(), ParcelError> {
+ let result = unsafe {
+ parcel_reset(
+ self.handle,
+ data.as_ptr() as *const c_void,
+ data.len() as c_uint,
+ )
+ };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a boolean value to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The boolean value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_bool(&mut self, val: bool) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_bool(self.handle, val as c_int) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 8-bit integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 8-bit integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_i8(&mut self, val: i8) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_byte(self.handle, val as c_char) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 16-bit integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 16-bit integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_i16(&mut self, val: i16) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_int16(self.handle, val as c_short) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 32-bit integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 32-bit integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_i32(&mut self, val: i32) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_int32(self.handle, val as c_int) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 64-bit integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 64-bit integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_i64(&mut self, val: i64) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_int64(self.handle, val as c_longlong) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 16-bit unsigned integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 16-bit unsigned integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_u16(&mut self, val: u16) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_uint16(self.handle, val as c_ushort) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 32-bit unsigned integer to the `Parcel`.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 32-bit unsigned integer value to be written.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_u32(&mut self, val: u32) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_uint32(self.handle, val as c_uint) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 64-bit unsigned integer to the parcel.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 64-bit unsigned integer value to write.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_u64(&mut self, val: u64) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_uint64(self.handle, val as c_ulonglong) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 32-bit floating point to the parcel.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 32-bit floating point value to write.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_f32(&mut self, val: f32) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_float(self.handle, val) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a 64-bit floating point to the parcel.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The 64-bit floating point value to write.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_f64(&mut self, val: f64) -> Result<(), ParcelError> {
+ let result = unsafe { parcel_write_double(self.handle, val) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Writes a string to the parcel.
+ ///
+ /// # Arguments
+ ///
+ /// * `val` - The string value to write.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(())` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn write_string(&mut self, val: &str) -> Result<(), ParcelError> {
+ let ptr = CString::new(val).unwrap();
+ let result = unsafe { parcel_write_string(self.handle, ptr.as_ptr() as *const c_char) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(())
+ }
+ }
+
+ /// Reads a boolean from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(bool)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_bool(&mut self) -> Result<bool, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_bool(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value != 0)
+ }
+ }
+
+ /// Reads a 8-bit interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(i8)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_i8(&mut self) -> Result<i8, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_byte(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value as i8)
+ }
+ }
+
+ /// Reads a 16-bit interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(i16)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_i16(&mut self) -> Result<i16, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_int16(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 32-bit interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(i32)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_i32(&mut self) -> Result<i32, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_int32(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 64-bit interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(i64)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_i64(&mut self) -> Result<i64, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_int64(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 16-bit unsigned interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(u16)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_u16(&mut self) -> Result<u16, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_uint16(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 32-bit unsigned interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(u32)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_u32(&mut self) -> Result<u32, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_uint32(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 64-bit unsigned interger from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(u64)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_u64(&mut self) -> Result<u64, ParcelError> {
+ let mut value = 0;
+ let result = unsafe { parcel_read_uint64(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 32-bit floating point from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(f32)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_f32(&mut self) -> Result<f32, ParcelError> {
+ let mut value = 0.0;
+ let result = unsafe { parcel_read_float(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a 64-bit floating point from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(f64)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_f64(&mut self) -> Result<f64, ParcelError> {
+ let mut value = 0.0;
+ let result = unsafe { parcel_read_double(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(value)
+ }
+ }
+
+ /// Reads a string from the parcel.
+ ///
+ /// # Returns
+ ///
+ /// Returns `Ok(String)` on success, or an appropriate `Err(ParcelError)` on failure.
+ pub fn read_string(&mut self) -> Result<String, ParcelError> {
+ let mut value: *mut c_char = ptr::null_mut();
+ let result = unsafe { parcel_read_string(self.handle, &mut value) };
+ if result != PARCEL_ERROR_NONE {
+ Err(ParcelError::from_c_int(result))
+ } else {
+ Ok(unsafe { CString::from_raw(value).into_string().unwrap() })
+ }
+ }
+}