diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 6eba5b71c..b026ad12e 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -116,7 +116,7 @@ jobs: api-level: 36 target: google_apis arch: x86_64 - script: ./gradlew connectedCheck + script: ./gradlew androidConnectedCheck - name: Upload test results uses: actions/upload-artifact@v4 if: failure() diff --git a/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/Collection.linuxMingw.kt b/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/Collection.linuxMingw.kt index 0c968fac3..d7b6886a7 100644 --- a/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/Collection.linuxMingw.kt +++ b/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/Collection.linuxMingw.kt @@ -31,25 +31,25 @@ internal fun Collection.createIndexImpl(name: String, config: IndexConfiguration is ValueIndexConfiguration -> CBLCollection_CreateValueIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) is FullTextIndexConfiguration -> CBLCollection_CreateFullTextIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) is ArrayIndexConfiguration -> CBLCollection_CreateArrayIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) is VectorIndexConfiguration -> CBLCollection_CreateVectorIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) } diff --git a/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/VectorIndexConfiguration.linuxMingw.kt b/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/VectorIndexConfiguration.linuxMingw.kt index 647fcd8e3..2dbd6fb5d 100644 --- a/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/VectorIndexConfiguration.linuxMingw.kt +++ b/couchbase-lite-ee/src/linuxMingwMain/ee/kotbase/VectorIndexConfiguration.linuxMingw.kt @@ -15,11 +15,12 @@ */ package kotbase +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue import kotlinx.cinterop.convert +import kotlinx.cinterop.cstr import libcblite.* -import platform.posix.strdup import platform.posix.strlen public actual class VectorIndexConfiguration @@ -103,21 +104,20 @@ public actual constructor( return this } - internal val actual: CValue - get() { - val exp = expression - return cValue { - centroids = this@VectorIndexConfiguration.centroids.convert() - dimensions = this@VectorIndexConfiguration.dimensions.convert() - encoding = this@VectorIndexConfiguration.encoding.actual - expression.buf = strdup(exp) - expression.size = strlen(exp) - expressionLanguage = kCBLN1QLLanguage - isLazy = this@VectorIndexConfiguration.isLazy - maxTrainingSize = this@VectorIndexConfiguration.maxTrainingSize.convert() - metric = this@VectorIndexConfiguration.metric.actual - minTrainingSize = this@VectorIndexConfiguration.minTrainingSize.convert() - numProbes = this@VectorIndexConfiguration.numProbes.convert() - } + internal fun actual(scope: AutofreeScope): CValue { + val exp = expression + return cValue { + centroids = this@VectorIndexConfiguration.centroids.convert() + dimensions = this@VectorIndexConfiguration.dimensions.convert() + encoding = this@VectorIndexConfiguration.encoding.actual + expression.buf = exp.cstr.getPointer(scope) + expression.size = strlen(exp) + expressionLanguage = kCBLN1QLLanguage + isLazy = this@VectorIndexConfiguration.isLazy + maxTrainingSize = this@VectorIndexConfiguration.maxTrainingSize.convert() + metric = this@VectorIndexConfiguration.metric.actual + minTrainingSize = this@VectorIndexConfiguration.minTrainingSize.convert() + numProbes = this@VectorIndexConfiguration.numProbes.convert() } + } } diff --git a/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLogSinkTest.kt b/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLogSinkTest.kt index 512c3a8b6..5b5d39e40 100644 --- a/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLogSinkTest.kt +++ b/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLogSinkTest.kt @@ -168,7 +168,7 @@ class KermitCouchbaseLiteLogSinkTest : BaseTest() { } private fun allowLogsToWrite() = runBlocking { - delay(50) + delay(100) } private fun Array.toTags() = ifEmpty { LogDomain.ALL.toTypedArray() } diff --git a/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLoggerTest.kt b/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLoggerTest.kt index 6abb7d611..7b8763c5d 100644 --- a/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLoggerTest.kt +++ b/couchbase-lite-kermit/src/commonTest/kotlin/kotbase/kermit/KermitCouchbaseLiteLoggerTest.kt @@ -172,7 +172,7 @@ class KermitCouchbaseLiteLoggerTest : BaseTest(useLegacyLogging = true) { } private fun allowLogsToWrite() = runBlocking { - delay(50) + delay(100) } private fun Set.toTags() = map { "CBL-${it.name}" }.toSet() diff --git a/couchbase-lite/src/linuxMingwMain/ce/kotbase/Collection.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/ce/kotbase/Collection.linuxMingw.kt index 7edf6a42e..0deee13dc 100644 --- a/couchbase-lite/src/linuxMingwMain/ce/kotbase/Collection.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/ce/kotbase/Collection.linuxMingw.kt @@ -29,19 +29,19 @@ internal fun Collection.createIndexImpl(name: String, config: IndexConfiguration is ValueIndexConfiguration -> CBLCollection_CreateValueIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) is FullTextIndexConfiguration -> CBLCollection_CreateFullTextIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) is ArrayIndexConfiguration -> CBLCollection_CreateArrayIndex( actual, name.toFLString(this), - config.actual, + config.actual(this), error ) } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ArrayIndexConfiguration.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ArrayIndexConfiguration.linuxMingw.kt index 47389348b..21dad9a8d 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ArrayIndexConfiguration.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ArrayIndexConfiguration.linuxMingw.kt @@ -15,11 +15,12 @@ */ package kotbase +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue +import kotlinx.cinterop.cstr import libcblite.CBLArrayIndexConfiguration import libcblite.kCBLN1QLLanguage -import platform.posix.strdup import platform.posix.strlen public actual class ArrayIndexConfiguration @@ -41,16 +42,15 @@ public actual constructor( } } - internal val actual: CValue - get() { - val exp = expressions.joinToString(separator = ",") - val path = path - return cValue { - expressionLanguage = kCBLN1QLLanguage - expressions.buf = strdup(exp) - expressions.size = strlen(exp) - this.path.buf = strdup(path) - this.path.size = strlen(path) - } + internal fun actual(scope: AutofreeScope): CValue { + val exp = expressions.joinToString(separator = ",") + val path = path + return cValue { + expressionLanguage = kCBLN1QLLanguage + expressions.buf = exp.cstr.getPointer(scope) + expressions.size = strlen(exp) + this.path.buf = path.cstr.getPointer(scope) + this.path.size = strlen(path) } + } } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Collection.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Collection.linuxMingw.kt index 2f0972298..5ff700769 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Collection.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Collection.linuxMingw.kt @@ -357,13 +357,13 @@ internal constructor( is ValueIndex -> CBLCollection_CreateValueIndex( actual, name.toFLString(this), - index.actual, + index.actual(this), error ) is FullTextIndex -> CBLCollection_CreateFullTextIndex( actual, name.toFLString(this), - index.actual, + index.actual(this), error ) else -> error("Unhandled Index type ${index::class}") diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Database.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Database.linuxMingw.kt index 19fed986f..43a89ccbd 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Database.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/Database.linuxMingw.kt @@ -723,13 +723,13 @@ internal constructor( is ValueIndex -> CBLDatabase_CreateValueIndex( actual, name.toFLString(this), - index.actual, + index.actual(this), error ) is FullTextIndex -> CBLDatabase_CreateFullTextIndex( actual, name.toFLString(this), - index.actual, + index.actual(this), error ) else -> error("Unhandled Index type ${index::class}") diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/DatabaseConfiguration.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/DatabaseConfiguration.linuxMingw.kt index a21bd0cc7..b62e8b264 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/DatabaseConfiguration.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/DatabaseConfiguration.linuxMingw.kt @@ -21,6 +21,7 @@ import kotlinx.io.files.SystemPathSeparator import libcblite.CBLDatabaseConfiguration import libcblite.CBLDatabaseConfiguration_Default import platform.posix.free +import platform.posix.memset import platform.posix.strdup import platform.posix.strlen import kotlin.experimental.ExperimentalNativeApi @@ -33,7 +34,10 @@ public actual constructor(config: DatabaseConfiguration?) { private val memory = object { val arena = Arena() - val actual = arena.alloc().ptr + val actual = arena.alloc().ptr.also { + // zero out struct to ensure free() isn't called on a garbage pointer + memset(it, 0, sizeOf().convert()) + } } @OptIn(ExperimentalNativeApi::class) diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FileLogger.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FileLogger.linuxMingw.kt index e0a9dc40a..62e2500e0 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FileLogger.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FileLogger.linuxMingw.kt @@ -33,9 +33,11 @@ public actual class FileLogger internal constructor() : Logger { if (value != null) { SystemFileSystem.createDirectories(Path(value.directory), false) } - val actual = value?.getActual(level) ?: LogFileConfiguration.getNullActual() - wrapCBLError { error -> - CBLLog_SetFileConfig(actual, error) + memScoped { + val actual = value?.getActual(level, this) ?: LogFileConfiguration.getNullActual() + wrapCBLError { error -> + CBLLog_SetFileConfig(actual, error) + } } } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndex.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndex.linuxMingw.kt index 6b1683de4..bf32bdb8a 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndex.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndex.linuxMingw.kt @@ -16,11 +16,12 @@ package kotbase import kotbase.internal.JsonUtils +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue +import kotlinx.cinterop.cstr import libcblite.CBLFullTextIndexConfiguration import libcblite.kCBLJSONLanguage -import platform.posix.strdup import platform.posix.strlen public actual class FullTextIndex @@ -50,17 +51,16 @@ internal constructor(private val items: List) : Index() { return JsonUtils.toJson(data) } - internal val actual: CValue - get() { - val json = getJson() - val lang = language - return cValue { - expressionLanguage = kCBLJSONLanguage - expressions.buf = strdup(json) - expressions.size = strlen(json) - language.buf = lang?.let { strdup(it) } - language.size = lang?.let { strlen(it) } ?: 0U - ignoreAccents = isIgnoringAccents - } + internal fun actual(scope: AutofreeScope): CValue { + val json = getJson() + val lang = language + return cValue { + expressionLanguage = kCBLJSONLanguage + expressions.buf = json.cstr.getPointer(scope) + expressions.size = strlen(json) + language.buf = lang?.cstr?.getPointer(scope) + language.size = lang?.let { strlen(it) } ?: 0U + ignoreAccents = isIgnoringAccents } + } } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndexConfiguration.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndexConfiguration.linuxMingw.kt index d939620eb..dfa28ecd7 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndexConfiguration.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/FullTextIndexConfiguration.linuxMingw.kt @@ -15,11 +15,12 @@ */ package kotbase +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue +import kotlinx.cinterop.cstr import libcblite.CBLFullTextIndexConfiguration import libcblite.kCBLN1QLLanguage -import platform.posix.strdup import platform.posix.strlen public actual class FullTextIndexConfiguration @@ -65,22 +66,21 @@ public actual constructor( public actual var where: String? = where - internal val actual: CValue - get() { - val exp = expressions.joinToString(separator = ",") - val lang = language - val whr = where - return cValue { - expressionLanguage = kCBLN1QLLanguage - expressions.buf = strdup(exp) - expressions.size = strlen(exp) - language.buf = lang?.let { strdup(it) } - language.size = lang?.let { strlen(it) } ?: 0U - where.buf = whr?.let { strdup(it) } - where.size = whr?.let { strlen(it) } ?: 0U - ignoreAccents = isIgnoringAccents - } + internal fun actual(scope: AutofreeScope): CValue { + val exp = expressions.joinToString(separator = ",") + val lang = language + val whr = where + return cValue { + expressionLanguage = kCBLN1QLLanguage + expressions.buf = exp.cstr.getPointer(scope) + expressions.size = strlen(exp) + language.buf = lang?.cstr?.getPointer(scope) + language.size = lang?.let { strlen(it) } ?: 0U + where.buf = whr?.cstr?.getPointer(scope) + where.size = whr?.let { strlen(it) } ?: 0U + ignoreAccents = isIgnoringAccents } + } internal actual companion object } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/LogFileConfiguration.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/LogFileConfiguration.linuxMingw.kt index d0e663d8d..9149f3961 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/LogFileConfiguration.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/LogFileConfiguration.linuxMingw.kt @@ -15,11 +15,12 @@ */ package kotbase +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue import kotlinx.cinterop.convert +import kotlinx.cinterop.cstr import libcblite.CBLLogFileConfiguration -import platform.posix.strdup import platform.posix.strlen public actual class LogFileConfiguration @@ -84,11 +85,11 @@ public actual constructor(public actual val directory: String) { override fun hashCode(): Int = directory.hashCode() - internal fun getActual(level: LogLevel): CValue { + internal fun getActual(level: LogLevel, scope: AutofreeScope): CValue { readonly = true return cValue { with(directory) { - buf = strdup(this@LogFileConfiguration.directory) + buf = this@LogFileConfiguration.directory.cstr.getPointer(scope) size = strlen(this@LogFileConfiguration.directory) } this.level = level.actual diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndex.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndex.linuxMingw.kt index ca83b8144..0ce6ef741 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndex.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndex.linuxMingw.kt @@ -16,11 +16,12 @@ package kotbase import kotbase.internal.JsonUtils +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue +import kotlinx.cinterop.cstr import libcblite.CBLValueIndexConfiguration import libcblite.kCBLJSONLanguage -import platform.posix.strdup import platform.posix.strlen public actual class ValueIndex @@ -35,13 +36,12 @@ internal constructor(private val items: List) : Index() { return JsonUtils.toJson(data) } - internal val actual: CValue - get() { - val json = getJson() - return cValue { - expressionLanguage = kCBLJSONLanguage - expressions.buf = strdup(json) - expressions.size = strlen(json) - } + internal fun actual(scope: AutofreeScope): CValue { + val json = getJson() + return cValue { + expressionLanguage = kCBLJSONLanguage + expressions.buf = json.cstr.getPointer(scope) + expressions.size = strlen(json) } + } } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndexConfiguration.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndexConfiguration.linuxMingw.kt index c19ab36fc..1b116714f 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndexConfiguration.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/ValueIndexConfiguration.linuxMingw.kt @@ -15,11 +15,12 @@ */ package kotbase +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue +import kotlinx.cinterop.cstr import libcblite.CBLValueIndexConfiguration import libcblite.kCBLN1QLLanguage -import platform.posix.strdup import platform.posix.strlen public actual class ValueIndexConfiguration @@ -43,16 +44,15 @@ public actual constructor( public actual var where: String? = null - internal val actual: CValue - get() { - val exp = expressions.joinToString(separator = ",") - val whr = where - return cValue { - expressionLanguage = kCBLN1QLLanguage - expressions.buf = strdup(exp) - expressions.size = strlen(exp) - where.buf = whr?.let { strdup(whr) } - where.size = whr?.let { strlen(whr) } ?: 0U - } + internal fun actual(scope: AutofreeScope): CValue { + val exp = expressions.joinToString(separator = ",") + val whr = where + return cValue { + expressionLanguage = kCBLN1QLLanguage + expressions.buf = exp.cstr.getPointer(scope) + expressions.size = strlen(exp) + where.buf = whr?.cstr?.getPointer(scope) + where.size = whr?.let { strlen(whr) } ?: 0U } + } } diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/FileLogSink.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/FileLogSink.linuxMingw.kt index 8f0ce7c7d..fcf79d5df 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/FileLogSink.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/FileLogSink.linuxMingw.kt @@ -17,13 +17,14 @@ package kotbase.logging import kotbase.LogLevel import kotbase.internal.fleece.toKString +import kotlinx.cinterop.AutofreeScope import kotlinx.cinterop.CValue import kotlinx.cinterop.cValue import kotlinx.cinterop.convert +import kotlinx.cinterop.cstr import kotlinx.cinterop.useContents import libcblite.CBLFileLogSink import libcblite.kCBLLogNone -import platform.posix.strdup import platform.posix.strlen internal fun CValue.asFileLogSink(): FileLogSink? { @@ -42,12 +43,13 @@ internal fun CValue.asFileLogSink(): FileLogSink? { } } -internal val FileLogSink?.actual: CValue - get() = cValue { +internal fun FileLogSink?.actual(scope: AutofreeScope): CValue { + return cValue { level = this@actual?.level?.actual ?: kCBLLogNone.convert() - directory.buf = this@actual?.directory?.let { strdup(it) } + directory.buf = this@actual?.directory?.cstr?.getPointer(scope) directory.size = this@actual?.directory?.let { strlen(it) } ?: 0U usePlaintext = this@actual?.isPlainText ?: false maxKeptFiles = this@actual?.maxKeptFiles?.convert() ?: 0U maxSize = this@actual?.maxFileSize?.convert() ?: 0UL } +} diff --git a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/LogSinks.linuxMingw.kt b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/LogSinks.linuxMingw.kt index 863c71d2b..534ab70d1 100644 --- a/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/LogSinks.linuxMingw.kt +++ b/couchbase-lite/src/linuxMingwMain/kotlin/kotbase/logging/LogSinks.linuxMingw.kt @@ -15,6 +15,7 @@ */ package kotbase.logging +import kotlinx.cinterop.memScoped import libcblite.CBLLogSinks_Console import libcblite.CBLLogSinks_File import libcblite.CBLLogSinks_SetConsole @@ -26,7 +27,9 @@ public actual object LogSinks { public actual var file: FileLogSink? get() = CBLLogSinks_File().asFileLogSink() set(value) { - CBLLogSinks_SetFile(value.actual) + memScoped { + CBLLogSinks_SetFile(value.actual(this)) + } } public actual var console: ConsoleLogSink?