added compile proto shell script to flash client and compiling in gradle
This commit is contained in:
@@ -21,12 +21,26 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
task compileProto(type: Exec) {
|
||||
executable "./compileProto.sh"
|
||||
}
|
||||
task buildProtoLib(type: Copy) {
|
||||
//just copy lib src to project
|
||||
def pathToProtoKotSrc = "../../../proto/compiler/src/"
|
||||
from pathToProtoKotSrc + "CodedInputStream.kt", pathToProtoKotSrc + "CodedOutputStream.kt",
|
||||
pathToProtoKotSrc + "WireFormat.kt", pathToProtoKotSrc + "WireType.kt",
|
||||
pathToProtoKotSrc + "InvalidProtocolBufferException.kt"
|
||||
into "src/main/java"
|
||||
}
|
||||
|
||||
task getDeps(type: Copy) {
|
||||
from sourceSets.main.compileClasspath
|
||||
into 'build/libs'
|
||||
}
|
||||
|
||||
build.dependsOn getDeps
|
||||
compileKotlin.dependsOn compileProto
|
||||
compileProto.dependsOn buildProtoLib
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
@@ -40,7 +54,7 @@ jar {
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
compile group: "com.martiansoftware",name:"jsap",version:"2.1"
|
||||
compile group: "com.martiansoftware", name: "jsap", version: "2.1"
|
||||
compile "com.google.protobuf:protobuf-java:3.0.0-beta-3"
|
||||
compile "io.netty:netty-all:4.1.2.Final"
|
||||
|
||||
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
../../../proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc --kotlin_out="./src/main/java" --proto_path="../../../proto" ../../../proto/carkot.proto
|
||||
@@ -0,0 +1,305 @@
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import WireFormat.VARINT_INFO_BITS_COUNT
|
||||
import WireFormat.VARINT_INFO_BITS_MASK
|
||||
import WireFormat.VARINT_UTIL_BIT_MASK
|
||||
|
||||
/**
|
||||
* Created by Dmitry Savvinov on 7/6/16.
|
||||
*
|
||||
* Hides details of work with Protobuf encoding
|
||||
*
|
||||
* Note that CodedInputStream reads protobuf-defined types from stream (such as int32, sint32, etc),
|
||||
* while CodedOutputStream has methods for writing Kotlin-types (such as Boolean, Int, Long, Short, etc)
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO: refactor correctness checks into readTag
|
||||
class CodedInputStream(input: java.io.InputStream) {
|
||||
val bufferedInput: java.io.BufferedInputStream
|
||||
init {
|
||||
bufferedInput = java.io.BufferedInputStream(input) // TODO: Java's realization uses hand-written buffers. Why?
|
||||
}
|
||||
|
||||
fun readInt32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
val actualFieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val actualWireType = WireFormat.getTagWireType(tag)
|
||||
checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType)
|
||||
return readInt32NoTag()
|
||||
}
|
||||
|
||||
// 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(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readUInt32NoTag()
|
||||
}
|
||||
|
||||
fun readUInt32NoTag(): Int {
|
||||
return readInt32NoTag()
|
||||
}
|
||||
|
||||
fun readInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readInt64NoTag()
|
||||
}
|
||||
|
||||
// See note on unsigned integers implementations above
|
||||
fun readUInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readUInt64NoTag()
|
||||
}
|
||||
|
||||
fun readUInt64NoTag(): Long {
|
||||
return readInt64NoTag()
|
||||
}
|
||||
|
||||
fun readBool(expectedFieldNumber: Int): Boolean {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readBoolNoTag()
|
||||
}
|
||||
|
||||
fun readBoolNoTag(): Boolean {
|
||||
val readValue = readInt32NoTag()
|
||||
val boolValue = when (readValue) {
|
||||
0 -> false
|
||||
1 -> true
|
||||
else -> throw InvalidProtocolBufferException("Expected boolean-encoding (1 or 0), got $readValue")
|
||||
}
|
||||
return boolValue
|
||||
}
|
||||
|
||||
// Reading enums is like reading one int32 number. Caller is responsible for converting this ordinal to enum-object
|
||||
fun readEnum(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readEnumNoTag()
|
||||
}
|
||||
|
||||
fun readEnumNoTag(): Int {
|
||||
return readUInt32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readSInt32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt32NoTag(): Int {
|
||||
return readZigZag32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readZigZag64NoTag()
|
||||
}
|
||||
|
||||
fun readFixed32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_32)
|
||||
return readFixed32NoInt()
|
||||
}
|
||||
|
||||
fun readFixed32NoInt(): Int {
|
||||
return readLittleEndianInt()
|
||||
}
|
||||
|
||||
fun readSFixed32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_32)
|
||||
return readSFixed32NoTag()
|
||||
}
|
||||
|
||||
fun readSFixed32NoTag(): Int {
|
||||
return readLittleEndianInt()
|
||||
}
|
||||
|
||||
fun readFixed64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_64)
|
||||
return readFixed64NoTag()
|
||||
}
|
||||
|
||||
fun readFixed64NoTag(): Long {
|
||||
return readLittleEndianLong()
|
||||
}
|
||||
|
||||
fun readSFixed64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_64)
|
||||
return readSFixed64NoTag()
|
||||
}
|
||||
|
||||
fun readSFixed64NoTag(): Long {
|
||||
return readLittleEndianLong()
|
||||
}
|
||||
|
||||
fun readDouble(expectedFieldNumber: Int): Double {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_64)
|
||||
return readDoubleNoTag()
|
||||
}
|
||||
|
||||
fun readDoubleNoTag(): Double {
|
||||
return readLittleEndianDouble()
|
||||
}
|
||||
|
||||
fun readFloat(expectedFieldNumber: Int): Float {
|
||||
val tag = readTag(expectedFieldNumber, WireType.FIX_32)
|
||||
return readFloatNoTag()
|
||||
}
|
||||
|
||||
fun readFloatNoTag(): Float {
|
||||
return readLittleEndianFloat()
|
||||
}
|
||||
|
||||
fun readString(expectedFieldNumber: Int): String {
|
||||
val tag = readTag(expectedFieldNumber, WireType.LENGTH_DELIMITED)
|
||||
return readStringNoTag()
|
||||
}
|
||||
|
||||
fun readStringNoTag(): String {
|
||||
val length = readInt32NoTag()
|
||||
val value = String(readRawBytes(length))
|
||||
return value
|
||||
}
|
||||
|
||||
fun readBytes(expectedFieldNumber: Int): ByteArray {
|
||||
val tag = readTag(expectedFieldNumber, WireType.LENGTH_DELIMITED)
|
||||
return readBytesNoTag()
|
||||
}
|
||||
|
||||
fun readBytesNoTag(): ByteArray {
|
||||
val length = readInt32NoTag()
|
||||
return readRawBytes(length)
|
||||
}
|
||||
|
||||
/** ============ 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.
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fun readLittleEndianFloat(): Float {
|
||||
val byteBuffer = ByteBuffer.wrap(readRawBytes(4))
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
return byteBuffer.getFloat(0)
|
||||
}
|
||||
|
||||
fun readLittleEndianInt(): Int {
|
||||
val byteBuffer = ByteBuffer.wrap(readRawBytes(8))
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
return byteBuffer.getInt(0)
|
||||
}
|
||||
|
||||
fun readLittleEndianLong(): Long {
|
||||
val byteBuffer = ByteBuffer.wrap(readRawBytes(4))
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
return byteBuffer.getLong(0)
|
||||
}
|
||||
|
||||
fun readRawBytes(count: Int): ByteArray {
|
||||
val ba = ByteArray(count)
|
||||
for (i in 0..(count - 1)) {
|
||||
ba[i] = bufferedInput.read().toByte()
|
||||
}
|
||||
return ba
|
||||
}
|
||||
|
||||
// reads tag. Note that it returns 0 for the end of message!
|
||||
fun readTag(expectedFieldNumber: Int, expectedWireType: WireType): Int {
|
||||
if (isAtEnd()) {
|
||||
return 0 // we can safely return 0 as sign of end of message, because 0-tags are illegal
|
||||
}
|
||||
val tag = readInt32NoTag()
|
||||
if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted
|
||||
throw InvalidProtocolBufferException("Invalid tag 0")
|
||||
}
|
||||
|
||||
val actualFieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val actualWireType = WireFormat.getTagWireType(tag)
|
||||
checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, expectedWireType, actualWireType)
|
||||
return tag
|
||||
}
|
||||
|
||||
// reads varint not larger than 32-bit integer according to protobuf varint-encoding
|
||||
fun readInt32NoTag(): 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 VARINT_INFO_BITS_MASK)
|
||||
shl
|
||||
(VARINT_INFO_BITS_COUNT * step)
|
||||
)
|
||||
step++
|
||||
if ((byte and VARINT_UTIL_BIT_MASK) == 0) {
|
||||
done = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// reads varint not larger than 64-bit integer according to protobuf varint-encoding
|
||||
fun readInt64NoTag(): 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 VARINT_INFO_BITS_MASK).toLong()
|
||||
shl
|
||||
(VARINT_INFO_BITS_COUNT * step)
|
||||
)
|
||||
step++
|
||||
if ((byte and VARINT_UTIL_BIT_MASK) == 0 || byte == -1) {
|
||||
done = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// reads zig-zag encoded integer not larger than 32-bit long
|
||||
fun readZigZag32NoTag(): Int {
|
||||
val value = readInt32NoTag()
|
||||
return (value shr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number
|
||||
}
|
||||
|
||||
// reads zig-zag encoded integer not larger than 64-bit long
|
||||
fun readZigZag64NoTag(): Long {
|
||||
val value = readInt64NoTag()
|
||||
return (value shr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import WireFormat.VARINT_INFO_BITS_COUNT
|
||||
import WireFormat.VARINT_INFO_BITS_MASK
|
||||
import WireFormat.VARINT_UTIL_BIT_MASK
|
||||
|
||||
/**
|
||||
* Created by user on 7/6/16.
|
||||
*/
|
||||
|
||||
class CodedOutputStream(val output: java.io.OutputStream) {
|
||||
fun writeTag(fieldNumber: Int, type: WireType) {
|
||||
val tag = (fieldNumber shl 3) or type.ordinal
|
||||
writeInt32NoTag(tag)
|
||||
}
|
||||
|
||||
fun writeInt32(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeInt32NoTag(value)
|
||||
}
|
||||
|
||||
// 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, writing unsigned ints simply redirect call to corresponding signed-writing method
|
||||
fun writeUInt32(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeInt32(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun writeInt64(fieldNumber: Int, value: Long?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeInt64NoTag(value)
|
||||
}
|
||||
|
||||
// See notes on unsigned integers implementation above
|
||||
fun writeUInt64(fieldNumber: Int, value: Long?) {
|
||||
value ?: return
|
||||
writeInt64(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun writeBool(fieldNumber: Int, value: Boolean?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeBoolNoTag(value)
|
||||
}
|
||||
|
||||
fun writeBoolNoTag(value: Boolean) {
|
||||
writeInt32NoTag(if (value) 1 else 0)
|
||||
}
|
||||
|
||||
// Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal
|
||||
fun writeEnum(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeEnumNoTag(value)
|
||||
}
|
||||
|
||||
fun writeEnumNoTag(value: Int) {
|
||||
writeInt32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSInt32(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeSInt32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSInt32NoTag(value: Int) {
|
||||
writeInt32NoTag((value shl 1) xor (value shr 31))
|
||||
}
|
||||
|
||||
fun writeSInt64(fieldNumber: Int, value: Long?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeSInt64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSInt64NoTag(value: Long) {
|
||||
writeInt64NoTag((value shl 1) xor (value shr 63))
|
||||
}
|
||||
|
||||
fun writeFixed32(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_32)
|
||||
writeFixed32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeFixed32NoTag(value: Int) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
// See notes on unsigned integers implementation above
|
||||
fun writeSFixed32(fieldNumber: Int, value: Int?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_32)
|
||||
writeSFixed32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSFixed32NoTag(value: Int) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
fun writeFixed64(fieldNumber: Int, value: Long?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_64)
|
||||
writeFixed64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeFixed64NoTag(value: Long) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
// See notes on unsigned integers implementation above
|
||||
fun writeSFixed64(fieldNumber: Int, value: Long?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_64)
|
||||
writeSFixed64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSFixed64NoTag(value: Long) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
fun writeDouble(fieldNumber: Int, value: Double?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_64)
|
||||
writeDoubleNoTag(value)
|
||||
}
|
||||
|
||||
fun writeDoubleNoTag(value: Double) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
fun writeFloat(fieldNumber: Int, value: Float?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.FIX_32)
|
||||
writeFloatNoTag(value)
|
||||
}
|
||||
|
||||
fun writeFloatNoTag(value: Float) {
|
||||
writeLittleEndian(value)
|
||||
}
|
||||
|
||||
fun writeString(fieldNumber: Int, value: String?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.LENGTH_DELIMITED)
|
||||
writeStringNoTag(value)
|
||||
}
|
||||
|
||||
fun writeStringNoTag(value: String) {
|
||||
writeInt32NoTag(value.length)
|
||||
output.write(value.toByteArray(Charsets.UTF_8))
|
||||
}
|
||||
|
||||
fun writeBytes(fieldNumber: Int, value: ByteArray?) {
|
||||
value ?: return
|
||||
writeTag(fieldNumber, WireType.LENGTH_DELIMITED)
|
||||
writeBytesNoTag(value)
|
||||
}
|
||||
|
||||
fun writeBytesNoTag(value: ByteArray) {
|
||||
writeInt32NoTag(value.size)
|
||||
output.write(value)
|
||||
}
|
||||
|
||||
/** ============ 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.
|
||||
*/
|
||||
|
||||
fun writeLittleEndian(value: Int?) {
|
||||
value ?: return
|
||||
val bb = ByteBuffer.allocate(4)
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
bb.putInt(value)
|
||||
output.write(bb.array())
|
||||
}
|
||||
|
||||
fun writeLittleEndian(value: Long?) {
|
||||
value ?: return
|
||||
val bb = ByteBuffer.allocate(8)
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
bb.putLong(value)
|
||||
output.write(bb.array())
|
||||
}
|
||||
|
||||
fun writeLittleEndian(value: Double?) {
|
||||
value ?: return
|
||||
val bb = ByteBuffer.allocate(8)
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
bb.putDouble(value)
|
||||
output.write(bb.array())
|
||||
}
|
||||
|
||||
fun writeLittleEndian(value: Float?) {
|
||||
value ?: return
|
||||
val bb = ByteBuffer.allocate(4)
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
bb.putFloat(value)
|
||||
output.write(bb.array())
|
||||
}
|
||||
|
||||
fun writeInt32NoTag(value: Int?) {
|
||||
value ?: return
|
||||
var curValue: Int = 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 {
|
||||
// encode current 7 bits
|
||||
var curByte = (curValue and WireFormat.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 VARINT_UTIL_BIT_MASK
|
||||
}
|
||||
|
||||
res[resSize] = curByte.toByte()
|
||||
resSize++
|
||||
} while(curValue != 0)
|
||||
output.write(res, 0, resSize)
|
||||
}
|
||||
|
||||
fun writeInt64NoTag(value: Long?) {
|
||||
value ?: return
|
||||
var curValue: Long = value
|
||||
|
||||
// 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) {
|
||||
// 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 VARINT_UTIL_BIT_MASK.toLong()
|
||||
}
|
||||
|
||||
res[resSize] = curByte.toByte()
|
||||
resSize++
|
||||
}
|
||||
output.write(res, 0, resSize)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Created by user on 7/7/16.
|
||||
*/
|
||||
|
||||
class InvalidProtocolBufferException(
|
||||
override val message: String? = null,
|
||||
override val cause : Throwable? = null
|
||||
) : Throwable(message, cause) {
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.martiansoftware.jsap.JSAP
|
||||
import com.martiansoftware.jsap.JSAPResult
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.netty.handler.codec.http.*
|
||||
import proto.Carkot
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
@@ -46,17 +45,17 @@ fun main(args: Array<String>) {
|
||||
return;
|
||||
}
|
||||
|
||||
val bytesBinTest = Carkot.Upload.newBuilder().setData(ByteString.copyFrom(fileBytes)).setBase(mcuSystem).build().toByteArray()
|
||||
val request = DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/loadBin", Unpooled.copiedBuffer(bytesBinTest));
|
||||
request.headers().set(HttpHeaderNames.HOST, host)
|
||||
request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
|
||||
request.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes())
|
||||
request.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8")
|
||||
|
||||
client.Client.sendRequest(request, host, port)
|
||||
println(client.ClientHandler.requestResult.code)
|
||||
println(client.ClientHandler.requestResult.stdErr)
|
||||
println(client.ClientHandler.requestResult.stdOut)
|
||||
// val bytesBinTest = Carkot.Upload.newBuilder().setData(ByteString.copyFrom(fileBytes)).setBase(mcuSystem).build().toByteArray()
|
||||
// val request = DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/loadBin", Unpooled.copiedBuffer(bytesBinTest));
|
||||
// request.headers().set(HttpHeaderNames.HOST, host)
|
||||
// request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE)
|
||||
// request.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes())
|
||||
// request.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8")
|
||||
//
|
||||
// client.Client.sendRequest(request, host, port)
|
||||
// println(client.ClientHandler.requestResult.code)
|
||||
// println(client.ClientHandler.requestResult.stdErr)
|
||||
// println(client.ClientHandler.requestResult.stdOut)
|
||||
}
|
||||
|
||||
fun saveFileConfig(actualValues: Map<String, String>) {
|
||||
@@ -102,7 +101,6 @@ fun readFileConfig(): Map<String, String> {
|
||||
result.put(keyValuePair[0], keyValuePair[1])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Created by user on 7/6/16.
|
||||
*/
|
||||
|
||||
|
||||
object WireFormat {
|
||||
// couple of constants for magic numbers
|
||||
val TAG_TYPE_BITS: Int = 3
|
||||
val TAG_TYPE_MASK: Int = (1 shl TAG_TYPE_BITS) - 1
|
||||
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
|
||||
val FIXED_32_BYTE_SIZE: Int = 4
|
||||
val FIXED_64_BYTE_SIZE: Int = 8
|
||||
|
||||
fun getTagWireType(tag: Int): WireType {
|
||||
return WireType from (tag and TAG_TYPE_MASK).toByte()
|
||||
}
|
||||
|
||||
fun getTagFieldNumber(tag: Int): Int {
|
||||
return tag ushr TAG_TYPE_BITS
|
||||
}
|
||||
|
||||
// TODO: refactor casts into function overloading as soon as translator will support it
|
||||
fun getTagSize(fieldNumber: Int, wireType: WireType): Int {
|
||||
return getVarint32Size((fieldNumber shl 3) or wireType.ordinal)
|
||||
}
|
||||
|
||||
fun getVarint32Size(value: Int): Int {
|
||||
var curValue = value
|
||||
var size = 0
|
||||
while (curValue != 0) {
|
||||
size += 1
|
||||
curValue = value ushr VARINT_INFO_BITS_COUNT
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
fun getVarint64Size(value: Long): Int {
|
||||
var curValue = value
|
||||
var size = 0
|
||||
while (curValue != 0L) {
|
||||
size += 1
|
||||
curValue = value ushr VARINT_INFO_BITS_COUNT
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
fun getZigZag32Size(value: Int): Int {
|
||||
return getVarint32Size((value shl 1) xor (value shr 31))
|
||||
}
|
||||
|
||||
fun getZigZag64Size(value: Long): Int {
|
||||
return getVarint64Size((value shl 1) xor (value shr 63))
|
||||
}
|
||||
|
||||
fun getInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getVarint32Size(value)
|
||||
}
|
||||
|
||||
fun getUInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getInt32Size(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun getInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getVarint64Size(value)
|
||||
}
|
||||
|
||||
fun getUInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getInt64Size(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun getBoolSize(fieldNumber: Int, value: Boolean): Int {
|
||||
val intValue = if (value) 1 else 0
|
||||
return getInt32Size(fieldNumber, intValue)
|
||||
}
|
||||
|
||||
fun getEnumSize(fieldNumber: Int, value: Int): Int {
|
||||
return getInt32Size(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun getSInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getZigZag32Size(value)
|
||||
}
|
||||
|
||||
fun getSInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getZigZag64Size(value)
|
||||
}
|
||||
|
||||
fun getFixed32Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFixed64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getDoubleSize(fieldNumber: Int, value: Double): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFloatSize(fieldNumber: Int, value: Float): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getStringSize(fieldNumber: Int, value: String): Int {
|
||||
val encodedStringSize = value.toByteArray(Charsets.UTF_8).size //TODO: not sure if it's the best way to do it
|
||||
return encodedStringSize + getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + getVarint32Size(encodedStringSize)
|
||||
}
|
||||
|
||||
fun getBytesSize(fieldNumber: Int, value: ByteArray): Int {
|
||||
return value.size + getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + getVarint32Size(value.size)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
enum class WireType(val id: Int) {
|
||||
VARINT(0), // int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||
FIX_64(1), // fixed64, sfixed64, double
|
||||
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
|
||||
|
||||
companion object {
|
||||
infix fun from (value: Byte): WireType {
|
||||
return when (value) {
|
||||
0.toByte() -> VARINT
|
||||
1.toByte() -> FIX_64
|
||||
2.toByte() -> LENGTH_DELIMITED
|
||||
3.toByte() -> START_GROUP
|
||||
4.toByte() -> END_GROUP
|
||||
5.toByte() -> FIX_32
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
class Upload private constructor (data: ByteArray = ByteArray(0), base: kotlin.String = "", method: Method = Upload.Method.BuilderMethod().build()) {
|
||||
var data : ByteArray
|
||||
private set
|
||||
|
||||
var base : kotlin.String
|
||||
private set
|
||||
|
||||
var method : Method
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.data = data
|
||||
this.base = base
|
||||
this.method = method
|
||||
}
|
||||
class Method private constructor (type: TYPE = Upload.Method.TYPE.fromIntToTYPE(0), port: kotlin.String = "", device: kotlin.String = "", arguments: MutableList <kotlin.String> = mutableListOf()) {
|
||||
var type : TYPE
|
||||
private set
|
||||
|
||||
var port : kotlin.String
|
||||
private set
|
||||
|
||||
var device : kotlin.String
|
||||
private set
|
||||
|
||||
var arguments : MutableList <kotlin.String>
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.type = type
|
||||
this.port = port
|
||||
this.device = device
|
||||
this.arguments = arguments
|
||||
}
|
||||
enum class TYPE(val ord: Int) {
|
||||
DFU (0),
|
||||
STLINK (1);
|
||||
|
||||
companion object {
|
||||
fun fromIntToTYPE (ord: Int): TYPE {
|
||||
return when (ord) {
|
||||
0 -> TYPE.DFU
|
||||
1 -> TYPE.STLINK
|
||||
else -> throw InvalidProtocolBufferException("Error: got unexpected int ${ord} while parsing TYPE ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun writeTo (output: CodedOutputStream): Unit {
|
||||
output.writeEnum (1, type.ord)
|
||||
output.writeString (2, port)
|
||||
output.writeString (3, device)
|
||||
if (arguments.size > 0) {
|
||||
output.writeTag(4, WireType.LENGTH_DELIMITED)
|
||||
var arrayByteSize = 0
|
||||
run {
|
||||
var arraySize = 0
|
||||
for (item in arguments) {
|
||||
arraySize += WireFormat.getStringSize(4, item)
|
||||
}
|
||||
arrayByteSize += arraySize
|
||||
}
|
||||
output.writeInt32NoTag(arrayByteSize)
|
||||
for (item in arguments) {
|
||||
output.writeString (4, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuilderMethod constructor (type: TYPE = Upload.Method.TYPE.fromIntToTYPE(0), port: kotlin.String = "", device: kotlin.String = "", arguments: MutableList <kotlin.String> = mutableListOf()) {
|
||||
var type : TYPE
|
||||
private set
|
||||
fun setType(value: TYPE): Upload.Method.BuilderMethod {
|
||||
type = value
|
||||
return this
|
||||
}
|
||||
|
||||
var port : kotlin.String
|
||||
private set
|
||||
fun setPort(value: kotlin.String): Upload.Method.BuilderMethod {
|
||||
port = value
|
||||
return this
|
||||
}
|
||||
|
||||
var device : kotlin.String
|
||||
private set
|
||||
fun setDevice(value: kotlin.String): Upload.Method.BuilderMethod {
|
||||
device = value
|
||||
return this
|
||||
}
|
||||
|
||||
var arguments : MutableList <kotlin.String>
|
||||
private set
|
||||
fun setArguments(value: MutableList <kotlin.String> ): Upload.Method.BuilderMethod {
|
||||
arguments = value
|
||||
return this
|
||||
}
|
||||
fun setkotlin.String(index: Int, value: kotlin.String): {
|
||||
arguments[index] = value
|
||||
return this
|
||||
}
|
||||
fun addkotlin.String(value: kotlin.String): {
|
||||
arguments.add(value)
|
||||
return this
|
||||
}
|
||||
fun addAllkotlin.String(value: Iterable<kotlin.String>): {
|
||||
for (item in value) {
|
||||
arguments.add(item)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
this.type = type
|
||||
this.port = port
|
||||
this.device = device
|
||||
this.arguments = arguments
|
||||
}
|
||||
|
||||
fun readFrom (input: CodedInputStream): Upload.Method.BuilderMethod {
|
||||
type = TYPE.fromIntToTYPE(input.readEnum(1))
|
||||
port = input.readString(2)
|
||||
device = input.readString(3)
|
||||
val tag = input.readTag(4, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: kotlin.String.Builderkotlin.String = kotlin.String.Builderkotlin.String()
|
||||
tmp = input.readString(4)
|
||||
readSize += WireFormat.getStringSize(4, tmp)
|
||||
arguments.add(tmp.build())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Method {
|
||||
return Method(type, port, device, arguments)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
if (input.isAtEnd()) { return false }
|
||||
val tag = input.readInt32NoTag()
|
||||
if (tag == 0) { return false }
|
||||
val fieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val wireType = WireFormat.getTagWireType(tag)
|
||||
when(fieldNumber) {
|
||||
1 -> type = TYPE.fromIntToTYPE(input.readEnumNoTag())
|
||||
2 -> port = input.readStringNoTag()
|
||||
3 -> device = input.readStringNoTag()
|
||||
4 -> {
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: kotlin.String.Builderkotlin.String = kotlin.String.Builderkotlin.String()
|
||||
tmp = input.readString(4)
|
||||
readSize += WireFormat.getStringSize(4, tmp)
|
||||
arguments.add(tmp.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
return true}
|
||||
fun parseFrom(input: CodedInputStream): Upload.Method.BuilderMethod {
|
||||
while(parseFieldFrom(input)) {}
|
||||
return this
|
||||
}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getEnumSize(1, type.ord)
|
||||
size += WireFormat.getStringSize(2, port)
|
||||
size += WireFormat.getStringSize(3, device)
|
||||
run {
|
||||
var arraySize = 0
|
||||
for (item in arguments) {
|
||||
arraySize += WireFormat.getStringSize(4, item)
|
||||
}
|
||||
size += arraySize + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
|
||||
}
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: Method) {
|
||||
type = other.type
|
||||
port = other.port
|
||||
device = other.device
|
||||
arguments.addAll(other.arguments)
|
||||
}
|
||||
|
||||
fun mergeFrom (input: CodedInputStream) {
|
||||
val builder = Upload.Method.BuilderMethod()
|
||||
mergeWith(builder.parseFrom(input).build())}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getEnumSize(1, type.ord)
|
||||
size += WireFormat.getStringSize(2, port)
|
||||
size += WireFormat.getStringSize(3, device)
|
||||
run {
|
||||
var arraySize = 0
|
||||
for (item in arguments) {
|
||||
arraySize += WireFormat.getStringSize(4, item)
|
||||
}
|
||||
size += arraySize + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
|
||||
}
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun writeTo (output: CodedOutputStream): Unit {
|
||||
output.writeBytes (1, data)
|
||||
output.writeString (2, base)
|
||||
output.writeTag(3, WireType.LENGTH_DELIMITED)
|
||||
output.writeInt32NoTag(method.getSize())
|
||||
method.writeTo(output)
|
||||
}
|
||||
|
||||
class BuilderUpload constructor (data: ByteArray = ByteArray(0), base: kotlin.String = "", method: Method = Upload.Method.BuilderMethod().build()) {
|
||||
var data : ByteArray
|
||||
private set
|
||||
fun setData(value: ByteArray): Upload.BuilderUpload {
|
||||
data = value
|
||||
return this
|
||||
}
|
||||
|
||||
var base : kotlin.String
|
||||
private set
|
||||
fun setBase(value: kotlin.String): Upload.BuilderUpload {
|
||||
base = value
|
||||
return this
|
||||
}
|
||||
|
||||
var method : Method
|
||||
private set
|
||||
fun setMethod(value: Method): Upload.BuilderUpload {
|
||||
method = value
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
this.data = data
|
||||
this.base = base
|
||||
this.method = method
|
||||
}
|
||||
|
||||
fun readFrom (input: CodedInputStream): Upload.BuilderUpload {
|
||||
data = input.readBytes(1)
|
||||
base = input.readString(2)
|
||||
input.readTag(3, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
method.mergeFrom(input)
|
||||
if (expectedSize != method.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${method.getSize()}") }
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Upload {
|
||||
return Upload(data, base, method)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
if (input.isAtEnd()) { return false }
|
||||
val tag = input.readInt32NoTag()
|
||||
if (tag == 0) { return false }
|
||||
val fieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val wireType = WireFormat.getTagWireType(tag)
|
||||
when(fieldNumber) {
|
||||
1 -> data = input.readBytesNoTag()
|
||||
2 -> base = input.readStringNoTag()
|
||||
3 -> {
|
||||
input.readTag(3, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
method.mergeFrom(input)
|
||||
if (expectedSize != method.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${method.getSize()}") }
|
||||
}
|
||||
}
|
||||
return true}
|
||||
fun parseFrom(input: CodedInputStream): Upload.BuilderUpload {
|
||||
while(parseFieldFrom(input)) {}
|
||||
return this
|
||||
}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getBytesSize(1, data)
|
||||
size += WireFormat.getStringSize(2, base)
|
||||
size += method.getSize() + WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(method.getSize())
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: Upload) {
|
||||
data.plus(other.data)
|
||||
base = other.base
|
||||
method = other.method
|
||||
}
|
||||
|
||||
fun mergeFrom (input: CodedInputStream) {
|
||||
val builder = Upload.BuilderUpload()
|
||||
mergeWith(builder.parseFrom(input).build())}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getBytesSize(1, data)
|
||||
size += WireFormat.getStringSize(2, base)
|
||||
size += method.getSize() + WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(method.getSize())
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UploadResult private constructor (stdOut: kotlin.String = "", stdErr: kotlin.String = "", resultCode: Int = 0) {
|
||||
var stdOut : kotlin.String
|
||||
private set
|
||||
|
||||
var stdErr : kotlin.String
|
||||
private set
|
||||
|
||||
var resultCode : Int
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.stdOut = stdOut
|
||||
this.stdErr = stdErr
|
||||
this.resultCode = resultCode
|
||||
}
|
||||
|
||||
fun writeTo (output: CodedOutputStream): Unit {
|
||||
output.writeString (1, stdOut)
|
||||
output.writeString (2, stdErr)
|
||||
output.writeInt32 (3, resultCode)
|
||||
}
|
||||
|
||||
class BuilderUploadResult constructor (stdOut: kotlin.String = "", stdErr: kotlin.String = "", resultCode: Int = 0) {
|
||||
var stdOut : kotlin.String
|
||||
private set
|
||||
fun setStdOut(value: kotlin.String): UploadResult.BuilderUploadResult {
|
||||
stdOut = value
|
||||
return this
|
||||
}
|
||||
|
||||
var stdErr : kotlin.String
|
||||
private set
|
||||
fun setStdErr(value: kotlin.String): UploadResult.BuilderUploadResult {
|
||||
stdErr = value
|
||||
return this
|
||||
}
|
||||
|
||||
var resultCode : Int
|
||||
private set
|
||||
fun setResultCode(value: Int): UploadResult.BuilderUploadResult {
|
||||
resultCode = value
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
this.stdOut = stdOut
|
||||
this.stdErr = stdErr
|
||||
this.resultCode = resultCode
|
||||
}
|
||||
|
||||
fun readFrom (input: CodedInputStream): UploadResult.BuilderUploadResult {
|
||||
stdOut = input.readString(1)
|
||||
stdErr = input.readString(2)
|
||||
resultCode = input.readInt32(3)
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): UploadResult {
|
||||
return UploadResult(stdOut, stdErr, resultCode)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
if (input.isAtEnd()) { return false }
|
||||
val tag = input.readInt32NoTag()
|
||||
if (tag == 0) { return false }
|
||||
val fieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val wireType = WireFormat.getTagWireType(tag)
|
||||
when(fieldNumber) {
|
||||
1 -> stdOut = input.readStringNoTag()
|
||||
2 -> stdErr = input.readStringNoTag()
|
||||
3 -> resultCode = input.readInt32NoTag()
|
||||
}
|
||||
return true}
|
||||
fun parseFrom(input: CodedInputStream): UploadResult.BuilderUploadResult {
|
||||
while(parseFieldFrom(input)) {}
|
||||
return this
|
||||
}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getStringSize(1, stdOut)
|
||||
size += WireFormat.getStringSize(2, stdErr)
|
||||
size += WireFormat.getInt32Size(3, resultCode)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: UploadResult) {
|
||||
stdOut = other.stdOut
|
||||
stdErr = other.stdErr
|
||||
resultCode = other.resultCode
|
||||
}
|
||||
|
||||
fun mergeFrom (input: CodedInputStream) {
|
||||
val builder = UploadResult.BuilderUploadResult()
|
||||
mergeWith(builder.parseFrom(input).build())}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getStringSize(1, stdOut)
|
||||
size += WireFormat.getStringSize(2, stdErr)
|
||||
size += WireFormat.getInt32Size(3, resultCode)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LogMessage private constructor (source: kotlin.String = "", message: ByteArray = ByteArray(0)) {
|
||||
var source : kotlin.String
|
||||
private set
|
||||
|
||||
var message : ByteArray
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.source = source
|
||||
this.message = message
|
||||
}
|
||||
|
||||
fun writeTo (output: CodedOutputStream): Unit {
|
||||
output.writeString (1, source)
|
||||
output.writeBytes (2, message)
|
||||
}
|
||||
|
||||
class BuilderLogMessage constructor (source: kotlin.String = "", message: ByteArray = ByteArray(0)) {
|
||||
var source : kotlin.String
|
||||
private set
|
||||
fun setSource(value: kotlin.String): LogMessage.BuilderLogMessage {
|
||||
source = value
|
||||
return this
|
||||
}
|
||||
|
||||
var message : ByteArray
|
||||
private set
|
||||
fun setMessage(value: ByteArray): LogMessage.BuilderLogMessage {
|
||||
message = value
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
this.source = source
|
||||
this.message = message
|
||||
}
|
||||
|
||||
fun readFrom (input: CodedInputStream): LogMessage.BuilderLogMessage {
|
||||
source = input.readString(1)
|
||||
message = input.readBytes(2)
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): LogMessage {
|
||||
return LogMessage(source, message)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
if (input.isAtEnd()) { return false }
|
||||
val tag = input.readInt32NoTag()
|
||||
if (tag == 0) { return false }
|
||||
val fieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val wireType = WireFormat.getTagWireType(tag)
|
||||
when(fieldNumber) {
|
||||
1 -> source = input.readStringNoTag()
|
||||
2 -> message = input.readBytesNoTag()
|
||||
}
|
||||
return true}
|
||||
fun parseFrom(input: CodedInputStream): LogMessage.BuilderLogMessage {
|
||||
while(parseFieldFrom(input)) {}
|
||||
return this
|
||||
}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getStringSize(1, source)
|
||||
size += WireFormat.getBytesSize(2, message)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: LogMessage) {
|
||||
source = other.source
|
||||
message.plus(other.message)
|
||||
}
|
||||
|
||||
fun mergeFrom (input: CodedInputStream) {
|
||||
val builder = LogMessage.BuilderLogMessage()
|
||||
mergeWith(builder.parseFrom(input).build())}
|
||||
fun getSize(): Int {
|
||||
var size = 0
|
||||
size += WireFormat.getStringSize(1, source)
|
||||
size += WireFormat.getBytesSize(2, message)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,27 +11,34 @@ import java.net.ConnectException
|
||||
/**
|
||||
* Created by user on 7/8/16.
|
||||
*/
|
||||
object Client {
|
||||
class Client constructor(host: String, port: Int) {
|
||||
|
||||
fun sendRequest(request: HttpRequest, host: String, port: Int):Int {
|
||||
val group = NioEventLoopGroup()
|
||||
val host: String
|
||||
val port: Int
|
||||
|
||||
init {
|
||||
this.host = host
|
||||
this.port = port
|
||||
}
|
||||
|
||||
fun sendRequest(request: HttpRequest) {
|
||||
val group = NioEventLoopGroup(1)
|
||||
try {
|
||||
val bootstrap: Bootstrap = Bootstrap()
|
||||
val bootstrap = Bootstrap()
|
||||
bootstrap.group(group).channel(NioSocketChannel().javaClass).handler(ClientInitializer())
|
||||
val channelFuture = bootstrap.connect(host, port).sync()
|
||||
val channel = channelFuture.channel()
|
||||
channel.writeAndFlush(request)
|
||||
channel.closeFuture().sync()
|
||||
} catch (e: InterruptedException) {
|
||||
println("interrupted before request done")
|
||||
return 2
|
||||
ClientHandler.requestResult.code = 2
|
||||
ClientHandler.requestResult.errorString = "command execution interrupted"
|
||||
} catch (e: ConnectException) {
|
||||
println("connection error to $host:$port")
|
||||
return 1
|
||||
ClientHandler.requestResult.code = 1
|
||||
ClientHandler.requestResult.errorString = "don't can connect to server ($host:$port)"
|
||||
} finally {
|
||||
group.shutdownGracefully()
|
||||
}
|
||||
return ClientHandler.requestResult.code
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import com.google.protobuf.InvalidProtocolBufferException
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.channel.SimpleChannelInboundHandler
|
||||
import io.netty.handler.codec.http.HttpContent
|
||||
import proto.Carkot
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by user on 7/8/16.
|
||||
@@ -28,10 +26,10 @@ class ClientHandler : SimpleChannelInboundHandler<Any> {
|
||||
val resultStdOut:String
|
||||
val resultStdErr:String
|
||||
try {
|
||||
val uploadResult: Carkot.UploadResult = Carkot.UploadResult.parseFrom(contentBytes)
|
||||
resultCode = uploadResult.resultCode
|
||||
resultStdOut = uploadResult.stdOut
|
||||
resultStdErr = uploadResult.stdErr
|
||||
// val uploadResult: Carkot.UploadResult = Carkot.UploadResult.parseFrom(contentBytes)
|
||||
// resultCode = uploadResult.resultCode
|
||||
// resultStdOut = uploadResult.stdOut
|
||||
// resultStdErr = uploadResult.stdErr
|
||||
} catch (e: InvalidProtocolBufferException) {
|
||||
e.printStackTrace()
|
||||
resultStdErr = ""
|
||||
@@ -39,9 +37,9 @@ class ClientHandler : SimpleChannelInboundHandler<Any> {
|
||||
resultCode = 2
|
||||
}
|
||||
synchronized(requestResult, {
|
||||
requestResult.code = resultCode
|
||||
requestResult.stdErr = resultStdErr
|
||||
requestResult.stdOut = resultStdOut
|
||||
// requestResult.code = resultCode
|
||||
// requestResult.stdErr = resultStdErr
|
||||
// requestResult.stdOut = resultStdOut
|
||||
})
|
||||
ctx.close()
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user