Skip to content
Snippets Groups Projects
Verified Commit 8614d0f2 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Reorganize code and add readme

parent ace3dba0
No related branches found
No related tags found
No related merge requests found
Pipeline #594 passed
# Kotlin Bitflags
Kotlin-Bitflags is a utility library to simplify implementing bitflags in Kotlin. It integrates with Kotlin unsigned
types and Java Enumsets. This especially useful when interacting with binary protocols from Kotlin.
## Using Kotlin-Bitflags
After adding this module to your dependencies, you'll have to implement the related interfaces in your classes:
```kotlin
enum class MessageFlag(
override val value: UInt,
) : Flag<UInt> {
Self(0x01u),
Highlight(0x02u),
Redirected(0x04u),
ServerMsg(0x08u),
Backlog(0x80u);
companion object : Flags<UInt, MessageFlag> {
override val all: Set<MessageFlag> = values().toEnumSet()
}
}
```
This allows you to then use this elsewhere to e.g initialize a field from discrete values
```kotlin
// Construct from varargs or an array
val field = MessageFlag.of(MessageFlag.Self, MessageFlag.Highlight)
val values = listOf(MessageFlag.Self, MessageFlag.Highlight)
// Or from a collection
val field = MessageFlag.of(values)
// Or use the to helper
val field = values.toEnumSet()
```
You can also convert such a field into the raw binary value easily
```kotlin
// Returns in this case UInt
field.toBits()
```
Additional utility functions are available:
```kotlin
// Empty field
MessageFlag.none()
// Get all non-null values
MessageFlag.validValues()
```
......@@ -11,6 +11,7 @@
package de.justjanne.bitflags
import java.util.EnumSet
import kotlin.experimental.and
/**
* Construct a bitfield out of discrete flags
......@@ -25,3 +26,79 @@ inline fun <reified T> Flags<*, T>.of(vararg values: T): EnumSet<T>
*/
inline fun <reified T> Flags<*, T>.of(values: Collection<T>): EnumSet<T>
where T : Flag<*>, T : Enum<T> = values.toEnumSet()
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Byte, T>.of(value: Byte?): EnumSet<T> where T : Flag<Byte>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toByte() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UByte, T>.of(value: UByte?): EnumSet<T> where T : Flag<UByte>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toUByte() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Short, T>.of(value: Short?): EnumSet<T> where T : Flag<Short>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toShort() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UShort, T>.of(value: UShort?): EnumSet<T> where T : Flag<UShort>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toUShort() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Int, T>.of(value: Int?): EnumSet<T> where T : Flag<Int>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0 }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UInt, T>.of(value: UInt?): EnumSet<T> where T : Flag<UInt>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0u }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Long, T>.of(value: Long?): EnumSet<T> where T : Flag<Long>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0L }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<ULong, T>.of(value: ULong?): EnumSet<T> where T : Flag<ULong>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0uL }.toEnumSet()
}
/*
* Kotlin Bitflags
*
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.bitflags
import java.util.EnumSet
import kotlin.experimental.and
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Byte, T>.of(value: Byte?): EnumSet<T> where T : Flag<Byte>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toByte() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UByte, T>.of(value: UByte?): EnumSet<T> where T : Flag<UByte>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toUByte() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Short, T>.of(value: Short?): EnumSet<T> where T : Flag<Short>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toShort() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UShort, T>.of(value: UShort?): EnumSet<T> where T : Flag<UShort>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0.toUShort() }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Int, T>.of(value: Int?): EnumSet<T> where T : Flag<Int>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0 }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<UInt, T>.of(value: UInt?): EnumSet<T> where T : Flag<UInt>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0u }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
inline fun <reified T> Flags<Long, T>.of(value: Long?): EnumSet<T> where T : Flag<Long>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0L }.toEnumSet()
}
/**
* Construct a bitfield out of a binary value
* @return bitfield
*/
@ExperimentalUnsignedTypes
inline fun <reified T> Flags<ULong, T>.of(value: ULong?): EnumSet<T> where T : Flag<ULong>, T : Enum<T> {
if (value == null) return emptyList<T>().toEnumSet()
return all.filter { (value and it.value) != 0uL }.toEnumSet()
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment