From a63c5dfaa77411d837d9edac8ffdf6249561a1dd Mon Sep 17 00:00:00 2001 From: Gustav Behm Date: Sat, 19 May 2018 09:59:04 +0200 Subject: [PATCH] Correct FieldEncoder and FieldDecoder's behavior regarding zeroed uint32:s --- .../scala/io/protoless/fields/FieldDecoder.scala | 11 ++++++++--- .../scala/io/protoless/fields/FieldEncoder.scala | 14 ++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/modules/core/src/main/scala/io/protoless/fields/FieldDecoder.scala b/modules/core/src/main/scala/io/protoless/fields/FieldDecoder.scala index db61bf5..aac36b1 100644 --- a/modules/core/src/main/scala/io/protoless/fields/FieldDecoder.scala +++ b/modules/core/src/main/scala/io/protoless/fields/FieldDecoder.scala @@ -203,13 +203,18 @@ object FieldDecoder extends MidPriorityFieldDecoder { * * @group Utilities */ - final private[protoless] def native[A](r: CIS => A, expectedType: FieldType): RepeatableFieldDecoder[A] = new RepeatableFieldDecoder[A] { + final private[protoless] def native[A](r: CIS => A, expectedType: FieldType, default: Option[A] = None): RepeatableFieldDecoder[A] = new RepeatableFieldDecoder[A] { override def fieldType: FieldType = expectedType override def read(input: CIS, index: Int): Result[A] = { val tag = readTag(input, index) // Check that the fieldNumber match the current index - if (tag.fieldNumber != index) Left(MissingField(index, expectedType, tag.wireType, tag.fieldNumber)) + if (tag.fieldNumber != index) { + default match { + case Some(a) => Right(a) + case _ => Left(MissingField(index, expectedType, tag.wireType, tag.fieldNumber)) + } + } // Check if the type match, except if fieldType=2 for repeatedfields else if (tag.wireType != 2 && tag.wireType != expectedType.getWireType) Left(WrongFieldType(expectedType, tag.fieldNumber, tag.wireType)) // else try to decode the input @@ -233,7 +238,7 @@ object FieldDecoder extends MidPriorityFieldDecoder { /** * @group DecodingNative */ - implicit final val decodeUInt: RepeatableFieldDecoder[Int @@ Unsigned] = native(cis => tag.unsigned(cis.readUInt32()), FieldType.UINT32) + implicit final val decodeUInt: RepeatableFieldDecoder[Int @@ Unsigned] = native(cis => tag.unsigned(cis.readUInt32()), FieldType.UINT32, Some(tag.unsigned(0))) /** * @group DecodingNative diff --git a/modules/core/src/main/scala/io/protoless/fields/FieldEncoder.scala b/modules/core/src/main/scala/io/protoless/fields/FieldEncoder.scala index 3baf6e8..74995d3 100644 --- a/modules/core/src/main/scala/io/protoless/fields/FieldEncoder.scala +++ b/modules/core/src/main/scala/io/protoless/fields/FieldEncoder.scala @@ -100,7 +100,7 @@ object FieldEncoder extends MidPriorityFieldEncoder { /** * @group EncodingNative */ - implicit final val encodeUnsignedInt: RepeatableFieldEncoder[Int @@ Unsigned] = native(_.writeUInt32, _.writeUInt32NoTag, FieldType.UINT32) + implicit final val encodeUnsignedInt: RepeatableFieldEncoder[Int @@ Unsigned] = native(_.writeUInt32, _.writeUInt32NoTag, FieldType.UINT32, Some(unsigned(0))) /** * @group EncodingNative @@ -358,13 +358,19 @@ trait FieldEncoderHelpers { * * @group Utilities */ - final protected def native[A](nativeWrite: COS => (Int, A) => Unit, nativeWriteRepeated: COS => A => Unit, nativeFieldType: FieldType): RepeatableFieldEncoder[A] = new RepeatableFieldEncoder[A] { + final protected def native[A](nativeWrite: COS => (Int, A) => Unit, nativeWriteRepeated: COS => A => Unit, nativeFieldType: FieldType, default: Option[A] = None): RepeatableFieldEncoder[A] = new RepeatableFieldEncoder[A] { override def write(index: Int, a: A, output: COS): Unit = { - nativeWrite(output)(index, a) + default match { + case Some(`a`) => + case _ => nativeWrite(output)(index, a) + } } override def writeRepeated(a: A, output: COS): Unit = { - nativeWriteRepeated(output)(a) + default match { + case Some(`a`) => + case _ => nativeWriteRepeated(output)(a) + } } override def fieldType: FieldType = nativeFieldType