#include "src/objects/js-temporal-zoneinfo64.h"
#include <iostream>
#include "src/base/logging.h"
#include "temporal_rs/Provider.hpp"
#include "temporal_rs/TimeZone.hpp"
#ifdef V8_INTL_SUPPORT
#include "udatamem.h"
#else
extern "C" uint32_t zoneinfo64_static_data[];
extern "C" size_t zoneinfo64_static_data_len;
#endif
namespace v8::internal {
ZoneInfo64Provider::ZoneInfo64Provider() {
#ifdef V8_INTL_SUPPORT
UErrorCode status = U_ZERO_ERROR;
memory = udata_open(0, "res", "zoneinfo64", &status);
if (U_FAILURE(status)) {
DCHECK_WITH_MSG(false, "Failed to open zoneinfo64.res");
provider = temporal_rs::Provider::empty();
return;
}
auto length = memory->length;
const void* data = udata_getRawMemory(memory);
DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should align udata to uint32_t");
if (length % 4 != 0) {
provider = temporal_rs::Provider::empty();
return;
}
const uint32_t* data_32 = static_cast<const uint32_t*>(data);
std::span<const uint32_t> data_span(data_32, length / 4);
#else
std::span<const uint32_t> data_span(zoneinfo64_static_data,
zoneinfo64_static_data_len);
#endif
auto result = temporal_rs::Provider::new_zoneinfo64(data_span);
DCHECK_WITH_MSG(result.is_ok(), "Baked-in zoneinfo64 file must parse");
if (result.is_ok()) {
provider = std::move(result).ok().value();
} else {
provider = temporal_rs::Provider::empty();
}
}
ZoneInfo64Provider& ZoneInfo64Provider::Singleton() {
static ZoneInfo64Provider* SINGLETON = new ZoneInfo64Provider();
return *SINGLETON;
}
ZoneInfo64Provider::~ZoneInfo64Provider() {
provider = nullptr;
#ifdef V8_INTL_SUPPORT
if (memory) {
udata_close(memory);
}
#endif
}
}