commonMain.mqtt.TopicUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kmqtt-common-jvm Show documentation
Show all versions of kmqtt-common-jvm Show documentation
Kotlin Multiplatform MQTT client & embeddable and standalone broker
package mqtt
public fun String.containsWildcard(): Boolean {
return this.contains("#") || this.contains("+")
}
public fun String.isValidTopic(): Boolean {
if (this.isEmpty())
return false
if (this.contains("#")) {
if (this.count { it.toString().contains("#") } > 1 || (this != "#" && !this.endsWith("/#")))
return false
}
if (this.contains("+")) {
for (i in 0 until length) {
if (this[i] == '+') {
val previousCharacter = this.getOrNull(i - 1)
val nextCharacter = this.getOrNull(i + 1)
if (!((previousCharacter == '/' || previousCharacter == null) && (nextCharacter == '/' || nextCharacter == null)))
return false
}
}
}
return true
}
public fun String.matchesWildcard(wildcardTopic: String): Boolean {
if (this.containsWildcard())
return false
if (!this.isValidTopic() || !wildcardTopic.isValidTopic())
return false
// The Server MUST NOT match Topic Filters starting with a wildcard character (# or +) with Topic Names beginning with a $ character
if ((wildcardTopic.startsWith("+") || wildcardTopic.startsWith("#")) && this.startsWith("$"))
return false
if (this == wildcardTopic) {
return true
}
var positionTopic = 0
var positionTopicFilter = 0
while (positionTopic < this.length && positionTopicFilter < wildcardTopic.length) {
if (this[positionTopic] == wildcardTopic[positionTopicFilter]) {
positionTopic++
positionTopicFilter++
continue
} else if (wildcardTopic[positionTopicFilter] != '#' && wildcardTopic[positionTopicFilter] != '+') {
break
}
if (wildcardTopic[positionTopicFilter] == '#') {
return true
} else if (wildcardTopic[positionTopicFilter] == '+') {
while (positionTopic < this.length && this[positionTopic] != '/') {
positionTopic++
}
positionTopicFilter++
if (wildcardTopic.getOrNull(positionTopicFilter) != '/') {
break
}
}
}
if (positionTopicFilter < wildcardTopic.length) {
if (wildcardTopic[positionTopicFilter] == '/' && wildcardTopic[positionTopicFilter + 1] == '#') {
return true
}
}
return positionTopic == this.length && positionTopicFilter == wildcardTopic.length
}
public fun String.isSharedTopicFilter(): Boolean {
val split = this.split("/")
if (split.size < 3)
return false
return split[0] == "\$share" && split[1].isNotEmpty() && !split[1].contains("+") && !split[1].contains("#") && this.substringAfter(
split[1] + "/"
).isValidTopic()
}
public fun String.getSharedTopicFilter(): String? {
if (isSharedTopicFilter()) {
val split = this.split("/")
return this.substringAfter(split[1] + "/")
}
return null
}
public fun String.getSharedTopicShareName(): String? {
if (isSharedTopicFilter()) {
val split = this.split("/")
return split[1]
}
return null
}