Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Api sync #246

Merged
merged 10 commits into from
Oct 1, 2024
109 changes: 25 additions & 84 deletions examples/src/main/kotlin/io.zenoh/ZBytes.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package io.zenoh

import io.zenoh.bytes.IntoZBytes
import io.zenoh.bytes.ZBytes
import io.zenoh.bytes.into
import java.nio.ByteBuffer
import java.nio.ByteOrder
import kotlin.reflect.typeOf
import io.zenoh.bytes.*
import io.zenoh.ext.zDeserialize
import io.zenoh.ext.zSerialize

fun main() {

Expand All @@ -16,23 +13,23 @@ fun main() {
/** Numeric: byte, short, int, float, double */
val intInput = 1234
var payload = ZBytes.from(intInput)
var intOutput = payload.deserialize<Int>().getOrThrow()
var intOutput = zDeserialize<Int>(payload).getOrThrow()
check(intInput == intOutput)

// Alternatively you can serialize into the type.
payload = ZBytes.serialize(intInput).getOrThrow()
intOutput = payload.deserialize<Int>().getOrThrow()
payload = zSerialize(intInput).getOrThrow()
intOutput = zDeserialize<Int>(payload).getOrThrow()
check(intInput == intOutput)

// Alternatively, `Numeric.into()`: ZBytes can be used
payload = intInput.into()
intOutput = payload.deserialize<Int>().getOrThrow()
intOutput = zDeserialize<Int>(payload).getOrThrow()
check(intInput == intOutput)

// Another example with float
val floatInput = 3.1415f
payload = ZBytes.from(floatInput)
val floatOutput = payload.deserialize<Float>().getOrThrow()
val floatOutput = zDeserialize<Float>(payload).getOrThrow()
check(floatInput == floatOutput)

/** String serialization and deserialization. */
Expand All @@ -41,7 +38,7 @@ fun main() {
// Alternatively, you can also call `String.into()` to convert
// a string into a ZBytes object:
// payload = stringInput.into()
var stringOutput = payload.deserialize<String>().getOrThrow()
var stringOutput = zDeserialize<String>(payload).getOrThrow()
check(stringInput == stringOutput)

// For the case of strings, ZBytes::toString() is equivalent:
Expand All @@ -51,7 +48,7 @@ fun main() {
/** ByteArray serialization and deserialization. */
val byteArrayInput = "example".toByteArray()
payload = ZBytes.from(byteArrayInput) // Equivalent to `byteArrayInput.into()`
var byteArrayOutput = payload.deserialize<ByteArray>().getOrThrow()
var byteArrayOutput = zDeserialize<ByteArray>(payload).getOrThrow()
check(byteArrayInput.contentEquals(byteArrayOutput))
// Alternatively, we can directly access the bytes of property of ZBytes:
byteArrayOutput = payload.toByteArray()
Expand All @@ -62,18 +59,18 @@ fun main() {
* Supported types: String, ByteArray, ZBytes, Byte, Short, Int, Long, Float and Double.
*/
val inputList = listOf("sample1", "sample2", "sample3")
payload = ZBytes.serialize(inputList).getOrThrow()
val outputList = payload.deserialize<List<String>>().getOrThrow()
payload = zSerialize(inputList).getOrThrow()
val outputList = zDeserialize<List<String>>(payload).getOrThrow()
check(inputList == outputList)

val inputListZBytes = inputList.map { value -> value.into() }
payload = ZBytes.serialize(inputListZBytes).getOrThrow()
val outputListZBytes = payload.deserialize<List<ZBytes>>().getOrThrow()
payload = zSerialize(inputListZBytes).getOrThrow()
val outputListZBytes = zDeserialize<List<ZBytes>>(payload).getOrThrow()
check(inputListZBytes == outputListZBytes)

val inputListByteArray = inputList.map { value -> value.toByteArray() }
payload = ZBytes.serialize(inputListByteArray).getOrThrow()
val outputListByteArray = payload.deserialize<List<ByteArray>>().getOrThrow()
payload = zSerialize(inputListByteArray).getOrThrow()
val outputListByteArray = zDeserialize<List<ByteArray>>(payload).getOrThrow()
check(compareByteArrayLists(inputListByteArray, outputListByteArray))

/**
Expand All @@ -82,13 +79,13 @@ fun main() {
* Maps with the following Type combinations are supported: String, ByteArray, ZBytes, Byte, Short, Int, Long, Float and Double.
*/
val inputMap = mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3")
payload = ZBytes.serialize(inputMap).getOrThrow()
val outputMap = payload.deserialize<Map<String, String>>().getOrThrow()
payload = zSerialize(inputMap).getOrThrow()
val outputMap = zDeserialize<Map<String, String>>(payload).getOrThrow()
check(inputMap == outputMap)

val combinedInputMap = mapOf("key1" to ZBytes.from("zbytes1"), "key2" to ZBytes.from("zbytes2"))
payload = ZBytes.serialize(combinedInputMap).getOrThrow()
val combinedOutputMap = payload.deserialize<Map<String, ZBytes>>().getOrThrow()
payload = zSerialize(combinedInputMap).getOrThrow()
val combinedOutputMap = zDeserialize<Map<String, ZBytes>>(payload).getOrThrow()
check(combinedInputMap == combinedOutputMap)

/*********************************************
Expand All @@ -107,38 +104,23 @@ fun main() {
* @see MyZBytes
*/
val inputMyZBytes = MyZBytes("example")
payload = ZBytes.serialize(inputMyZBytes).getOrThrow()
payload = zSerialize(inputMyZBytes).getOrThrow()
val outputMyZBytes = MyZBytes.from(payload)
check(inputMyZBytes == outputMyZBytes)

/** List of MyZBytes. */
val inputListMyZBytes = inputList.map { value -> MyZBytes(value) }
payload = ZBytes.serialize<List<MyZBytes>>(inputListMyZBytes).getOrThrow()
val outputListMyZBytes = payload.deserialize<List<ZBytes>>().getOrThrow().map { zbytes -> MyZBytes.from(zbytes) }
payload = zSerialize<List<MyZBytes>>(inputListMyZBytes).getOrThrow()
val outputListMyZBytes = zDeserialize<List<ZBytes>>(payload).getOrThrow().map { zbytes -> MyZBytes.from(zbytes) }
check(inputListMyZBytes == outputListMyZBytes)

/** Map of MyZBytes. */
val inputMapMyZBytes = inputMap.map { (k, v) -> MyZBytes(k) to MyZBytes(v) }.toMap()
payload = ZBytes.serialize<Map<MyZBytes, MyZBytes>>(inputMapMyZBytes).getOrThrow()
val outputMapMyZBytes = payload.deserialize<Map<ZBytes, ZBytes>>().getOrThrow()
payload = zSerialize<Map<MyZBytes, MyZBytes>>(inputMapMyZBytes).getOrThrow()
val outputMapMyZBytes = zDeserialize<Map<ZBytes, ZBytes>>(payload).getOrThrow()
.map { (key, value) -> MyZBytes.from(key) to MyZBytes.from(value) }.toMap()
check(inputMapMyZBytes == outputMapMyZBytes)

/**
* Providing a map of deserializers.
*
* Alternatively, [ZBytes.deserialize] also accepts a deserializers parameter of type
* `Map<KType, KFunction1<ByteArray, Any>>`. That is, a map of types that is associated
* to a function receiving a ByteArray, that returns Any. This way, you can provide a series
* of deserializer functions that extend the deserialization mechanisms we provide by default.
*
* For example, let's say we have a custom map serializer, with its own deserializer:
*/
val fooMap = mapOf(Foo("foo1") to Foo("bar1"), Foo("foo2") to Foo("bar2"))
val fooMapSerialized = ZBytes.from(serializeFooMap(fooMap))
val deserializersMap = mapOf(typeOf<Map<Foo, Foo>>() to ::deserializeFooMap)
val deserializedFooMap = fooMapSerialized.deserialize<Map<Foo, Foo>>(deserializersMap).getOrThrow()
check(fooMap == deserializedFooMap)
}

data class MyZBytes(val content: String) : IntoZBytes {
Expand All @@ -152,47 +134,6 @@ data class MyZBytes(val content: String) : IntoZBytes {
}
}

/** Example class for the deserialization map examples. */
data class Foo(val content: String)

/** Example serializer and deserializer. */
private fun serializeFooMap(testMap: Map<Foo, Foo>): ByteArray {
return testMap.map {
val key = it.key.content.toByteArray()
val keyLength = ByteBuffer.allocate(Int.SIZE_BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(key.size).array()
val value = it.value.content.toByteArray()
val valueLength =
ByteBuffer.allocate(Int.SIZE_BYTES).order(ByteOrder.LITTLE_ENDIAN).putInt(value.size).array()
keyLength + key + valueLength + value
}.reduce { acc, bytes -> acc + bytes }
}

private fun deserializeFooMap(serializedMap: ZBytes): Map<Foo, Foo> {
var idx = 0
var sliceSize: Int
val bytes = serializedMap.toByteArray()
val decodedMap = mutableMapOf<Foo, Foo>()
while (idx < bytes.size) {
sliceSize = ByteBuffer.wrap(bytes.sliceArray(IntRange(idx, idx + Int.SIZE_BYTES - 1)))
.order(ByteOrder.LITTLE_ENDIAN).int
idx += Int.SIZE_BYTES

val key = bytes.sliceArray(IntRange(idx, idx + sliceSize - 1))
idx += sliceSize

sliceSize = ByteBuffer.wrap(bytes.sliceArray(IntRange(idx, idx + Int.SIZE_BYTES - 1))).order(
ByteOrder.LITTLE_ENDIAN
).int
idx += Int.SIZE_BYTES

val value = bytes.sliceArray(IntRange(idx, idx + sliceSize - 1))
idx += sliceSize

decodedMap[Foo(key.decodeToString())] = Foo(value.decodeToString())
}
return decodedMap
}

/** Utils for this example. */

private fun compareByteArrayLists(list1: List<ByteArray>, list2: List<ByteArray>): Boolean {
Expand Down
Loading