Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 100
ColumnLimit: 120
---
Language: Cpp
SortIncludes: false
Expand Down
2 changes: 1 addition & 1 deletion haiku/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "iana-time-zone-haiku"
description = "iana-time-zone support crate for Haiku OS"
version = "0.1.2"
version = "0.1.3"
authors = ["René Kijewski <crates.io@k6i.de>"]
repository = "https://github.com/strawlab/iana-time-zone"
license = "MIT OR Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion haiku/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn main() {
.warnings(false)
.cpp(true)
.file("src/implementation.cc")
.flag_if_supported("-std=c++11")
.flag_if_supported("-std=c++17")
.compile("tz_haiku");

println!("cargo:rerun-if-changed=src/lib.rs");
Expand Down
84 changes: 52 additions & 32 deletions haiku/src/implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,59 +9,79 @@
#include <String.h>
#include <TimeZone.h>

extern "C" {
/**
* @brief Retrieves the IANA time zone identifier on Haiku.
*
* This function obtains the default time zone from the Haiku Locale Roster and writes its IANA
* time zone identifier into the provided buffer.
*
* @param buf Pointer to a character buffer where the time zone identifier will be stored.
* @param buf_size The size of the buffer pointed to by @a buf.
* @return The length of the time zone identifier written into @a buf (excluding the null terminator),
* or 0 if an error occurs (e.g., invalid parameters, failure to retrieve the time zone,
* or insufficient buffer size).
*
* @note If the buffer is large enough, the function guarantees that the output is null-terminated.
*
* @warning This function is marked as noexcept; it will not throw exceptions. In case of any
* internal error, the function will simply return 0.
*/
extern "C" [[nodiscard]] auto iana_time_zone_haiku_get_tz(char* buf, const std::size_t buf_size) noexcept
-> std::size_t {
if (buf == nullptr || buf_size == 0) {
return 0;
}

size_t iana_time_zone_haiku_get_tz(char *buf, size_t buf_size) {
try {
static_assert(sizeof(char) == sizeof(uint8_t), "Illegal char size");

if (buf_size == 0) {
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) {
// Retrieve the default locale roster (statically allocated object)
BLocaleRoster* locale_roster = BLocaleRoster::Default();
if (locale_roster == nullptr) {
return 0;
}

BTimeZone tz(NULL, NULL);
if (locale_roster->GetDefaultTimeZone(&tz) != B_OK) {
BTimeZone timezone(nullptr, nullptr);
if (locale_roster->GetDefaultTimeZone(&timezone) != B_OK) {
return 0;
}

BString bname(tz.ID());
int32_t ilength(bname.Length());
if (ilength <= 0) {
const BString bname = timezone.ID();
const auto raw_length = bname.Length();
if (raw_length <= 0) {
return 0;
}

size_t length(ilength);
if (length > buf_size) {
const auto length = static_cast<std::size_t>(raw_length);
// Ensure there is room for the null terminator without doing an addition that might overflow.
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, sname, length);
bname.CopyInto(buf, 0, raw_length);
// Insert the null terminator.
buf[length] = '\0';
return length;
} catch (const std::exception& /*e*/) {
return 0;
} catch (...) {
return 0;
}
}
} // extern "C"

#else

extern "C" {

size_t iana_time_zone_haiku_get_tz(char *buf, size_t buf_size) { return 0; }
} // extern "C"
/**
* @brief Dummy implementation for non-Haiku platforms.
*
* On non-Haiku platforms, this function does nothing and always returns 0.
*
* @param buf Pointer to a character buffer (unused).
* @param buf_size The size of the buffer (unused).
* @return Always returns 0.
*/
extern "C" [[nodiscard]] auto iana_time_zone_haiku_get_tz([[maybe_unused]] char* buf,
[[maybe_unused]] const std::size_t buf_size) noexcept
-> std::size_t {
return 0;
}

#endif
1 change: 1 addition & 0 deletions haiku/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use std::os::raw::c_char;

extern "C" {
#[must_use]
fn iana_time_zone_haiku_get_tz(buf: *mut c_char, buf_size: usize) -> usize;
}

Expand Down
Loading