diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc b/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc index 62ab8a41164..0204430d3ff 100755 Binary files a/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc and b/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc differ diff --git a/proto/compiler/src/CodedInputStream.kt b/proto/compiler/src/CodedInputStream.kt index 382cdf620ce..98873956132 100644 --- a/proto/compiler/src/CodedInputStream.kt +++ b/proto/compiler/src/CodedInputStream.kt @@ -15,10 +15,11 @@ import WireFormat.VARINT_UTIL_BIT_MASK */ // TODO: refactor correctness checks into readTag -class CodedInputStream(input: java.io.InputStream) { - val bufferedInput: java.io.BufferedInputStream +class CodedInputStream(buffer: ByteArray) { + var errorMessage: String = "" + val inputStream: KotlinInputStream init { - bufferedInput = java.io.BufferedInputStream(input) // TODO: Java's realization uses hand-written buffers. Why? + inputStream = KotlinInputStream(buffer) // TODO: Java's realization uses hand-written buffers. Why? } fun readInt32(expectedFieldNumber: Int): Int { @@ -66,7 +67,10 @@ class CodedInputStream(input: java.io.InputStream) { val boolValue = when (readValue) { 0 -> false 1 -> true - else -> throw InvalidProtocolBufferException("Expected boolean-encoding (1 or 0), got $readValue") + else -> { + errorMessage = "Expected boolean-encoding (1 or 0), got $readValue" + false + } } return boolValue } @@ -181,14 +185,18 @@ class CodedInputStream(input: java.io.InputStream) { expectedWireType: WireType, actualWireType: WireType) { if (expectedFieldNumber != actualFieldNumber) { - throw InvalidProtocolBufferException( + errorMessage = "Error in protocol format: \n " + - "Expected field number ${expectedFieldNumber}, got ${actualFieldNumber}") + "Expected field number ${expectedFieldNumber}, got ${actualFieldNumber}" + println(errorMessage) + return } if (expectedWireType != actualWireType) { - throw InvalidProtocolBufferException("Error in protocol format: \n " + - "Expected ${expectedWireType.name} type, got ${actualWireType.name}") + errorMessage = "Error in protocol format: \n " + + "Expected ${expectedWireType.name} type, got ${actualWireType.name}" + println(errorMessage) + return } } @@ -219,7 +227,7 @@ class CodedInputStream(input: java.io.InputStream) { fun readRawBytes(count: Int): ByteArray { val ba = ByteArray(count) for (i in 0..(count - 1)) { - ba[i] = bufferedInput.read().toByte() + ba[i] = inputStream.read().toByte() } return ba } @@ -231,7 +239,8 @@ class CodedInputStream(input: java.io.InputStream) { } val tag = readInt32NoTag() if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted - throw InvalidProtocolBufferException("Invalid tag 0") + errorMessage = "Invalid tag 0" + return 0 } val actualFieldNumber = WireFormat.getTagFieldNumber(tag) @@ -246,7 +255,7 @@ class CodedInputStream(input: java.io.InputStream) { var result: Int = 0 var step: Int = 0 while (!done) { - val byte: Int = bufferedInput.read() + val byte: Int = inputStream.read().toInt() result = result or ( (byte and VARINT_INFO_BITS_MASK) @@ -267,7 +276,7 @@ class CodedInputStream(input: java.io.InputStream) { var result: Long = 0 var step: Int = 0 while (!done) { - val byte: Int = bufferedInput.read() + val byte: Int = inputStream.read().toInt() result = result or ( (byte and VARINT_INFO_BITS_MASK).toLong() @@ -275,7 +284,7 @@ class CodedInputStream(input: java.io.InputStream) { (VARINT_INFO_BITS_COUNT * step) ) step++ - if ((byte and VARINT_UTIL_BIT_MASK) == 0 || byte == -1) { + if ((byte and VARINT_UTIL_BIT_MASK) == 0 /* || byte == -1 ???? */) { done = true } } @@ -296,10 +305,7 @@ class CodedInputStream(input: java.io.InputStream) { // 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 + return inputStream.isAtEnd() } } diff --git a/proto/compiler/src/CodedOutputStream.kt b/proto/compiler/src/CodedOutputStream.kt index 646189cfd8f..19a490ff539 100644 --- a/proto/compiler/src/CodedOutputStream.kt +++ b/proto/compiler/src/CodedOutputStream.kt @@ -8,7 +8,13 @@ import WireFormat.VARINT_UTIL_BIT_MASK * Created by user on 7/6/16. */ -class CodedOutputStream(val output: java.io.OutputStream) { +class CodedOutputStream(val buffer: ByteArray) { + val output = KotlinOutputStream(buffer) + + fun toByteArray(): ByteArray { + return buffer + } + fun writeTag(fieldNumber: Int, type: WireType) { val tag = (fieldNumber shl 3) or type.ordinal writeInt32NoTag(tag) @@ -156,6 +162,9 @@ class CodedOutputStream(val output: java.io.OutputStream) { fun writeBytes(fieldNumber: Int, value: ByteArray?) { value ?: return + if (value.size == 0) { + return + } writeTag(fieldNumber, WireType.LENGTH_DELIMITED) writeBytesNoTag(value) } diff --git a/proto/compiler/src/KotlinInputStream.kt b/proto/compiler/src/KotlinInputStream.kt new file mode 100644 index 00000000000..89a00d8a1bb --- /dev/null +++ b/proto/compiler/src/KotlinInputStream.kt @@ -0,0 +1,16 @@ +/** + * Created by user on 8/8/16. + */ + +class KotlinInputStream(val buffer: ByteArray) { + var pos = 0 + + fun read(): Byte { + pos += 1 + return buffer[pos - 1] + } + + fun isAtEnd(): Boolean { + return pos >= buffer.size + } +} \ No newline at end of file diff --git a/proto/compiler/src/KotlinOutputStream.kt b/proto/compiler/src/KotlinOutputStream.kt new file mode 100644 index 00000000000..01e0ed2a410 --- /dev/null +++ b/proto/compiler/src/KotlinOutputStream.kt @@ -0,0 +1,18 @@ +/** + * Created by user on 8/8/16. + */ + +class KotlinOutputStream(val buffer: ByteArray) { + var pos = 0 + + fun write (data: ByteArray) { + write(data, 0, data.size) + } + + fun write (data: ByteArray, begin: Int, size: Int) { + for (i in begin..(begin + size - 1)) { + buffer[pos] = data[i] + pos += 1 + } + } +} diff --git a/proto/compiler/src/WireFormat.kt b/proto/compiler/src/WireFormat.kt index f81259f7496..0f2f3b685f5 100644 --- a/proto/compiler/src/WireFormat.kt +++ b/proto/compiler/src/WireFormat.kt @@ -14,7 +14,7 @@ object WireFormat { val FIXED_64_BYTE_SIZE: Int = 8 fun getTagWireType(tag: Int): WireType { - return WireType from (tag and TAG_TYPE_MASK).toByte() + return WireType.from ( (tag and TAG_TYPE_MASK).toByte()) } fun getTagFieldNumber(tag: Int): Int { diff --git a/proto/compiler/src/WireType.kt b/proto/compiler/src/WireType.kt index 6cc55da3f42..edc02c60414 100644 --- a/proto/compiler/src/WireType.kt +++ b/proto/compiler/src/WireType.kt @@ -1,7 +1,7 @@ /** * Created by Dmitry Savvinov on 7/6/16. * Enum for possible WireTypes. - * See details at [official Google reference]()https://developers.google.com/protocol-buffers/docs/encoding#structure) + * See details at [official Google reference](https://developers.google.com/protocol-buffers/docs/encoding#structure) */ enum class WireType(val id: Int) { @@ -10,10 +10,11 @@ enum class WireType(val id: Int) { LENGTH_DELIMITED(2), // string, bytes, embedded messages, packed repeated fields START_GROUP(3), // groups (deprecated) END_GROUP(4), // groups (deprecated) - FIX_32(5); // fixed32, sfixed32, float + FIX_32(5), // fixed32, sfixed32, float + UNDEFINED(6); // indicates error when parsing from Int companion object { - infix fun from (value: Byte): WireType { + fun from (value: Byte): WireType { return when (value) { 0.toByte() -> VARINT 1.toByte() -> FIX_64 @@ -21,7 +22,7 @@ enum class WireType(val id: Int) { 3.toByte() -> START_GROUP 4.toByte() -> END_GROUP 5.toByte() -> FIX_32 - else -> throw IllegalArgumentException() + else -> UNDEFINED } } }