Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add support for encoding byte array as base64 string
  • Loading branch information
OptimumCode committed Mar 1, 2025
commit 22d7a41fcf6f443287bcc95fbbdf0cfdca2e4f47
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.github.optimumcode.json.schema.model.AbstractElement
import io.github.optimumcode.json.schema.model.ArrayElement
import io.github.optimumcode.json.schema.model.ObjectElement
import io.github.optimumcode.json.schema.model.PrimitiveElement
import io.github.optimumcode.json.schema.wrappers.objects.internal.encodeBase64
import kotlin.jvm.JvmInline
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
Expand All @@ -24,17 +25,24 @@ public class WrappingConfiguration internal constructor(
* If set to `true` the [Char] is converted to a codepoint (and then to [Long])
*/
public val charAsCodepoint: Boolean = false,
/**
* If set to `true` the [ByteArray] is encoded using Base64 encoding and wrapped as a [PrimitiveElement].
* Otherwise, the [ByteArray] is wrapped as an [ArrayElement].
*/
public val byteArrayAsBase64String: Boolean = true,
)

@ExperimentalApi
@JvmOverloads
public fun wrappingConfiguration(
allowSets: Boolean = false,
charAsCodepoint: Boolean = false,
byteArrayAsBase64String: Boolean = true,
): WrappingConfiguration =
WrappingConfiguration(
allowSets = allowSets,
charAsCodepoint = charAsCodepoint,
byteArrayAsBase64String = byteArrayAsBase64String,
)

/**
Expand All @@ -59,10 +67,14 @@ public fun wrappingConfiguration(
* * [Map] -> keys MUST have a [String] type, values MUST be one of the supported types
* * [List] -> elements MUST be one of the supported types
* * [Array] -> elements MUST be one of the supported types
* * [CharArray], [ByteArray], [ShortArray], [IntArray], [LongArray], [FloatArray], [DoubleArray]
*
* If [WrappingConfiguration.allowSets] is enabled [Set] is also converted to [ArrayElement].
* Please be aware that in order to have consistent verification results
* the [Set] must be one of the ORDERED types, e.g. [LinkedHashSet].
*
* If [WrappingConfiguration.byteArrayAsBase64String] is enabled (enabled by default)
* a [ByteArray] will be encoded using Base64 and wrapped as a [PrimitiveElement].
*/
@JvmOverloads
@ExperimentalApi
Expand All @@ -83,7 +95,12 @@ public fun wrapAsElement(
obj is DoubleArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
obj is FloatArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
obj is CharArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
obj is ByteArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
obj is ByteArray ->
if (configuration.byteArrayAsBase64String) {
PrimitiveWrapper(obj.encodeBase64())
} else {
ListWrapper(obj.map { wrapAsElement(it, configuration) })
}
obj is Set<*> && configuration.allowSets ->
ListWrapper(obj.map { wrapAsElement(it, configuration) })

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.github.optimumcode.json.schema.wrappers.objects.internal

import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi

@OptIn(ExperimentalEncodingApi::class)
internal fun ByteArray.encodeBase64(): String = Base64.Default.encode(this)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ class WrappersTest : FunSpec() {
fun Any?.str(): String =
when (this) {
is Array<*> -> this.contentToString()
is ByteArray -> this.contentToString()
is ShortArray -> this.contentToString()
is IntArray -> this.contentToString()
is LongArray -> this.contentToString()
is FloatArray -> this.contentToString()
is DoubleArray -> this.contentToString()
is CharArray -> this.contentToString()
else -> toString()
}

Expand All @@ -35,7 +42,8 @@ class WrappersTest : FunSpec() {
emptyMap<String, Any>() to ObjectElement::class,
listOf<Any>() to ArrayElement::class,
emptyArray<Any>() to ArrayElement::class,
byteArrayOf() to ArrayElement::class,
// by default ByteArray is encoded as base64 string
byteArrayOf() to PrimitiveElement::class,
shortArrayOf() to ArrayElement::class,
intArrayOf() to ArrayElement::class,
longArrayOf() to ArrayElement::class,
Expand Down Expand Up @@ -297,6 +305,18 @@ class WrappersTest : FunSpec() {
wrapAsElement(MyNumber())
}.message.shouldStartWith("unsupported number type:")
}

test("byte array can be wrapped as an array element") {
wrapAsElement(
byteArrayOf(42),
wrappingConfiguration(
byteArrayAsBase64String = false,
),
).shouldBeInstanceOf<ArrayElement> {
it.size shouldBe 1
it.single().shouldBeInstanceOf<PrimitiveElement>()
}
}
}
}

Expand Down