Skip to content

Commit 22d7a41

Browse files
committed
Add support for encoding byte array as base64 string
1 parent 75adf68 commit 22d7a41

File tree

3 files changed

+46
-2
lines changed
  • json-schema-validator-objects/src
    • commonMain/kotlin/io/github/optimumcode/json/schema/wrappers/objects
    • commonTest/kotlin/io/github/optimumcode/json/schema/wrappers/objects

3 files changed

+46
-2
lines changed

json-schema-validator-objects/src/commonMain/kotlin/io/github/optimumcode/json/schema/wrappers/objects/Wrappers.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.github.optimumcode.json.schema.model.AbstractElement
88
import io.github.optimumcode.json.schema.model.ArrayElement
99
import io.github.optimumcode.json.schema.model.ObjectElement
1010
import io.github.optimumcode.json.schema.model.PrimitiveElement
11+
import io.github.optimumcode.json.schema.wrappers.objects.internal.encodeBase64
1112
import kotlin.jvm.JvmInline
1213
import kotlin.jvm.JvmName
1314
import kotlin.jvm.JvmOverloads
@@ -24,17 +25,24 @@ public class WrappingConfiguration internal constructor(
2425
* If set to `true` the [Char] is converted to a codepoint (and then to [Long])
2526
*/
2627
public val charAsCodepoint: Boolean = false,
28+
/**
29+
* If set to `true` the [ByteArray] is encoded using Base64 encoding and wrapped as a [PrimitiveElement].
30+
* Otherwise, the [ByteArray] is wrapped as an [ArrayElement].
31+
*/
32+
public val byteArrayAsBase64String: Boolean = true,
2733
)
2834

2935
@ExperimentalApi
3036
@JvmOverloads
3137
public fun wrappingConfiguration(
3238
allowSets: Boolean = false,
3339
charAsCodepoint: Boolean = false,
40+
byteArrayAsBase64String: Boolean = true,
3441
): WrappingConfiguration =
3542
WrappingConfiguration(
3643
allowSets = allowSets,
3744
charAsCodepoint = charAsCodepoint,
45+
byteArrayAsBase64String = byteArrayAsBase64String,
3846
)
3947

4048
/**
@@ -59,10 +67,14 @@ public fun wrappingConfiguration(
5967
* * [Map] -> keys MUST have a [String] type, values MUST be one of the supported types
6068
* * [List] -> elements MUST be one of the supported types
6169
* * [Array] -> elements MUST be one of the supported types
70+
* * [CharArray], [ByteArray], [ShortArray], [IntArray], [LongArray], [FloatArray], [DoubleArray]
6271
*
6372
* If [WrappingConfiguration.allowSets] is enabled [Set] is also converted to [ArrayElement].
6473
* Please be aware that in order to have consistent verification results
6574
* the [Set] must be one of the ORDERED types, e.g. [LinkedHashSet].
75+
*
76+
* If [WrappingConfiguration.byteArrayAsBase64String] is enabled (enabled by default)
77+
* a [ByteArray] will be encoded using Base64 and wrapped as a [PrimitiveElement].
6678
*/
6779
@JvmOverloads
6880
@ExperimentalApi
@@ -83,7 +95,12 @@ public fun wrapAsElement(
8395
obj is DoubleArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
8496
obj is FloatArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
8597
obj is CharArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
86-
obj is ByteArray -> ListWrapper(obj.map { wrapAsElement(it, configuration) })
98+
obj is ByteArray ->
99+
if (configuration.byteArrayAsBase64String) {
100+
PrimitiveWrapper(obj.encodeBase64())
101+
} else {
102+
ListWrapper(obj.map { wrapAsElement(it, configuration) })
103+
}
87104
obj is Set<*> && configuration.allowSets ->
88105
ListWrapper(obj.map { wrapAsElement(it, configuration) })
89106

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.github.optimumcode.json.schema.wrappers.objects.internal
2+
3+
import kotlin.io.encoding.Base64
4+
import kotlin.io.encoding.ExperimentalEncodingApi
5+
6+
@OptIn(ExperimentalEncodingApi::class)
7+
internal fun ByteArray.encodeBase64(): String = Base64.Default.encode(this)

json-schema-validator-objects/src/commonTest/kotlin/io/github/optimumcode/json/schema/wrappers/objects/WrappersTest.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ class WrappersTest : FunSpec() {
2626
fun Any?.str(): String =
2727
when (this) {
2828
is Array<*> -> this.contentToString()
29+
is ByteArray -> this.contentToString()
30+
is ShortArray -> this.contentToString()
31+
is IntArray -> this.contentToString()
32+
is LongArray -> this.contentToString()
33+
is FloatArray -> this.contentToString()
34+
is DoubleArray -> this.contentToString()
35+
is CharArray -> this.contentToString()
2936
else -> toString()
3037
}
3138

@@ -35,7 +42,8 @@ class WrappersTest : FunSpec() {
3542
emptyMap<String, Any>() to ObjectElement::class,
3643
listOf<Any>() to ArrayElement::class,
3744
emptyArray<Any>() to ArrayElement::class,
38-
byteArrayOf() to ArrayElement::class,
45+
// by default ByteArray is encoded as base64 string
46+
byteArrayOf() to PrimitiveElement::class,
3947
shortArrayOf() to ArrayElement::class,
4048
intArrayOf() to ArrayElement::class,
4149
longArrayOf() to ArrayElement::class,
@@ -297,6 +305,18 @@ class WrappersTest : FunSpec() {
297305
wrapAsElement(MyNumber())
298306
}.message.shouldStartWith("unsupported number type:")
299307
}
308+
309+
test("byte array can be wrapped as an array element") {
310+
wrapAsElement(
311+
byteArrayOf(42),
312+
wrappingConfiguration(
313+
byteArrayAsBase64String = false,
314+
),
315+
).shouldBeInstanceOf<ArrayElement> {
316+
it.size shouldBe 1
317+
it.single().shouldBeInstanceOf<PrimitiveElement>()
318+
}
319+
}
300320
}
301321
}
302322

0 commit comments

Comments
 (0)