1 /* 2 * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.serialization.features 6 7 import kotlinx.serialization.* 8 import kotlinx.serialization.builtins.* 9 import kotlinx.serialization.descriptors.* 10 import kotlinx.serialization.encoding.* 11 import kotlinx.serialization.json.Json 12 import kotlinx.serialization.test.* 13 import kotlin.test.Test 14 import kotlin.test.assertEquals 15 16 class BinaryPayloadExampleTest { 17 @Serializable(BinaryPayload.Companion::class) 18 class BinaryPayload(val req: ByteArray, val res: ByteArray) { 19 companion object : KSerializer<BinaryPayload> { <lambda>null20 override val descriptor: SerialDescriptor = buildClassSerialDescriptor("BinaryPayload") { 21 element("req", ByteArraySerializer().descriptor) 22 element("res", ByteArraySerializer().descriptor) 23 } 24 serializenull25 override fun serialize(encoder: Encoder, value: BinaryPayload) { 26 val compositeOutput = encoder.beginStructure(descriptor) 27 compositeOutput.encodeStringElement(descriptor, 0, InternalHexConverter.printHexBinary(value.req)) 28 compositeOutput.encodeStringElement(descriptor, 1, InternalHexConverter.printHexBinary(value.res)) 29 compositeOutput.endStructure(descriptor) 30 } 31 deserializenull32 override fun deserialize(decoder: Decoder): BinaryPayload { 33 val dec: CompositeDecoder = decoder.beginStructure(descriptor) 34 var req: ByteArray? = null // consider using flags or bit mask if you 35 var res: ByteArray? = null // need to read nullable non-optional properties 36 loop@ while (true) { 37 when (val i = dec.decodeElementIndex(descriptor)) { 38 CompositeDecoder.DECODE_DONE -> break@loop 39 0 -> req = InternalHexConverter.parseHexBinary(dec.decodeStringElement(descriptor, i)) 40 1 -> res = InternalHexConverter.parseHexBinary(dec.decodeStringElement(descriptor, i)) 41 else -> throw SerializationException("Unknown index $i") 42 } 43 } 44 dec.endStructure(descriptor) 45 return BinaryPayload( 46 req ?: throw SerializationException("MFE: req"), 47 res ?: throw SerializationException("MFE: res") 48 ) 49 } 50 } 51 equalsnull52 override fun equals(other: Any?): Boolean { 53 if (this === other) return true 54 if (other == null || this::class != other::class) return false 55 56 other as BinaryPayload 57 58 if (!req.contentEquals(other.req)) return false 59 if (!res.contentEquals(other.res)) return false 60 61 return true 62 } 63 hashCodenull64 override fun hashCode(): Int { 65 var result = req.contentHashCode() 66 result = 31 * result + res.contentHashCode() 67 return result 68 } 69 } 70 71 @Test payloadEquivalencenull72 fun payloadEquivalence() { 73 val payload1 = BinaryPayload(byteArrayOf(0, 0, 0), byteArrayOf(127, 127)) 74 val s = Json.encodeToString(BinaryPayload.serializer(), payload1) 75 assertEquals("""{"req":"000000","res":"7F7F"}""", s) 76 val payload2 = Json.decodeFromString(BinaryPayload.serializer(), s) 77 assertEquals(payload1, payload2) 78 } 79 } 80