1111#include " temporal_rs/TimeZone.hpp"
1212
1313#ifdef V8_INTL_SUPPORT
14+ #ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
15+ // ICU internal header file
1416#include " udatamem.h"
1517#else
18+ /* *
19+ * Shadow definition of UDataMemory
20+ * This is functionally identical to the definition in udatamem.h
21+ * Irrelevant fields are marked 'ignored' and should not be used.
22+ *
23+ * This definition is copied here so that the result of udata_open()
24+ * can be used and length-checked without needing to resort to
25+ * calling internal ICU functions.
26+ *
27+ * Note, there is an ICU ticket,
28+ * https://unicode-org.atlassian.net/browse/ICU-23400
29+ * to consider whether the API surface should be changed
30+ * here. If and when this is done, such an API could be used.
31+ */
32+ struct UDataMemoryShadow {
33+ const void * ignored1;
34+ const void * data; // < pointer to header of data object
35+ const void * ignored2;
36+ UBool ignored3;
37+ void * ignored4;
38+ void * ignored5;
39+ int32_t
40+ length; // < length of entire region pointed to by data if known, else -1
41+ };
42+ #endif
43+ #else
1644// Defined in builtins-temporal-zoneinfo64-data.cc, generated by
1745// include-file-as-bytes.py
1846extern " C" uint32_t zoneinfo64_static_data[];
@@ -30,17 +58,29 @@ ZoneInfo64Provider::ZoneInfo64Provider() {
3058 provider = temporal_rs::Provider::empty ();
3159 return ;
3260 }
61+ #ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
3362 // NOT udata_getLength: this ignores the header,
3463 // and we're parsing resb files with the header
3564 auto length = memory->length ;
3665 const void * data = udata_getRawMemory (memory);
37- DCHECK_WITH_MSG (length % 4 == 0 , " ICU4C should align udata to uint32_t" );
38- if (length % 4 != 0 ) {
39- // This really shouldn't happen: ICU4C aligns these files
40- // to 4 when baking them in
66+ #else
67+ // reinterpret with a local struct
68+ const UDataMemoryShadow* shadowMemory =
69+ reinterpret_cast <const UDataMemoryShadow*>(memory);
70+ // just need the length and data
71+ auto length = shadowMemory->length ;
72+ auto data = shadowMemory->data ;
73+ #endif
74+ // This really shouldn't happen: ICU4C pads these files
75+ // to 4 when baking them in
76+ DCHECK_WITH_MSG (length % 4 == 0 , " ICU4C should pad udata to uint32_t" );
77+ // Length may not be known. If we're not OK with that, don't proceed.
78+ DCHECK_WITH_MSG (length != -1 , " ICU4C usually knows the length" );
79+ if (length % 4 != 0 || length == -1 ) {
4180 provider = temporal_rs::Provider::empty ();
4281 return ;
4382 }
83+ DCHECK_WITH_MSG (data != nullptr , " ICU4C returned nullptr" );
4484
4585 const uint32_t * data_32 = static_cast <const uint32_t *>(data);
4686 std::span<const uint32_t > data_span (data_32, length / 4 );
0 commit comments