Skip to content
This repository was archived by the owner on Aug 18, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions build.gradle

This file was deleted.

74 changes: 74 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import org.gradle.internal.jvm.Jvm
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferPlugin

plugins {
alias(libs.plugins.animalsniffer) apply false
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.mavenPublish)
}

kotlin {
jvm {
withJava() // Required for Animal Sniffer to work.
}
jvmToolchain(11)

iosX64()
iosArm64()
iosSimulatorArm64()

sourceSets {
val commonMain by getting

val commonTest by getting {
dependencies {
implementation(libs.kotlin.test.junit)
}
}

val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}

val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val iosTest by creating {
dependsOn(commonTest)
iosX64Test.dependsOn(this)
iosArm64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
}
}
}

tasks.withType(Test::class.java).all {
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}

repositories {
mavenCentral()
}

// Animal Sniffer only works on JDK 11 or older currently.
if (Jvm.current().javaVersion?.isJava12Compatible == false) {
project.apply<AnimalSnifferPlugin>()

configure<AnimalSnifferExtension> {
sourceSets = listOf(project.sourceSets.getByName("main"))
}

val signature: Configuration by configurations

dependencies {
signature(variantOf(libs.animalSniffer.android) { artifactType("signature") })
signature(variantOf(libs.animalSniffer.java) { artifactType("signature") })
}
}
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ kotlin = "1.8.10"

[libraries]
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
plugin-animalsniffer = { module = "ru.vyarus:gradle-animalsniffer-plugin", version = "1.7.0" }
animalSniffer-android = { module = "net.sf.androidscents.signature:android-api-level-15", version = "4.0.3_r5" }
animalSniffer-java = { module = "org.codehaus.mojo.signature:java17", version = "1.0" }

[plugins]
mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.18.0" }
animalsniffer = { id = "ru.vyarus.animalsniffer", version = "1.7.0" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
92 changes: 92 additions & 0 deletions src/commonMain/kotlin/com/jakewharton/byteunits/BinaryByteUnit.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.jakewharton.byteunits

/**
* A [BinaryByteUnit] represents power-of-two byte sizes at a given unit of granularity and
* provides utility methods to convert across units. A [BinaryByteUnit] does not maintain
* byte size information, but only helps organize and use byte size representations that may be
* maintained separately across various contexts.
*/
expect enum class BinaryByteUnit : ByteUnit {
/** Byte unit representing one byte. */
BYTES,

/** A byte unit representing 1024 bytes. */
KIBIBYTES,

/** A byte unit representing 1024 kibibytes. */
MEBIBYTES,

/** A byte unit representing 1024 mebibytes. */
GIBIBYTES,

/** A byte unit representing 1024 gibibytes. */
TEBIBYTES,

/** A byte unit representing 1024 tebibytes. */
PEBIBYTES,
;

/**
* Converts the given size in the given unit to this unit. Conversions from finer to coarser
* granularities truncate, so lose precision. For example, converting from `999` bytes to
* kibibytes results in `0`. Conversions from coarser to finer granularities with arguments
* that would numerically overflow saturate to [Long.MIN_VALUE] if negative or
* [Long.MAX_VALUE] if positive.
*
* For example, to convert 10 kilobytes to bytes, use:
* `ByteUnit.KIBIBYTES.convert(10, ByteUnit.BYTES)`
*
* [sourceCount] the size in the given [sourceUnit].
* [sourceUnit] the unit of the [sourceCount] argument.
* @return the converted size in this unit, or [Long.MIN_VALUE] if conversion would
* negatively overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun convert(sourceCount: Long, sourceUnit: BinaryByteUnit): Long

/**
* Equivalent to [KIBIBYTES.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toKibibytes(count: Long): Long

/**
* Equivalent to [MEBIBYTES.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toMebibytes(count: Long): Long

/**
* Equivalent to [GIBIBYTES.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toGibibytes(count: Long): Long

/**
* Equivalent to [TEBIBYTES.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toTebibytes(count: Long): Long

/**
* Equivalent to [PEBIBYTES.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toPebibytes(count: Long): Long

companion object {
/**
* Return `bytes` as human-readable size string (e.g., "1.2 GiB").
*/
fun format(bytes: Long): String
}
}
100 changes: 100 additions & 0 deletions src/commonMain/kotlin/com/jakewharton/byteunits/BitUnit.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.jakewharton.byteunits

/**
* A [BitUnit] represents bit size at a given unit of granularity and provides utility
* methods to convert across units. A [BitUnit] does not maintain bit size information,
* but only helps organize and use bit size representations that may be maintained separately
* across various contexts.
*/
expect enum class BitUnit : ByteUnit {
/** Bit unit representing one bit. */
BITS,

/** A bit unit representing 1000 bits. */
KILOBITS,

/** A bit unit representing 1000 kilobits. */
MEGABITS,

/** A bit unit representing 1000 megabits. */
GIGABITS,

/** A bit unit representing 1000 gigabits. */
TERABITS,

/** A bit unit representing 1000 terabits. */
PETABITS,
;

/**
* Converts the given size in the given unit to this unit. Conversions from finer to coarser
* granularities truncate, so lose precision. For example, converting from `999` bit to
* kilobits results in `0`. Conversions from coarser to finer granularities with arguments
* that would numerically overflow saturate to [Long.MIN_VALUE] if negative or
* [Long.MAX_VALUE] if positive.
*
* For example, to convert 10 kilobytes to bytes, use:
* `ByteUnit.KILOBITS.convert(10, ByteUnit.BITS)`
*
* [sourceCount] the size in the given [sourceUnit].
* [sourceUnit] the unit of the [sourceCount] argument.
* @return the converted size in this unit, or [Long.MIN_VALUE] if conversion would
* negatively overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun convert(sourceCount: Long, sourceUnit: BitUnit): Long

/**
* Equivalent to [BITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toBits(count: Long): Long

/**
* Equivalent to [KILOBITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toKilobits(count: Long): Long

/**
* Equivalent to [MEGABITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toMegabits(count: Long): Long

/**
* Equivalent to [GIGABITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toGigabits(count: Long): Long

/**
* Equivalent to [TERABITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toTerabits(count: Long): Long

/**
* Equivalent to [PETABITS.convert(count, this)][convert].
* [count] the bit count
* @return the converted count, or [Long.MIN_VALUE] if conversion would negatively
* overflow, or [Long.MAX_VALUE] if it would positively overflow.
*/
fun toPetabits(count: Long): Long

companion object {
/**
* Return `bits` as human-readable size string (e.g., "1.2 Gb".
*/
fun format(bits: Long): String
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package com.jakewharton.byteunits
* @see BinaryByteUnit
* @see BitUnit
*/
sealed interface ByteUnit {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make it sealed again once everything is in commonMain. Currently, we can't mix between source sets.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't. Actual implementations use that interface to implement it, which the Kotlin compiler does not allow if it's sealed.

interface ByteUnit {
/**
* Converts the given size in the given unit to bytes. Conversions with arguments that would
* numerically overflow saturate to [Long.MIN_VALUE] if negative or [Long.MAX_VALUE]
Expand Down
Loading