| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
use crate::ffi_utils::buffer::{tzname_buf, MAX_LEN}; |
| 6 |
use crate::GetTimezoneError; |
| 7 |
use std::ffi::{c_char, CStr}; |
| 8 |
|
| 9 |
#[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| 10 |
#[repr(C)] |
| 11 |
#[allow(non_camel_case_types)] |
| 12 |
#[allow(dead_code)] |
| 13 |
enum TimeService_ErrCode { |
| 14 |
TIMESERVICE_ERR_OK = 0, |
| 15 |
TIMESERVICE_ERR_INTERNAL_ERROR = 13000001, |
| 16 |
TIMESERVICE_ERR_INVALID_PARAMETER = 13000002, |
| 17 |
} |
| 18 |
|
| 19 |
#[link(name = "time_service_ndk", kind = "dylib")] |
| 20 |
extern "C" { |
| 21 |
fn OH_TimeService_GetTimeZone(timeZone: *mut c_char, len: u32) -> TimeService_ErrCode; |
| 22 |
} |
| 23 |
|
| 24 |
|
| 25 |
fn from_bytes_until_nul(bytes: &[u8]) -> Option<&CStr> { |
| 26 |
let nul_pos = bytes.iter().position(|&b| b == 0)?; |
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
Some(unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[..=nul_pos]) }) |
| 31 |
} |
| 32 |
|
| 33 |
pub(crate) fn get_timezone_inner() -> Result<String, GetTimezoneError> { |
| 34 |
let mut time_zone = tzname_buf(); |
| 35 |
|
| 36 |
|
| 37 |
let ret = unsafe { |
| 38 |
OH_TimeService_GetTimeZone(time_zone.as_mut_ptr().cast::<c_char>(), MAX_LEN as u32 - 1) |
| 39 |
}; |
| 40 |
if ret != TimeService_ErrCode::TIMESERVICE_ERR_OK { |
| 41 |
return Err(GetTimezoneError::OsError); |
| 42 |
} |
| 43 |
from_bytes_until_nul(&time_zone) |
| 44 |
.and_then(|x| x.to_str().ok()) |
| 45 |
.map(|x| x.to_owned()) |
| 46 |
.ok_or(GetTimezoneError::OsError) |
| 47 |
} |