diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/iana-time-zone-haiku/src | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/iana-time-zone-haiku/src')
-rw-r--r-- | vendor/iana-time-zone-haiku/src/implementation.cc | 66 | ||||
-rw-r--r-- | vendor/iana-time-zone-haiku/src/interface.h | 9 | ||||
-rw-r--r-- | vendor/iana-time-zone-haiku/src/lib.rs | 68 |
3 files changed, 143 insertions, 0 deletions
diff --git a/vendor/iana-time-zone-haiku/src/implementation.cc b/vendor/iana-time-zone-haiku/src/implementation.cc new file mode 100644 index 000000000..35e130552 --- /dev/null +++ b/vendor/iana-time-zone-haiku/src/implementation.cc @@ -0,0 +1,66 @@ +#include "iana-time-zone-haiku/src/interface.h" +#include "iana-time-zone-haiku/src/lib.rs.h" + +#ifdef __HAIKU__ + +#include <cstring> + +#include <Errors.h> +#include <LocaleRoster.h> +#include <String.h> +#include <TimeZone.h> + +namespace iana_time_zone_haiku { +size_t get_tz(rust::Slice<uint8_t> buf) { + try { + static_assert(sizeof(char) == sizeof(uint8_t), "Illegal char size"); + + if (buf.empty()) { + return 0; + } + + // `BLocaleRoster::Default()` returns a reference to a statically allocated object. + // https://github.com/haiku/haiku/blob/8f16317/src/kits/locale/LocaleRoster.cpp#L143-L147 + BLocaleRoster *locale_roster(BLocaleRoster::Default()); + if (!locale_roster) { + return 0; + } + + BTimeZone tz(NULL, NULL); + if (locale_roster->GetDefaultTimeZone(&tz) != B_OK) { + return 0; + } + + BString bname(tz.ID()); + int32_t ilength(bname.Length()); + if (ilength <= 0) { + return 0; + } + + size_t length(ilength); + if (length > buf.size()) { + return 0; + } + + // BString::String() returns a borrowed string. + // https://www.haiku-os.org/docs/api/classBString.html#ae4fe78b06c8e3310093b80305e14ba87 + const char *sname(bname.String()); + if (!sname) { + return 0; + } + + std::memcpy(buf.data(), sname, length); + return length; + } catch (...) { + return 0; + } +} +} // namespace iana_time_zone_haiku + +#else + +namespace iana_time_zone_haiku { +size_t get_tz(rust::Slice<uint8_t>) { return 0; } +} // namespace iana_time_zone_haiku + +#endif diff --git a/vendor/iana-time-zone-haiku/src/interface.h b/vendor/iana-time-zone-haiku/src/interface.h new file mode 100644 index 000000000..5913a4043 --- /dev/null +++ b/vendor/iana-time-zone-haiku/src/interface.h @@ -0,0 +1,9 @@ +#pragma once + +#include "rust/cxx.h" + +#include <cstddef> + +namespace iana_time_zone_haiku { +size_t get_tz(rust::Slice<uint8_t> buf); +} diff --git a/vendor/iana-time-zone-haiku/src/lib.rs b/vendor/iana-time-zone-haiku/src/lib.rs new file mode 100644 index 000000000..55681a267 --- /dev/null +++ b/vendor/iana-time-zone-haiku/src/lib.rs @@ -0,0 +1,68 @@ +#![warn(clippy::all)] +#![warn(clippy::cargo)] +#![warn(clippy::undocumented_unsafe_blocks)] +#![allow(unknown_lints)] +#![warn(missing_copy_implementations)] +#![warn(missing_debug_implementations)] +#![warn(missing_docs)] +#![warn(rust_2018_idioms)] +#![warn(trivial_casts, trivial_numeric_casts)] +#![warn(unsafe_op_in_unsafe_fn)] +#![warn(unused_qualifications)] +#![warn(variant_size_differences)] + +//! # iana-time-zone-haiku +//! +//! [](https://crates.io/crates/iana-time-zone-haiku) +//! [](https://docs.rs/iana-time-zone/) +//! [](https://crates.io/crates/iana-time-zone-haiku) +//! [](https://github.com/strawlab/iana-time-zone/actions?query=branch%3Amaster) +//! +//! [iana-time-zone](https://github.com/strawlab/iana-time-zone) support crate for Haiku OS. + +#[cxx::bridge(namespace = "iana_time_zone_haiku")] +mod ffi { + // SAFETY: in here "unsafe" is simply part of the syntax + unsafe extern "C++" { + include!("iana-time-zone-haiku/src/interface.h"); + + fn get_tz(buf: &mut [u8]) -> usize; + } +} + +/// Get the current IANA time zone as a string. +/// +/// On Haiku platforms this function will return [`Some`] with the timezone string +/// or [`None`] if an error occurs. On all other platforms, [`None`] is returned. +/// +/// # Examples +/// +/// ``` +/// let timezone = iana_time_zone_haiku::get_timezone(); +/// ``` +pub fn get_timezone() -> Option<String> { + // The longest name in the IANA time zone database is 25 ASCII characters long. + let mut buf = [0u8; 32]; + let len = ffi::get_tz(&mut buf); + // The name should not be empty, or excessively long. + match buf.get(..len)? { + b"" => None, + s => Some(std::str::from_utf8(s).ok()?.to_owned()), + } +} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(not(target_os = "haiku"))] + fn test_fallback_on_non_haiku_platforms() { + assert!(super::get_timezone().is_none()); + } + + #[test] + #[cfg(target_os = "haiku")] + fn test_retrieve_time_zone_on_haiku_platforms() { + let timezone = super::get_timezone().unwrap(); + assert!(!timezone.is_empty()); + } +} |