Skip to content

Commit 93f9637

Browse files
committed
Remove the last piece of cinterop
1 parent a70dcf5 commit 93f9637

File tree

4 files changed

+55
-47
lines changed

4 files changed

+55
-47
lines changed

core/build.gradle.kts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,26 +149,6 @@ kotlin {
149149
compilations["test"].kotlinOptions {
150150
freeCompilerArgs += listOf("-trw")
151151
}
152-
when {
153-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.MINGW -> {
154-
compilations["main"].cinterops {
155-
create("declarations") {
156-
defFile("$projectDir/windows/cinterop/definitions.def")
157-
headers("$projectDir/windows/cinterop/definitions.h")
158-
}
159-
}
160-
}
161-
162-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.LINUX ||
163-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.ANDROID ||
164-
konanTarget.family.isAppleFamily ->
165-
{
166-
// do nothing special
167-
}
168-
else -> {
169-
throw IllegalArgumentException("Unknown native target ${this@withType}")
170-
}
171-
}
172152
}
173153
sourceSets {
174154
commonMain {

core/windows/cinterop/definitions.def

Lines changed: 0 additions & 1 deletion
This file was deleted.

core/windows/cinterop/definitions.h

Lines changed: 0 additions & 11 deletions
This file was deleted.

core/windows/src/internal/TzdbInRegistry.kt

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package kotlinx.datetime.internal
88
import kotlinx.datetime.*
99
import kotlinx.cinterop.*
1010
import platform.windows.*
11+
import kotlin.experimental.*
1112

1213
internal class TzdbInRegistry: TimeZoneDatabase {
1314

@@ -78,7 +79,7 @@ internal class TzdbInRegistry: TimeZoneDatabase {
7879
private const val MAX_KEY_LENGTH = 128
7980
private const val KEY_BUFFER_SIZE = MAX_KEY_LENGTH + 1
8081

81-
internal fun processTimeZonesInRegistry(onTimeZone: (String, PerYearZoneRulesData, List<Pair<Int, PerYearZoneRulesData>>) -> Unit) {
82+
private fun processTimeZonesInRegistry(onTimeZone: (String, PerYearZoneRulesData, List<Pair<Int, PerYearZoneRulesData>>) -> Unit) {
8283
memScoped {
8384
alloc<HKEYVar>().withRegistryKey(HKEY_LOCAL_MACHINE!!, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", { err ->
8485
throw IllegalStateException("Error while opening the registry to fetch the time zones (err = $err): ${getLastWindowsError()}")
@@ -167,23 +168,62 @@ private class RegistryTimeZoneInfoBuffer private constructor(
167168
private val buffer: CPointer<BYTEVar>,
168169
private val cbData: DWORDVar,
169170
) {
171+
/**
172+
* The data structure is described at
173+
* https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/ns-timezoneapi-time_zone_information, as
174+
* `_REG_TZI_FORMAT`:
175+
*
176+
* ```
177+
* // 16 bytes
178+
* typedef struct {
179+
* uint16_t wYear;
180+
* uint16_t wMonth;
181+
* uint16_t wDayOfWeek;
182+
* uint16_t wDay;
183+
* uint16_t wHour;
184+
* uint16_t wMinute;
185+
* uint16_t wSecond;
186+
* uint16_t wMilliseconds;
187+
* } SYSTEMTIME;
188+
*
189+
* // 44 bytes
190+
* typedef struct _REG_TZI_FORMAT
191+
* {
192+
* int32_t Bias;
193+
* int32_t StandardBias;
194+
* int32_t DaylightBias;
195+
* SYSTEMTIME StandardDate;
196+
* SYSTEMTIME DaylightDate;
197+
* } REG_TZI_FORMAT;
198+
* ```
199+
*/
170200
companion object {
171201
fun allocate(scope: MemScope, cbData: DWORDVar): RegistryTimeZoneInfoBuffer =
172-
RegistryTimeZoneInfoBuffer(scope.allocArray<BYTEVar>(sizeOf<REG_TZI_FORMAT>().convert()), cbData)
202+
RegistryTimeZoneInfoBuffer(scope.allocArray<BYTEVar>(SIZE_BYTES), cbData)
203+
204+
private val SIZE_BYTES = 44
173205
}
174206

207+
@OptIn(ExperimentalNativeApi::class)
175208
fun readZoneRules(tzHKey: HKEY, name: String): PerYearZoneRulesData {
176-
getRegistryValue(cbData, buffer, sizeOf<REG_TZI_FORMAT>().convert(), tzHKey, name)
177-
return with(buffer.reinterpret<REG_TZI_FORMAT>().pointed) {
178-
val standardOffset = UtcOffset(minutes = -(StandardBias + Bias))
179-
val daylightOffset = UtcOffset(minutes = -(DaylightBias + Bias))
180-
if (DaylightDate.wMonth == 0.convert<WORD>()) {
181-
return PerYearZoneRulesData(standardOffset, null)
182-
}
183-
val changeToDst = RecurringZoneRules.Rule(DaylightDate.toMonthDayTime(), standardOffset, daylightOffset)
184-
val changeToStd = RecurringZoneRules.Rule(StandardDate.toMonthDayTime(), daylightOffset, standardOffset)
185-
PerYearZoneRulesData(standardOffset, changeToDst to changeToStd)
209+
getRegistryValue(cbData, buffer, SIZE_BYTES.convert(), tzHKey, name)
210+
// convert the buffer to a byte array
211+
val byteArray = buffer.readBytes(SIZE_BYTES)
212+
// obtaining raw data
213+
val bias = byteArray.getIntAt(0)
214+
val standardBias = byteArray.getIntAt(4)
215+
val daylightBias = byteArray.getIntAt(8)
216+
val standardDate = (buffer + 12)!!.reinterpret<SYSTEMTIME>().pointed
217+
val daylightDate = (buffer + 28)!!.reinterpret<SYSTEMTIME>().pointed
218+
// calculating the things we're interested in
219+
val standardOffset = UtcOffset(minutes = -(standardBias + bias))
220+
val daylightOffset = UtcOffset(minutes = -(daylightBias + bias))
221+
if (daylightDate.wMonth == 0.convert<WORD>()) {
222+
return PerYearZoneRulesData(standardOffset, null)
186223
}
224+
val changeToDst = RecurringZoneRules.Rule(daylightDate.toMonthDayTime(), standardOffset, daylightOffset)
225+
val changeToStd = RecurringZoneRules.Rule(standardDate.toMonthDayTime(), daylightOffset, standardOffset)
226+
return PerYearZoneRulesData(standardOffset, changeToDst to changeToStd)
187227
}
188228
}
189229

@@ -230,9 +270,9 @@ private fun SYSTEMTIME.toMonthDayTime(): MonthDayTime {
230270
return MonthDayTime(MonthDayOfYear(month, transitionDay), localTime, MonthDayTime.OffsetResolver.WallClockOffset)
231271
}
232272

233-
internal class PerYearZoneRulesData(
234-
val standardOffset: UtcOffset,
235-
val transitions: Pair<RecurringZoneRules.Rule<MonthDayTime>, RecurringZoneRules.Rule<MonthDayTime>>?,
273+
private class PerYearZoneRulesData(
274+
val standardOffset: UtcOffset,
275+
val transitions: Pair<RecurringZoneRules.Rule<MonthDayTime>, RecurringZoneRules.Rule<MonthDayTime>>?,
236276
) {
237277
override fun toString(): String = "standard offset is $standardOffset" + (transitions?.let {
238278
", the transitions: ${it.first}, ${it.second}"

0 commit comments

Comments
 (0)