From 86e55175c9a1fc2c8ec6e3c3ce4d24c2e53fb183 Mon Sep 17 00:00:00 2001 From: dsavvinov <45yadjlzti> Date: Mon, 11 Jul 2016 13:28:36 +0300 Subject: [PATCH] Removed all generics from Kotlin Protobuf Runtime (as too advanced language feature for target platform) --- proto/compiler/.idea/compiler.iml | 5 +- .../.idea/libraries/KotlinJavaRuntime.xml | 12 + proto/compiler/.idea/misc.xml | 7 +- .../{protobuf_draft.iml => compiler.iml} | 2 +- proto/compiler/src/CodedInputStream.kt | 229 ++++++++++-------- proto/compiler/src/CodedOutputStream.kt | 36 ++- proto/compiler/src/PersonMessage.kt | 6 +- proto/compiler/src/TestStreams.kt | 68 +++--- 8 files changed, 220 insertions(+), 145 deletions(-) create mode 100644 proto/compiler/.idea/libraries/KotlinJavaRuntime.xml rename proto/compiler/{protobuf_draft.iml => compiler.iml} (98%) diff --git a/proto/compiler/.idea/compiler.iml b/proto/compiler/.idea/compiler.iml index d6ebd480598..245d3429faa 100644 --- a/proto/compiler/.idea/compiler.iml +++ b/proto/compiler/.idea/compiler.iml @@ -2,8 +2,11 @@ - + + + + \ No newline at end of file diff --git a/proto/compiler/.idea/libraries/KotlinJavaRuntime.xml b/proto/compiler/.idea/libraries/KotlinJavaRuntime.xml new file mode 100644 index 00000000000..207fc74dd51 --- /dev/null +++ b/proto/compiler/.idea/libraries/KotlinJavaRuntime.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/proto/compiler/.idea/misc.xml b/proto/compiler/.idea/misc.xml index 880e17b132c..c6d8fb73c8c 100644 --- a/proto/compiler/.idea/misc.xml +++ b/proto/compiler/.idea/misc.xml @@ -1,5 +1,8 @@ + + + - + + + \ No newline at end of file diff --git a/proto/compiler/protobuf_draft.iml b/proto/compiler/compiler.iml similarity index 98% rename from proto/compiler/protobuf_draft.iml rename to proto/compiler/compiler.iml index 7fa3b1b2717..1ca312ac2f6 100644 --- a/proto/compiler/protobuf_draft.iml +++ b/proto/compiler/compiler.iml @@ -3,7 +3,7 @@ - + diff --git a/proto/compiler/src/CodedInputStream.kt b/proto/compiler/src/CodedInputStream.kt index a63b8f5012f..827bcfb3282 100644 --- a/proto/compiler/src/CodedInputStream.kt +++ b/proto/compiler/src/CodedInputStream.kt @@ -14,153 +14,171 @@ import java.nio.ByteOrder // TODO: decide, if we want to optimize for performance (then we have to deal with spaghetti-code) class CodedInputStream(input: java.io.InputStream) { - data class Field (val fieldNumber: Int, val wireType: WireType, val value: ValueType) // TODO: think about variance - val bufferedInput: java.io.BufferedInputStream init { bufferedInput = java.io.BufferedInputStream(input) // TODO: Java's realization uses hand-written buffers. Why? } - fun readInt32(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.VARINT) - throw InvalidProtocolBufferException("Expected Varint tag, got ${wireType.name}") - val value = readRawVarint32() - return Field(fieldNumber, wireType, value) + fun readInt32(expectedFieldNumber: Int): Int { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readRawVarint32() } // Note that unsigned integer types are stored as their signed counterparts with top bit // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all - // methods, reading unsigned ints simply redirect call to corresponding signed-reading method - fun readUInt32(): Field { - return readInt32() + // methods reading unsigned ints simply redirect call to corresponding signed-reading method + fun readUInt32(expectedFieldNumber: Int): Int { + return readInt32(expectedFieldNumber) } - fun readInt64(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.VARINT) - throw InvalidProtocolBufferException("Expected Varint tag, got ${wireType.name}") - val value = readRawVarint64() - return Field(fieldNumber, wireType, value) + fun readInt64(expectedFieldNumber: Int): Long { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, actualWireType, WireType.VARINT) + return readRawVarint64() } // See note on unsigned integers implementations above - fun readUInt64(): Field { - return readUInt64() + fun readUInt64(expectedFieldNumber: Int): Long { + return readUInt64(expectedFieldNumber) } - fun readBool(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.VARINT) - throw InvalidProtocolBufferException("Expected Varint tag, got ${wireType.name}") - + fun readBool(expectedFieldNumber: Int): Boolean { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, actualWireType, WireType.VARINT) val readValue = readRawVarint32() val boolValue = when (readValue) { 0 -> false 1 -> true else -> throw InvalidProtocolBufferException("Expected boolean-encoding (1 or 0), got $readValue") } - - return Field(fieldNumber, wireType, boolValue) + return boolValue } // Reading enums is like reading one int32 number. Caller is responsible for converting this ordinal to enum-object - fun readEnum(): Field { - return readInt32() + fun readEnum(expectedFieldNumber: Int): Int { + return readInt32(expectedFieldNumber) } - fun readSInt32(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.VARINT) - throw InvalidProtocolBufferException("Expected Varint tag, got ${wireType.name}") - val value = readZigZag32() - return Field(fieldNumber, wireType, value) + fun readSInt32(expectedFieldNumber: Int): Int { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readZigZag32() } - fun readSInt64(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.VARINT) - throw InvalidProtocolBufferException("Expected Varint tag, got ${wireType.name}") - val value = readZigZag64() - return Field(fieldNumber, wireType, value) + fun readSInt64(expectedFieldNumber: Int): Long { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readZigZag64() } - fun readFixed32(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.FIX_32) - throw InvalidProtocolBufferException("Expected FIX_32 tag, got ${wireType.name}") - val value = readLittleEndianInt() - return Field(fieldNumber, wireType, value) + fun readFixed32(expectedFieldNumber: Int): Int { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_32, actualWireType) + return readLittleEndianInt() } - fun readSFixed32(): Field { - return readFixed32() + fun readSFixed32(expectedFieldNumber: Int): Int { + return readFixed32(expectedFieldNumber) } - fun readFixed64(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.FIX_64) - throw InvalidProtocolBufferException("Expected FIX_64 tag, got ${wireType.name}") - val value = readLittleEndianLong() - return Field(fieldNumber, wireType, value) + fun readFixed64(expectedFieldNumber: Int): Long { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_64, actualWireType) + return readLittleEndianLong() } - fun readSFixed64(): Field { - return readFixed64() + fun readSFixed64(expectedFieldNumber: Int): Long { + return readFixed64(expectedFieldNumber) } - fun readDouble(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.FIX_64) - throw InvalidProtocolBufferException("Expected FIX_64 tag, got ${wireType.name}") - val value = readLittleEndianDouble() - return Field(fieldNumber, wireType, value) + fun readDouble(expectedFieldNumber: Int): Double { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_64, actualWireType) + return readLittleEndianDouble() } - fun readFloat(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.FIX_32) - throw InvalidProtocolBufferException("Expected FIX_64 tag, got ${wireType.name}") - val value = readLittleEndianFloat() - return Field(fieldNumber, wireType, value) + fun readFloat(expectedFieldNumber: Int): Float { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_32, actualWireType) + return readLittleEndianFloat() } - fun readString(): Field { - val (fieldNumber, wireType) = readAndParseTag() - if (wireType != WireType.LENGTH_DELIMITED) - throw InvalidProtocolBufferException("Expected LENGTH_DELMITED tag, got ${wireType.name}") + fun readString(expectedFieldNumber: Int): String { + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.LENGTH_DELIMITED, actualWireType) val length = readRawVarint32() val value = String(readRawBytes(length)) - return Field(fieldNumber, wireType, value) + return value } - // ============ private methods ================== + /** ============ Utility methods ================== + * They are left non-private for cases when one wants to implement her/his own protocol format. + * Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags. + */ - private fun readLittleEndianDouble(): Double { + fun checkFieldCorrectness( + expectedFieldNumber: Int, + actualFieldNumber: Int, + expectedWireType: WireType, + actualWireType: WireType) { + if (expectedFieldNumber != actualFieldNumber) { + throw InvalidProtocolBufferException( + "Error in protocol format: \n " + + "Expected field number ${expectedFieldNumber}, got ${actualFieldNumber}") + } + + if (expectedWireType != actualWireType) { + throw InvalidProtocolBufferException("Error in protocol format: \n " + + "Expected ${expectedWireType.name} type, got ${actualWireType.name}") + } + } + + fun readLittleEndianDouble(): Double { val byteBuffer = ByteBuffer.wrap(readRawBytes(8)) byteBuffer.order(ByteOrder.LITTLE_ENDIAN) return byteBuffer.getDouble(0) } - private fun readLittleEndianFloat(): Float { + fun readLittleEndianFloat(): Float { val byteBuffer = ByteBuffer.wrap(readRawBytes(4)) byteBuffer.order(ByteOrder.LITTLE_ENDIAN) return byteBuffer.getFloat(0) } - private fun readLittleEndianInt(): Int { + fun readLittleEndianInt(): Int { val byteBuffer = ByteBuffer.wrap(readRawBytes(8)) byteBuffer.order(ByteOrder.LITTLE_ENDIAN) return byteBuffer.getInt(0) } - private fun readLittleEndianLong(): Long { + fun readLittleEndianLong(): Long { val byteBuffer = ByteBuffer.wrap(readRawBytes(4)) byteBuffer.order(ByteOrder.LITTLE_ENDIAN) return byteBuffer.getLong(0) } - private fun readRawBytes(count: Int): ByteArray { + fun readRawBytes(count: Int): ByteArray { val ba = ByteArray(count) for (i in 0..(count - 1)) { ba[i] = bufferedInput.read().toByte() @@ -168,67 +186,84 @@ class CodedInputStream(input: java.io.InputStream) { return ba } - private fun readTag(): Int { + // reads tag. Note that it returns 0 for the end of message! + fun readTag(): Int { if (isAtEnd()) { return 0 // we can safely return 0 as sign of end of message, because 0-tags are illegal } val tag = readRawVarint32() - if (tag == 0) { // if we somehow read 0-tag, then message is corrupted + if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted throw InvalidProtocolBufferException("Invalid tag 0") } return tag } - private fun readAndParseTag(): Pair { - val tag = readTag() - return Pair(WireFormat.getTagFieldNumber(tag), WireFormat.getTagWireType(tag)) - } - - private fun readRawVarint32(): Int { + // reads varint not larger than 32-bit integer according to protobuf varint-encoding + fun readRawVarint32(): Int { var done: Boolean = false var result: Int = 0 var step: Int = 0 while (!done) { val byte: Int = bufferedInput.read() - result = result or ((byte and 127) shl (7 * step)) + result = result or + ( + (byte and VARINT_INFO_BITS_MASK) + shl + (VARINT_INFO_BITS_COUNT * step) + ) step++ - if ((byte and 128) == 0) { + if ((byte and VARINT_UTIL_BIT_MASK) == 0) { done = true } } return result } - private fun readRawVarint64(): Long { + // reads varint not larger than 64-bit integer according to protobuf varint-encoding + fun readRawVarint64(): Long { var done: Boolean = false var result: Long = 0 var step: Int = 0 while (!done) { val byte: Int = bufferedInput.read() - result = result or ((byte and 127).toLong() shl (7 * step)) + result = result or + ( + (byte and VARINT_INFO_BITS_MASK).toLong() + shl + (VARINT_INFO_BITS_COUNT * step) + ) step++ - if ((byte and 128) == 0 || byte == -1) { + if ((byte and VARINT_UTIL_BIT_MASK) == 0 || byte == -1) { done = true } } return result } - private fun readZigZag32(): Int { + // reads zig-zag encoded integer not larger than 32-bit long + fun readZigZag32(): Int { val value = readRawVarint32() - return (value shr 1) xor (-(value and 1)) + return (value shr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number } - private fun readZigZag64(): Long { + // reads zig-zag encoded integer not larger than 64-bit long + fun readZigZag64(): Long { val value = readRawVarint64() - return (value shr 1) xor (-(value and 1L)) + return (value shr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number } - private fun isAtEnd(): Boolean { + // checks if at least one more byte can be read from underlying input stream + fun isAtEnd(): Boolean { bufferedInput.mark(1) val byte = bufferedInput.read() bufferedInput.reset() return byte == -1 } + + // couple of constants for magic numbers + val VARINT_INFO_BITS_COUNT: Int = 7 + val VARINT_INFO_BITS_MASK: Int = 0b01111111 // mask for separating lowest 7 bits, where actual information stored + val VARINT_UTIL_BIT_MASK: Int = 0b10000000 // mask for separating highest bit, that indicates next byte presence + } diff --git a/proto/compiler/src/CodedOutputStream.kt b/proto/compiler/src/CodedOutputStream.kt index 04a1fdd3bcd..97cf7c31f96 100644 --- a/proto/compiler/src/CodedOutputStream.kt +++ b/proto/compiler/src/CodedOutputStream.kt @@ -116,14 +116,23 @@ class CodedOutputStream(val output: java.io.OutputStream) { fun writeVarint32(value: Int) { var curValue = value + + // we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding val res = ByteArray(5) + var resSize = 0 do { - var curByte = (curValue and 127) - curValue = curValue ushr 7 + // encode current 7 bits + var curByte = (curValue and VARINT_INFO_BITS_MASK) + + // discard encoded bits. Note that unsigned shift is needed for cases with negative numbers + curValue = curValue ushr VARINT_INFO_BITS_COUNT + + // check if there will be next byte in encoding and set util bit if needed if (curValue != 0) { - curByte = curByte or 128 + curByte = curByte or VARINT_UTIL_BIT_MASK } + res[resSize] = curByte.toByte() resSize++ } while(curValue != 0) @@ -132,13 +141,21 @@ class CodedOutputStream(val output: java.io.OutputStream) { fun writeVarint64(value: Long) { var curValue = value - val res = ByteArray(10) // we reserve 10 bytes for the cases when value was negative int32/int64 + + // we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding + val res = ByteArray(10) + var resSize = 0 while(curValue != 0L) { - var curByte = (curValue and 127L) - curValue = curValue ushr 7 + // encode current 7 bits + var curByte = (curValue and VARINT_INFO_BITS_MASK.toLong()) + + // discard encoded bits. Note that unsigned shift is needed for cases with negative numbers + curValue = curValue ushr VARINT_INFO_BITS_COUNT + + // check if there will be next byte and set util bit if needed if (curValue != 0L) { - curByte = curByte or 128L + curByte = curByte or VARINT_UTIL_BIT_MASK.toLong() } res[resSize] = curByte.toByte() @@ -146,4 +163,9 @@ class CodedOutputStream(val output: java.io.OutputStream) { } output.write(res, 0, resSize) } + + // couple of constants for magic numbers + val VARINT_INFO_BITS_COUNT: Int = 7 + val VARINT_INFO_BITS_MASK: Int = 0b01111111 // mask for separating lowest 7 bits, where actual information stored + val VARINT_UTIL_BIT_MASK: Int = 0b10000000 // mask for separating highest bit, that indicates next byte presence } diff --git a/proto/compiler/src/PersonMessage.kt b/proto/compiler/src/PersonMessage.kt index 01fd498807c..1aa727a801a 100644 --- a/proto/compiler/src/PersonMessage.kt +++ b/proto/compiler/src/PersonMessage.kt @@ -12,9 +12,9 @@ class PersonMessage(val name: String, val id: Long, val hasCat: Boolean) // : Me } fun readFrom(input: CodedInputStream) : PersonMessage { - val newName = input.readString().value - val newId = input.readInt64().value - val newHasCatFlag = input.readBool().value + val newName = input.readString(1) + val newId = input.readInt64(2) + val newHasCatFlag = input.readBool(3) return PersonMessage(newName, newId, newHasCatFlag) } diff --git a/proto/compiler/src/TestStreams.kt b/proto/compiler/src/TestStreams.kt index d0b315fe85d..0c8dfeb58e5 100644 --- a/proto/compiler/src/TestStreams.kt +++ b/proto/compiler/src/TestStreams.kt @@ -19,15 +19,15 @@ fun testTrivialPositiveVarInts() { outs.writeInt64(9, -32132132132131L) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(1, 42, ins.readInt32()) - assertSuccessfulRead(42, 1, ins.readInt32()) - assertSuccessfulRead(2, -2, ins.readInt32()) - assertSuccessfulRead(3, -21321, ins.readInt32()) - assertSuccessfulRead(5, 42L, ins.readInt64()) - assertSuccessfulRead(6, 1232132131212321L, ins.readInt64()) - assertSuccessfulRead(7, -2, ins.readInt64()) - assertSuccessfulRead(8, -21321L, ins.readInt64()) - assertSuccessfulRead(9, -32132132132131L, ins.readInt64()) + assertSuccessfulRead(42, ins.readInt32(1)) + assertSuccessfulRead(1, ins.readInt32(16)) + assertSuccessfulRead(-2, ins.readInt32(2)) + assertSuccessfulRead(-21321, ins.readInt32(3)) + assertSuccessfulRead(42L, ins.readInt64(5)) + assertSuccessfulRead(1232132131212321L, ins.readInt64(6)) + assertSuccessfulRead(-2, ins.readInt64(7)) + assertSuccessfulRead(-21321L, ins.readInt64(8)) + assertSuccessfulRead(-32132132132131L, ins.readInt64(9)) } @@ -38,8 +38,8 @@ fun testMinPossibleVarInts() { outs.writeInt64(2, Long.MIN_VALUE) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(1, Int.MIN_VALUE, ins.readInt32()) - assertSuccessfulRead(2, Long.MIN_VALUE, ins.readInt64()) + assertSuccessfulRead(Int.MIN_VALUE, ins.readInt32(1)) + assertSuccessfulRead(Long.MIN_VALUE, ins.readInt64(2)) } fun testMaxPossibleVarInts() { @@ -49,8 +49,8 @@ fun testMaxPossibleVarInts() { outs.writeInt64(2, Long.MAX_VALUE) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(1, Int.MAX_VALUE, ins.readInt32()) - assertSuccessfulRead(2, Long.MAX_VALUE, ins.readInt64()) + assertSuccessfulRead(Int.MAX_VALUE, ins.readInt32(1)) + assertSuccessfulRead(Long.MAX_VALUE, ins.readInt64(2)) } fun testMaxPossibleFieldNumber() { @@ -59,7 +59,7 @@ fun testMaxPossibleFieldNumber() { outs.writeInt64(536870911, Long.MAX_VALUE) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(536870911, Long.MAX_VALUE, ins.readInt64()) + assertSuccessfulRead(Long.MAX_VALUE, ins.readInt64(536870911)) } fun testZigZag32() { @@ -70,9 +70,9 @@ fun testZigZag32() { outs.writeSInt32(4, -12345675) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(5, -213123, ins.readSInt32()) - assertSuccessfulRead(1, 3123123, ins.readSInt32()) - assertSuccessfulRead(4, -12345675, ins.readSInt32()) + assertSuccessfulRead(-213123, ins.readSInt32(5)) + assertSuccessfulRead(3123123, ins.readSInt32(1)) + assertSuccessfulRead(-12345675, ins.readSInt32(4)) } fun testZigZag64() { @@ -85,11 +85,11 @@ fun testZigZag64() { outs.writeSInt64(42, 483567314231L) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(5, -213123L, ins.readSInt64()) - assertSuccessfulRead(1, 3123123L, ins.readSInt64()) - assertSuccessfulRead(4, -12345675L, ins.readSInt64()) - assertSuccessfulRead(12, -123456789012L, ins.readSInt64()) - assertSuccessfulRead(42, 483567314231L, ins.readSInt64()) + assertSuccessfulRead(-213123L, ins.readSInt64(5)) + assertSuccessfulRead(3123123L, ins.readSInt64(1)) + assertSuccessfulRead(-12345675L, ins.readSInt64(4)) + assertSuccessfulRead(-123456789012L, ins.readSInt64(12)) + assertSuccessfulRead(483567314231L, ins.readSInt64(42)) } fun testBoolean() { @@ -99,8 +99,8 @@ fun testBoolean() { outs.writeBool(2, false) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(1, true, ins.readBool()) - assertSuccessfulRead(2, false, ins.readBool()) + assertSuccessfulRead(true, ins.readBool(1)) + assertSuccessfulRead(false, ins.readBool(2)) } fun testEnum() { @@ -110,8 +110,8 @@ fun testEnum() { outs.writeEnum(2, WireType.FIX_64.ordinal) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(1, WireType.END_GROUP.ordinal, ins.readEnum()) - assertSuccessfulRead(2, WireType.FIX_64.ordinal, ins.readEnum()) + assertSuccessfulRead(WireType.END_GROUP.ordinal, ins.readEnum(1)) + assertSuccessfulRead(WireType.FIX_64.ordinal, ins.readEnum(2)) } fun testFloatAndDouble() { @@ -122,9 +122,9 @@ fun testFloatAndDouble() { outs.writeFloat(14, -1.32131321f) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(42, 123212.34282, ins.readDouble()) - assertSuccessfulRead(15, Math.PI, ins.readDouble()) - assertSuccessfulRead(14, -1.32131321f, ins.readFloat()) + assertSuccessfulRead(123212.34282, ins.readDouble(42)) + assertSuccessfulRead(Math.PI, ins.readDouble(15)) + assertSuccessfulRead(-1.32131321f, ins.readFloat(14)) } fun testStrings() { @@ -134,14 +134,12 @@ fun testStrings() { outs.writeString(15, """!@#$%^&*()QWERTYUI выфвфывфы""") val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - assertSuccessfulRead(42, "dasddasd asd ", ins.readString()) - assertSuccessfulRead(15, """!@#$%^&*()QWERTYUI выфвфывфы""", ins.readString()) + assertSuccessfulRead("dasddasd asd ", ins.readString(42)) + assertSuccessfulRead("""!@#$%^&*()QWERTYUI выфвфывфы""", ins.readString(15)) } -fun assertSuccessfulRead(fieldNumber: Int, value: T, field: CodedInputStream.Field) { - assert(field.fieldNumber == fieldNumber) - assert(field.wireType == WireType.VARINT) - assert(field.value == value) +fun assertSuccessfulRead(value: T, actualValue: T) { + assert(actualValue == value) } fun main(args: Array) {