diff --git a/protocol/src/test/kotlin/Main.kt b/protocol/src/test/kotlin/Main.kt new file mode 100644 index 00000000..a1d4613d --- /dev/null +++ b/protocol/src/test/kotlin/Main.kt @@ -0,0 +1,266 @@ +import com.zfoo.kotlin.ByteBuffer +import com.zfoo.kotlin.ProtocolManager +import com.zfoo.kotlin.ProtocolManager.Companion.initProtocol +import com.zfoo.kotlin.ProtocolManager.Companion.read +import com.zfoo.kotlin.ProtocolManager.Companion.write +import java.io.* + +/** + * @author godotg + */ +fun main() { + println("zfoo test") + initProtocol() + byteBufferTest() + compatibleTest() + normalReadTest() +} + + +fun byteBufferTest() { + byteTest() + bytesTest() + shortTest() + intTest() + longTest() + floatTest() + doubleTest() + stringTest() +} + +fun byteTest() { + val value: Byte = 9 + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeByte(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readByte() + assertObjectEquals(value, readValue) +} + +fun bytesTest() { + val value = byteArrayOf(1, 2, 3) + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeBytes(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readBytes(3) + assertArrayEquals(value, readValue) +} + +fun shortTest() { + val value: Short = 9999 + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeShort(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readShort() + assertObjectEquals(value, readValue) +} + +fun intTest() { + val value = 99999999 + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeInt(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readInt() + assertObjectEquals(value, readValue) +} + +fun longTest() { + val value = 9999999999999999L + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeLong(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readLong() + assertObjectEquals(value, readValue) +} + +fun floatTest() { + val value = 999999.56f + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeFloat(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readFloat() + assertObjectEquals(value, readValue) +} + +fun doubleTest() { + val value = 999999.56 + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeDouble(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readDouble() + assertObjectEquals(value, readValue) +} + +fun stringTest() { + val value = "aaa" + val writerByteBuffer = ByteBuffer() + writerByteBuffer.writeString(value) + val bytes = writerByteBuffer.toBytes() + + val readerByteBuffer = ByteBuffer() + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readString() + assertObjectEquals(value, readValue) +} + +fun assertObjectEquals(a: Any, b: Any) { + if (a == b) { + return + } + + throw RuntimeException("a is not equals b") +} + +fun assertArrayEquals(a: ByteArray?, b: ByteArray?) { + if (a == b) { + return + } + if (a != null && b != null && a.size == b.size) { + for (i in a.indices) { + assertObjectEquals(a[i], b[i]) + } + return + } + throw RuntimeException("a is not equals b") +} + +// ----------------------------------------------------------------------------------------------------------------- +@Throws(IOException::class) +fun compatibleTest() { + val bytes = + toByteArray(FileInputStream("C:\\github\\zfoo\\protocol\\src\\test\\resources\\complexObject.bytes")) + val buffer = ByteBuffer() + buffer.writeBytes(bytes) + + val packet = read(buffer) + + val newBuffer = ByteBuffer() + write(newBuffer, packet!!) + + buffer.setReadOffset(0) + newBuffer.setReadOffset(0) + + var equal = 0 + var notEqual = 0 + for (i in 0 until buffer.writeOffset()) { + val a = buffer.readByte() + val b = newBuffer.readByte() + if (a == b) { + equal++ + } else { + notEqual++ + } + } + println(format("equal [{}], not equal [{}]", equal, notEqual)) +} + + +@Throws(IOException::class) +fun normalReadTest() { +// var bytes = toByteArray(FileInputStream("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-inner-compatible.bytes")); +// var bytes = toByteArray(FileInputStream("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-compatible.bytes")); +// var bytes = toByteArray(FileInputStream ("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-inner-compatible.bytes")); + var bytes = + toByteArray(FileInputStream("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-inner-compatible.bytes")); +// val bytes = toByteArray(FileInputStream("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-inner-inner-compatible.bytes")) + + val buffer = ByteBuffer() + buffer.writeBytes(bytes) + val packet = read(buffer) + + var newBuffer = ByteBuffer(); + ProtocolManager.write(newBuffer, packet) + var newPacket = ProtocolManager.read(newBuffer) + + println(packet) + println(newPacket) +} + + +// ----------------------------------------------------------------------------------------------------------------- +@Throws(IOException::class) +fun toByteArray(input: InputStream): ByteArray { + val output = ByteArrayOutputStream() + copy(input, output) + val bytes = output.toByteArray() + return bytes +} + +const val EOF: Int = -1 + +// The number of bytes in a byte +const val ONE_BYTE: Int = 1 + +// The number of bytes in a kilobyte +const val BYTES_PER_KB: Int = ONE_BYTE * 1024 + +// The number of bytes in a megabyte +const val BYTES_PER_MB: Int = BYTES_PER_KB * 1024 + +// The number of bytes in a gigabyte +const val BYTES_PER_GB: Long = (BYTES_PER_MB * 1024).toLong() + +@Throws(IOException::class) +fun copy(input: InputStream, output: OutputStream): Int { + val buffer = ByteArray(BYTES_PER_KB) + var count: Long = 0 + var n: Int + while (EOF != (input.read(buffer).also { n = it })) { + output.write(buffer, 0, n) + count += n.toLong() + } + + if (count > BYTES_PER_GB * 2L) { + return -1 + } + return count.toInt() +} + +fun format(template: String, vararg args: Any?): String { + // 初始化定义好的长度以获得更好的性能 + val builder = StringBuilder(template.length + 50) + + // 记录已经处理到的位置 + var readIndex = 0 + for (i in args.indices) { + // 占位符所在位置 + val placeholderIndex = template.indexOf("{}", readIndex) + // 剩余部分无占位符 + if (placeholderIndex == -1) { + // 不带占位符的模板直接返回 + if (readIndex == 0) { + return template + } + break + } + + builder.append(template, readIndex, placeholderIndex) + builder.append(args[i]) + readIndex = placeholderIndex + 2 + } + + // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + builder.append(template, readIndex, template.length) + return builder.toString() +} diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/ByteBuffer.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/ByteBuffer.kt new file mode 100644 index 00000000..2850f208 --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/ByteBuffer.kt @@ -0,0 +1,1241 @@ +package com.zfoo.kotlin + +import java.nio.charset.Charset + +class ByteBuffer { + private var buffer = ByteArray(INIT_SIZE) + private var writeOffset = 0 + private var readOffset = 0 + fun adjustPadding(predictionLength: Int, beforewriteIndex: Int) { + // 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置 + val currentwriteIndex = writeOffset + val predictionCount = writeIntCount(predictionLength) + val length = currentwriteIndex - beforewriteIndex - predictionCount + val lengthCount = writeIntCount(length) + val padding = lengthCount - predictionCount + if (padding == 0) { + writeOffset = beforewriteIndex + writeInt(length) + writeOffset = currentwriteIndex + } else { + val bytes = ByteArray(length) + System.arraycopy(buffer, currentwriteIndex - length, bytes, 0, length) + writeOffset = beforewriteIndex + writeInt(length) + writeBytes(bytes) + } + } + + fun compatibleRead(beforereadIndex: Int, length: Int): Boolean { + return length != -1 && readOffset < length + beforereadIndex + } + + // -------------------------------------------------get/set------------------------------------------------- + fun writeOffset(): Int { + return writeOffset + } + + fun setwriteOffset(writeIndex: Int) { + if (writeIndex > buffer.size) { + throw RuntimeException( + "writeIndex[" + writeIndex + "] out of bounds exception: readerIndex: " + readOffset + + ", writerIndex: " + writeOffset + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + buffer.size + ) + } + writeOffset = writeIndex + } + + fun readOffset(): Int { + return readOffset + } + + fun setReadOffset(readIndex: Int) { + if (readIndex > writeOffset) { + throw RuntimeException( + "readIndex[" + readIndex + "] out of bounds exception: readerIndex: " + readOffset + + ", writerIndex: " + writeOffset + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + buffer.size + ) + } + readOffset = readIndex + } + + fun toBytes(): ByteArray { + val bytes = ByteArray(writeOffset) + System.arraycopy(buffer, 0, bytes, 0, writeOffset) + return bytes + } + + val isReadable: Boolean + get() = writeOffset > readOffset + + // -------------------------------------------------write/read------------------------------------------------- + fun writeBool(value: Boolean) { + ensureCapacity(1) + buffer[writeOffset] = if (value) 1.toByte() else 0.toByte() + writeOffset++ + } + + fun readBool(): Boolean { + val byteValue = buffer[readOffset] + readOffset++ + return byteValue.toInt() == 1 + } + + fun writeByte(value: Byte) { + ensureCapacity(1) + buffer[writeOffset++] = value + } + + fun readByte(): Byte { + return buffer[readOffset++] + } + + val capacity: Int + get() = buffer.size - writeOffset + + fun ensureCapacity(capacity: Int) { + while (capacity - this.capacity > 0) { + val newSize = buffer.size * 2 + if (newSize > MAX_SIZE) { + throw RuntimeException("Bytebuf max size is [655537], out of memory error") + } + val newBytes = ByteArray(newSize) + System.arraycopy(buffer, 0, newBytes, 0, buffer.size) + buffer = newBytes + } + } + + @JvmOverloads + fun writeBytes(bytes: ByteArray, length: Int = bytes.size) { + ensureCapacity(length) + System.arraycopy(bytes, 0, buffer, writeOffset, length) + writeOffset += length + } + + fun readBytes(count: Int): ByteArray { + val bytes = ByteArray(count) + System.arraycopy(buffer, readOffset, bytes, 0, count) + readOffset += count + return bytes + } + + fun writeShort(value: Short) { + ensureCapacity(2) + buffer[writeOffset++] = (value.toInt() ushr 8).toByte() + buffer[writeOffset++] = value.toByte() + } + + fun readShort(): Short { + return (buffer[readOffset++].toInt() shl 8 or (buffer[readOffset++].toInt() and 255)).toShort() + } + + // *******************************************int*************************************************** + fun writeInt(value: Int): Int { + return writeVarInt(value shl 1 xor (value shr 31)) + } + + fun writeVarInt(value: Int): Int { + var a = value ushr 7 + if (a == 0) { + writeByte(value.toByte()) + return 1 + } + ensureCapacity(5) + buffer[writeOffset++] = (value or 0x80).toByte() + var b = value ushr 14 + if (b == 0) { + buffer[writeOffset++] = a.toByte() + return 2 + } + buffer[writeOffset++] = (a or 0x80).toByte() + a = value ushr 21 + if (a == 0) { + buffer[writeOffset++] = b.toByte() + return 3 + } + buffer[writeOffset++] = (b or 0x80).toByte() + b = value ushr 28 + if (b == 0) { + buffer[writeOffset++] = a.toByte() + return 4 + } + buffer[writeOffset++] = (a or 0x80).toByte() + buffer[writeOffset++] = b.toByte() + return 5 + } + + fun readInt(): Int { + var b = readByte().toInt() + var value = b + if (b < 0) { + b = readByte().toInt() + value = value and 0x0000007F or (b shl 7) + if (b < 0) { + b = readByte().toInt() + value = value and 0x00003FFF or (b shl 14) + if (b < 0) { + b = readByte().toInt() + value = value and 0x001FFFFF or (b shl 21) + if (b < 0) { + value = value and 0x0FFFFFFF or (readByte().toInt() shl 28) + } + } + } + } + return value ushr 1 xor -(value and 1) + } + + fun writeIntCount(value: Int): Int { + var value = value + value = value shl 1 xor (value shr 31) + if (value ushr 7 == 0) { + return 1 + } + if (value ushr 14 == 0) { + return 2 + } + if (value ushr 21 == 0) { + return 3 + } + return if (value ushr 28 == 0) { + 4 + } else 5 + } + + // 写入没有压缩的int + fun writeRawInt(value: Int) { + ensureCapacity(4) + buffer[writeOffset++] = (value ushr 24).toByte() + buffer[writeOffset++] = (value ushr 16).toByte() + buffer[writeOffset++] = (value ushr 8).toByte() + buffer[writeOffset++] = value.toByte() + } + + // 读取没有压缩的int + fun readRawInt(): Int { + return buffer[readOffset++].toInt() and 255 shl 24 or (buffer[readOffset++].toInt() and 255 shl 16) or (buffer[readOffset++].toInt() and 255 shl 8) or (buffer[readOffset++].toInt() and 255) + } + + // *******************************************long************************************************** + fun writeLong(value: Long) { + val mask = value shl 1 xor (value shr 63) + if (mask ushr 32 == 0L) { + writeVarInt(mask.toInt()) + return + } + val bytes = ByteArray(9) + bytes[0] = (mask or 0x80L).toByte() + bytes[1] = (mask ushr 7 or 0x80L).toByte() + bytes[2] = (mask ushr 14 or 0x80L).toByte() + bytes[3] = (mask ushr 21 or 0x80L).toByte() + var a = (mask ushr 28).toInt() + var b = (mask ushr 35).toInt() + if (b == 0) { + bytes[4] = a.toByte() + writeBytes(bytes, 5) + return + } + bytes[4] = (a or 0x80).toByte() + a = (mask ushr 42).toInt() + if (a == 0) { + bytes[5] = b.toByte() + writeBytes(bytes, 6) + return + } + bytes[5] = (b or 0x80).toByte() + b = (mask ushr 49).toInt() + if (b == 0) { + bytes[6] = a.toByte() + writeBytes(bytes, 7) + return + } + bytes[6] = (a or 0x80).toByte() + a = (mask ushr 56).toInt() + if (a == 0) { + bytes[7] = b.toByte() + writeBytes(bytes, 8) + return + } + bytes[7] = (b or 0x80).toByte() + bytes[8] = a.toByte() + writeBytes(bytes, 9) + } + + fun readLong(): Long { + var b = readByte().toLong() + var value = b + if (b < 0) { + b = readByte().toLong() + value = value and 0x000000000000007FL or (b shl 7) + if (b < 0) { + b = readByte().toLong() + value = value and 0x0000000000003FFFL or (b shl 14) + if (b < 0) { + b = readByte().toLong() + value = value and 0x00000000001FFFFFL or (b shl 21) + if (b < 0) { + b = readByte().toLong() + value = value and 0x000000000FFFFFFFL or (b shl 28) + if (b < 0) { + b = readByte().toLong() + value = value and 0x00000007FFFFFFFFL or (b shl 35) + if (b < 0) { + b = readByte().toLong() + value = value and 0x000003FFFFFFFFFFL or (b shl 42) + if (b < 0) { + b = readByte().toLong() + value = value and 0x0001FFFFFFFFFFFFL or (b shl 49) + if (b < 0) { + b = readByte().toLong() + value = value and 0x00FFFFFFFFFFFFFFL or (b shl 56) + } + } + } + } + } + } + } + } + return value ushr 1 xor -(value and 1L) + } + + fun writeRawLong(value: Long) { + ensureCapacity(8) + buffer[writeOffset++] = (value ushr 56).toInt().toByte() + buffer[writeOffset++] = (value ushr 48).toInt().toByte() + buffer[writeOffset++] = (value ushr 40).toInt().toByte() + buffer[writeOffset++] = (value ushr 32).toInt().toByte() + buffer[writeOffset++] = (value ushr 24).toInt().toByte() + buffer[writeOffset++] = (value ushr 16).toInt().toByte() + buffer[writeOffset++] = (value ushr 8).toInt().toByte() + buffer[writeOffset++] = value.toInt().toByte() + } + + fun readRawLong(): Long { + return buffer[readOffset++].toLong() and 255L shl 56 or (buffer[readOffset++].toLong() and 255L shl 48) or (buffer[readOffset++].toLong() and 255L shl 40) or (buffer[readOffset++].toLong() and 255L shl 32) or (buffer[readOffset++].toLong() and 255L shl 24) or (buffer[readOffset++].toLong() and 255L shl 16) or (buffer[readOffset++].toLong() and 255L shl 8) or (buffer[readOffset++].toLong() and 255L) + } + + // *******************************************float*************************************************** + fun writeFloat(value: Float) { + writeRawInt(java.lang.Float.floatToRawIntBits(value)) + } + + fun readFloat(): Float { + return java.lang.Float.intBitsToFloat(readRawInt()) + } + + // *******************************************double*************************************************** + fun writeDouble(value: Double) { + writeRawLong(java.lang.Double.doubleToRawLongBits(value)) + } + + fun readDouble(): Double { + return java.lang.Double.longBitsToDouble(readRawLong()) + } + + fun writeString(value: String?) { + if (value == null || value.isEmpty()) { + writeInt(0) + return + } + val bytes = value.toByteArray(DEFAULT_CHARSET) + writeInt(bytes.size) + writeBytes(bytes) + } + + fun readString(): String { + val length = readInt() + if (length <= 0) { + return "" + } + val bytes = readBytes(length) + return String(bytes, DEFAULT_CHARSET) + } + + fun writeBooleanArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeBool(array[index]) + } + } + } + + fun readBooleanArray(): Array { + val size = readInt() + val array = Array(size) { init -> false } + if (size > 0) { + for (index in 0 until size) { + array[index] = readBool() + } + } + return array + } + + fun writeByteArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeByte(array[index]) + } + } + } + + fun readByteArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0 } + if (size > 0) { + for (index in 0 until size) { + array[index] = readByte() + } + } + return array + } + + fun writeShortArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeShort(array[index]) + } + } + } + + fun readShortArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0 } + if (size > 0) { + for (index in 0 until size) { + array[index] = readShort() + } + } + return array + } + + fun writeIntArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeInt(array[index]) + } + } + } + + fun readIntArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0 } + if (size > 0) { + for (index in 0 until size) { + array[index] = readInt() + } + } + return array + } + + fun writeLongArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeLong(array[index]) + } + } + } + + fun readLongArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0 } + if (size > 0) { + for (index in 0 until size) { + array[index] = readLong() + } + } + return array + } + + fun writeFloatArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeFloat(array[index]) + } + } + } + + fun readFloatArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0F } + if (size > 0) { + for (index in 0 until size) { + array[index] = readFloat() + } + } + return array + } + + fun writeDoubleArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeDouble(array[index]) + } + } + } + + fun readDoubleArray(): Array { + val size = readInt() + val array = Array(size) { init -> 0.0 } + if (size > 0) { + for (index in 0 until size) { + array[index] = readDouble() + } + } + return array + } + + fun writeStringArray(array: Array) { + if (array.size == 0) { + writeInt(0) + } else { + writeInt(array.size) + val length = array.size + for (index in 0 until length) { + writeString(array[index]) + } + } + } + + fun readStringArray(): Array { + val size = readInt() + val array = Array(size) { init -> "" } + if (size > 0) { + for (index in 0 until size) { + array[index] = readString() + } + } + return array + } + + fun writeBooleanList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeBool(ele) + } + } + } + + fun readBooleanList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readBool()) + } + } + return list + } + + fun writeByteList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeByte(ele) + } + } + } + + fun readByteList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readByte()) + } + } + return list + } + + fun writeShortList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeShort(ele) + } + } + } + + fun readShortList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readShort()) + } + } + return list + } + + fun writeIntList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeInt(ele) + } + } + } + + fun readIntList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readInt()) + } + } + return list + } + + fun writeLongList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeLong(ele) + } + } + } + + fun readLongList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readLong()) + } + } + return list + } + + fun writeFloatList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeFloat(ele) + } + } + } + + fun readFloatList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readFloat()) + } + } + return list + } + + fun writeDoubleList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeDouble(ele) + } + } + } + + fun readDoubleList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readDouble()) + } + } + return list + } + + fun writeStringList(list: List) { + if (list.isEmpty()) { + writeInt(0) + } else { + writeInt(list.size) + for (ele in list) { + writeString(ele) + } + } + } + + fun readStringList(): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + for (index in 0 until size) { + list.add(readString()) + } + } + return list + } + + fun writePacketList(list: List<*>, protocolId: Short) { + if (list.isEmpty()) { + writeInt(0) + } else { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(list.size) + for (ele in list) { + protocolRegistration.write(this, ele) + } + } + } + + fun readPacketList(clazz: Class, protocolId: Short): List { + val size = readInt() + val list: MutableList = ArrayList() + if (size > 0) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index in 0 until size) { + list.add(protocolRegistration.read(this) as T) + } + } + return list + } + + fun writeBooleanSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeBool(ele) + } + } + } + + fun readBooleanSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readBool()) + } + } + return set + } + + fun writeShortSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeShort(ele) + } + } + } + + fun readShortSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readShort()) + } + } + return set + } + + fun writeIntSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeInt(ele) + } + } + } + + fun readIntSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readInt()) + } + } + return set + } + + fun writeLongSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeLong(ele) + } + } + } + + fun readLongSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readLong()) + } + } + return set + } + + fun writeFloatSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeFloat(ele) + } + } + } + + fun readFloatSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readFloat()) + } + } + return set + } + + fun writeDoubleSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeDouble(ele) + } + } + } + + fun readDoubleSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readDouble()) + } + } + return set + } + + fun writeStringSet(set: Set) { + if (set.isEmpty()) { + writeInt(0) + } else { + writeInt(set.size) + for (ele in set) { + writeString(ele) + } + } + } + + fun readStringSet(): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + for (index in 0 until size) { + set.add(readString()) + } + } + return set + } + + fun writePacketSet(set: Set<*>, protocolId: Short) { + if (set.isEmpty()) { + writeInt(0) + } else { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(set.size) + for (element in set) { + protocolRegistration.write(this, element) + } + } + } + + fun readPacketSet(clazz: Class, protocolId: Short): Set { + val size = readInt() + val set: MutableSet = HashSet() + if (size > 0) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index in 0 until size) { + set.add(protocolRegistration.read(this) as T) + } + } + return set + } + + fun writeIntIntMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeInt(key) + writeInt(value) + } + } + } + + fun readIntIntMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readInt() + val value = readInt() + map[key] = value + } + } + return map + } + + fun writeIntLongMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeInt(key) + writeLong(value) + } + } + } + + fun readIntLongMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readInt() + val value = readLong() + map[key] = value + } + } + return map + } + + fun writeIntStringMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeInt(key) + writeString(value) + } + } + } + + fun readIntStringMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readInt() + val value = readString() + map[key] = value + } + } + return map + } + + fun writeIntPacketMap(map: Map, protocolId: Short) { + if (map.isEmpty()) { + writeInt(0) + } else { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) in map) { + writeInt(key) + protocolRegistration.write(this, value) + } + } + } + + fun readIntPacketMap(clazz: Class, protocolId: Short): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index in 0 until size) { + val key = readInt() + val value = protocolRegistration.read(this) as T + map[key] = value + } + } + return map + } + + fun writeLongIntMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeLong(key) + writeInt(value) + } + } + } + + fun readLongIntMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readLong() + val value = readInt() + map[key] = value + } + } + return map + } + + fun writeLongLongMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeLong(key) + writeLong(value) + } + } + } + + fun readLongLongMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readLong() + val value = readLong() + map[key] = value + } + } + return map + } + + fun writeLongStringMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeLong(key) + writeString(value) + } + } + } + + fun readLongStringMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readLong() + val value = readString() + map[key] = value + } + } + return map + } + + fun writeLongPacketMap(map: Map, protocolId: Short) { + if (map.isEmpty()) { + writeInt(0) + } else { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) in map) { + writeLong(key) + protocolRegistration.write(this, value) + } + } + } + + fun readLongPacketMap(clazz: Class, protocolId: Short): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index in 0 until size) { + val key = readLong() + val value = protocolRegistration.read(this) as T + map[key] = value + } + } + return map + } + + fun writeStringIntMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeString(key) + writeInt(value) + } + } + } + + fun readStringIntMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readString() + val value = readInt() + map[key] = value + } + } + return map + } + + fun writeStringLongMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeString(key) + writeLong(value) + } + } + } + + fun readStringLongMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readString() + val value = readLong() + map[key] = value + } + } + return map + } + + fun writeStringStringMap(map: Map) { + if (map.isEmpty()) { + writeInt(0) + } else { + writeInt(map.size) + for ((key, value) in map) { + writeString(key) + writeString(value) + } + } + } + + fun readStringStringMap(): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + for (index in 0 until size) { + val key = readString() + val value = readString() + map[key] = value + } + } + return map + } + + fun writeStringPacketMap(map: Map, protocolId: Short) { + if (map.isEmpty()) { + writeInt(0) + } else { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) in map) { + writeString(key) + protocolRegistration.write(this, value) + } + } + } + + fun readStringPacketMap(clazz: Class, protocolId: Short): Map { + val size = readInt() + val map: MutableMap = HashMap() + if (size > 0) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index in 0 until size) { + val key = readString() + val value = protocolRegistration.read(this) as T + map[key] = value + } + } + return map + } + + fun writePacket(packet: Any?, protocolId: Short) { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + protocolRegistration.write(this, packet) + } + + fun readPacket(protocolId: Short): Any { + val protocolRegistration = ProtocolManager.getProtocol(protocolId) + return protocolRegistration.read(this) + } + + companion object { + private const val INIT_SIZE = 128 + private const val MAX_SIZE = 655537 + + // *******************************************String*************************************************** + const val DEFAULT_CHARSET_NAME = "UTF-8" + val DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME) + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/IProtocolRegistration.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/IProtocolRegistration.kt new file mode 100644 index 00000000..97f810af --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/IProtocolRegistration.kt @@ -0,0 +1,7 @@ +package com.zfoo.kotlin + +interface IProtocolRegistration { + fun protocolId(): Short + fun write(buffer: ByteBuffer, packet: Any?) + fun read(buffer: ByteBuffer): Any +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/ProtocolManager.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/ProtocolManager.kt new file mode 100644 index 00000000..85d3633d --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/ProtocolManager.kt @@ -0,0 +1,55 @@ +package com.zfoo.kotlin +import com.zfoo.kotlin.packet.EmptyObject +import com.zfoo.kotlin.packet.ComplexObject +import com.zfoo.kotlin.packet.NormalObject +import com.zfoo.kotlin.packet.ObjectA +import com.zfoo.kotlin.packet.ObjectB +import com.zfoo.kotlin.packet.SimpleObject +class ProtocolManager { + companion object { + val protocols = arrayOfNulls(Short.MAX_VALUE.toInt()) + var protocolIdMap: MutableMap, Short> = HashMap() + @JvmStatic + fun initProtocol() { + // initProtocol + protocols[0] = EmptyObject.registrationEmptyObject + protocolIdMap[EmptyObject::class.java] = 0.toShort() + protocols[100] = ComplexObject.registrationComplexObject + protocolIdMap[ComplexObject::class.java] = 100.toShort() + protocols[101] = NormalObject.registrationNormalObject + protocolIdMap[NormalObject::class.java] = 101.toShort() + protocols[102] = ObjectA.registrationObjectA + protocolIdMap[ObjectA::class.java] = 102.toShort() + protocols[103] = ObjectB.registrationObjectB + protocolIdMap[ObjectB::class.java] = 103.toShort() + protocols[104] = SimpleObject.registrationSimpleObject + protocolIdMap[SimpleObject::class.java] = 104.toShort() + } + + @JvmStatic + fun getProtocolId(clazz: Class<*>): Short { + return protocolIdMap[clazz]!! + } + + @JvmStatic + fun getProtocol(protocolId: Short): IProtocolRegistration { + return protocols[protocolId.toInt()] + ?: throw RuntimeException("[protocolId:$protocolId] not exist") + } + + @JvmStatic + fun write(buffer: ByteBuffer, packet: Any) { + val protocolId = getProtocolId(packet.javaClass) + // write protocol id to buffer + buffer.writeShort(protocolId) + // write packet + getProtocol(protocolId).write(buffer, packet) + } + + @JvmStatic + fun read(buffer: ByteBuffer): Any { + val protocolId = buffer.readShort() + return getProtocol(protocolId).read(buffer) + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ComplexObject.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ComplexObject.kt new file mode 100644 index 00000000..9dba335b --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ComplexObject.kt @@ -0,0 +1,423 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.packet.ObjectA +import com.zfoo.kotlin.packet.ObjectB +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer +// 复杂的对象,包括了各种复杂的结构,数组,List,Set,Map +class ComplexObject { + // byte类型,最简单的整形 + var a: Byte = 0 + // byte的包装类型,优先使用基础类型,包装类型会有装箱拆箱 + var aa: Byte = 0 + // 数组类型 + var aaa: Array = emptyArray() + var aaaa: Array = emptyArray() + var b: Short = 0 + var bb: Short = 0 + var bbb: Array = emptyArray() + var bbbb: Array = emptyArray() + var c: Int = 0 + var cc: Int = 0 + var ccc: Array = emptyArray() + var cccc: Array = emptyArray() + var d: Long = 0 + var dd: Long = 0 + var ddd: Array = emptyArray() + var dddd: Array = emptyArray() + var e: Float = 0f + var ee: Float = 0f + var eee: Array = emptyArray() + var eeee: Array = emptyArray() + var f: Double = 0.0 + var ff: Double = 0.0 + var fff: Array = emptyArray() + var ffff: Array = emptyArray() + var g: Boolean = false + var gg: Boolean = false + var ggg: Array = emptyArray() + var gggg: Array = emptyArray() + var jj: String = "" + var jjj: Array = emptyArray() + var kk: ObjectA? = null + var kkk: Array = emptyArray() + var l: List = emptyList() + var ll: List>> = emptyList() + var lll: List> = emptyList() + var llll: List = emptyList() + var lllll: List> = emptyList() + var m: Map = emptyMap() + var mm: Map = emptyMap() + var mmm: Map> = emptyMap() + var mmmm: Map>, List>>> = emptyMap() + var mmmmm: Map>, Set>> = emptyMap() + var s: Set = emptySet() + var ss: Set>> = emptySet() + var sss: Set> = emptySet() + var ssss: Set = emptySet() + var sssss: Set> = emptySet() + // 如果要修改协议并且兼容老协议,需要加上Compatible注解,保持Compatible注解的value自增 + var myCompatible: Int = 0 + var myObject: ObjectA? = null + + companion object { + @JvmField + val registrationComplexObject: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 100 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as ComplexObject + val beforeWriteIndex = buffer.writeOffset() + buffer.writeInt(36962) + buffer.writeByte(message.a) + buffer.writeByte(message.aa) + buffer.writeByteArray(message.aaa) + buffer.writeByteArray(message.aaaa) + buffer.writeShort(message.b) + buffer.writeShort(message.bb) + buffer.writeShortArray(message.bbb) + buffer.writeShortArray(message.bbbb) + buffer.writeInt(message.c) + buffer.writeInt(message.cc) + buffer.writeIntArray(message.ccc) + buffer.writeIntArray(message.cccc) + buffer.writeLong(message.d) + buffer.writeLong(message.dd) + buffer.writeLongArray(message.ddd) + buffer.writeLongArray(message.dddd) + buffer.writeFloat(message.e) + buffer.writeFloat(message.ee) + buffer.writeFloatArray(message.eee) + buffer.writeFloatArray(message.eeee) + buffer.writeDouble(message.f) + buffer.writeDouble(message.ff) + buffer.writeDoubleArray(message.fff) + buffer.writeDoubleArray(message.ffff) + buffer.writeBool(message.g) + buffer.writeBool(message.gg) + buffer.writeBooleanArray(message.ggg) + buffer.writeBooleanArray(message.gggg) + buffer.writeString(message.jj) + buffer.writeStringArray(message.jjj) + buffer.writePacket(message.kk, 102) + buffer.writeInt(message.kkk.size) + val length0 = message.kkk.size + for (i1 in 0 until length0) { + val element2 = message.kkk[i1] + buffer.writePacket(element2, 102) + } + buffer.writeIntList(message.l) + buffer.writeInt(message.ll.size) + for (element3 in message.ll) { + buffer.writeInt(element3.size) + for (element4 in element3) { + buffer.writeIntList(element4) + } + } + buffer.writeInt(message.lll.size) + for (element5 in message.lll) { + buffer.writePacketList(element5, 102) + } + buffer.writeStringList(message.llll) + buffer.writeInt(message.lllll.size) + for (element6 in message.lllll) { + buffer.writeIntStringMap(element6) + } + buffer.writeIntStringMap(message.m) + buffer.writeIntPacketMap(message.mm, 102) + buffer.writeInt(message.mmm.size) + for ((keyElement7, valueElement8) in message.mmm) { + buffer.writePacket(keyElement7, 102) + buffer.writeIntList(valueElement8) + } + buffer.writeInt(message.mmmm.size) + for ((keyElement9, valueElement10) in message.mmmm) { + buffer.writeInt(keyElement9.size) + for (element11 in keyElement9) { + buffer.writePacketList(element11, 102) + } + buffer.writeInt(valueElement10.size) + for (element12 in valueElement10) { + buffer.writeInt(element12.size) + for (element13 in element12) { + buffer.writeIntList(element13) + } + } + } + buffer.writeInt(message.mmmmm.size) + for ((keyElement14, valueElement15) in message.mmmmm) { + buffer.writeInt(keyElement14.size) + for (element16 in keyElement14) { + buffer.writeIntStringMap(element16) + } + buffer.writeInt(valueElement15.size) + for (i17 in valueElement15) { + buffer.writeIntStringMap(i17) + } + } + buffer.writeIntSet(message.s) + buffer.writeInt(message.ss.size) + for (i18 in message.ss) { + buffer.writeInt(i18.size) + for (i19 in i18) { + buffer.writeIntList(i19) + } + } + buffer.writeInt(message.sss.size) + for (i20 in message.sss) { + buffer.writePacketSet(i20, 102) + } + buffer.writeStringSet(message.ssss) + buffer.writeInt(message.sssss.size) + for (i21 in message.sssss) { + buffer.writeIntStringMap(i21) + } + buffer.writeInt(message.myCompatible) + buffer.writePacket(message.myObject, 102) + buffer.adjustPadding(36962, beforeWriteIndex) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = ComplexObject() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + val result0 = buffer.readByte() + packet.a = result0 + val result1 = buffer.readByte() + packet.aa = result1 + val array2 = buffer.readByteArray() + packet.aaa = array2 + val array3 = buffer.readByteArray() + packet.aaaa = array3 + val result4 = buffer.readShort() + packet.b = result4 + val result5 = buffer.readShort() + packet.bb = result5 + val array6 = buffer.readShortArray() + packet.bbb = array6 + val array7 = buffer.readShortArray() + packet.bbbb = array7 + val result8 = buffer.readInt() + packet.c = result8 + val result9 = buffer.readInt() + packet.cc = result9 + val array10 = buffer.readIntArray() + packet.ccc = array10 + val array11 = buffer.readIntArray() + packet.cccc = array11 + val result12 = buffer.readLong() + packet.d = result12 + val result13 = buffer.readLong() + packet.dd = result13 + val array14 = buffer.readLongArray() + packet.ddd = array14 + val array15 = buffer.readLongArray() + packet.dddd = array15 + val result16 = buffer.readFloat() + packet.e = result16 + val result17 = buffer.readFloat() + packet.ee = result17 + val array18 = buffer.readFloatArray() + packet.eee = array18 + val array19 = buffer.readFloatArray() + packet.eeee = array19 + val result20 = buffer.readDouble() + packet.f = result20 + val result21 = buffer.readDouble() + packet.ff = result21 + val array22 = buffer.readDoubleArray() + packet.fff = array22 + val array23 = buffer.readDoubleArray() + packet.ffff = array23 + val result24 = buffer.readBool() + packet.g = result24 + val result25 = buffer.readBool() + packet.gg = result25 + val array26 = buffer.readBooleanArray() + packet.ggg = array26 + val array27 = buffer.readBooleanArray() + packet.gggg = array27 + val result28 = buffer.readString() + packet.jj = result28 + val array29 = buffer.readStringArray() + packet.jjj = array29 + val result30 = buffer.readPacket(102) as ObjectA + packet.kk = result30 + val size34 = buffer.readInt() + val result31 = Array(size34) { init -> ObjectA()} + if (size34 > 0) { + for (index32 in 0 until size34) { + val result35 = buffer.readPacket(102) as ObjectA + result31[index32] = result35 + } + } + packet.kkk = result31 + val list36 = buffer.readIntList() + packet.l = list36 + val size39 = buffer.readInt() + val result37 = ArrayList>>(size39) + if (size39 > 0) { + for (index38 in 0 until size39) { + val size42 = buffer.readInt() + val result40 = ArrayList>(size42) + if (size42 > 0) { + for (index41 in 0 until size42) { + val list43 = buffer.readIntList() + result40.add(list43) + } + } + result37.add(result40) + } + } + packet.ll = result37 + val size46 = buffer.readInt() + val result44 = ArrayList>(size46) + if (size46 > 0) { + for (index45 in 0 until size46) { + val list47 = buffer.readPacketList(ObjectA::class.java, 102) + result44.add(list47) + } + } + packet.lll = result44 + val list48 = buffer.readStringList() + packet.llll = list48 + val size51 = buffer.readInt() + val result49 = ArrayList>(size51) + if (size51 > 0) { + for (index50 in 0 until size51) { + val map52 = buffer.readIntStringMap() + result49.add(map52) + } + } + packet.lllll = result49 + val map53 = buffer.readIntStringMap() + packet.m = map53 + val map54 = buffer.readIntPacketMap(ObjectA::class.java, 102) + packet.mm = map54 + val size56 = buffer.readInt() + val result55 = HashMap>(size56) + if (size56 > 0) { + for (index57 in 0 until size56) { + val result58 = buffer.readPacket(102) as ObjectA + val list59 = buffer.readIntList() + result55.put(result58, list59) + } + } + packet.mmm = result55 + val size61 = buffer.readInt() + val result60 = HashMap>, List>>>(size61) + if (size61 > 0) { + for (index62 in 0 until size61) { + val size65 = buffer.readInt() + val result63 = ArrayList>(size65) + if (size65 > 0) { + for (index64 in 0 until size65) { + val list66 = buffer.readPacketList(ObjectA::class.java, 102) + result63.add(list66) + } + } + val size69 = buffer.readInt() + val result67 = ArrayList>>(size69) + if (size69 > 0) { + for (index68 in 0 until size69) { + val size72 = buffer.readInt() + val result70 = ArrayList>(size72) + if (size72 > 0) { + for (index71 in 0 until size72) { + val list73 = buffer.readIntList() + result70.add(list73) + } + } + result67.add(result70) + } + } + result60.put(result63, result67) + } + } + packet.mmmm = result60 + val size75 = buffer.readInt() + val result74 = HashMap>, Set>>(size75) + if (size75 > 0) { + for (index76 in 0 until size75) { + val size79 = buffer.readInt() + val result77 = ArrayList>(size79) + if (size79 > 0) { + for (index78 in 0 until size79) { + val map80 = buffer.readIntStringMap() + result77.add(map80) + } + } + val size83 = buffer.readInt() + val result81 = HashSet>() + if (size83 > 0) { + for (index82 in 0 until size83) { + val map84 = buffer.readIntStringMap() + result81.add(map84) + } + } + result74.put(result77, result81) + } + } + packet.mmmmm = result74 + val set85 = buffer.readIntSet() + packet.s = set85 + val size88 = buffer.readInt() + val result86 = HashSet>>() + if (size88 > 0) { + for (index87 in 0 until size88) { + val size91 = buffer.readInt() + val result89 = HashSet>() + if (size91 > 0) { + for (index90 in 0 until size91) { + val list92 = buffer.readIntList() + result89.add(list92) + } + } + result86.add(result89) + } + } + packet.ss = result86 + val size95 = buffer.readInt() + val result93 = HashSet>() + if (size95 > 0) { + for (index94 in 0 until size95) { + val set96 = buffer.readPacketSet(ObjectA::class.java, 102) + result93.add(set96) + } + } + packet.sss = result93 + val set97 = buffer.readStringSet() + packet.ssss = set97 + val size100 = buffer.readInt() + val result98 = HashSet>() + if (size100 > 0) { + for (index99 in 0 until size100) { + val map101 = buffer.readIntStringMap() + result98.add(map101) + } + } + packet.sssss = result98 + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result102 = buffer.readInt() + packet.myCompatible = result102 + } + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result103 = buffer.readPacket(102) as ObjectA + packet.myObject = result103 + } + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/EmptyObject.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/EmptyObject.kt new file mode 100644 index 00000000..7c74d1da --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/EmptyObject.kt @@ -0,0 +1,39 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer + +class EmptyObject { + + + companion object { + @JvmField + val registrationEmptyObject: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 0 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as EmptyObject + buffer.writeInt(-1) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = EmptyObject() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/NormalObject.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/NormalObject.kt new file mode 100644 index 00000000..767c2b74 --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/NormalObject.kt @@ -0,0 +1,126 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.packet.ObjectA +import com.zfoo.kotlin.packet.ObjectB +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer +// 常规的对象,取所有语言语法的交集,基本上所有语言都支持下面的语法 +class NormalObject { + var a: Byte = 0 + var aaa: Array = emptyArray() + var b: Short = 0 + // 整数类型 + var c: Int = 0 + var d: Long = 0 + var e: Float = 0f + var f: Double = 0.0 + var g: Boolean = false + var jj: String = "" + var kk: ObjectA? = null + var l: List = emptyList() + var ll: List = emptyList() + var lll: List = emptyList() + var llll: List = emptyList() + var m: Map = emptyMap() + var mm: Map = emptyMap() + var s: Set = emptySet() + var ssss: Set = emptySet() + var outCompatibleValue: Int = 0 + var outCompatibleValue2: Int = 0 + + companion object { + @JvmField + val registrationNormalObject: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 101 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as NormalObject + val beforeWriteIndex = buffer.writeOffset() + buffer.writeInt(857) + buffer.writeByte(message.a) + buffer.writeByteArray(message.aaa) + buffer.writeShort(message.b) + buffer.writeInt(message.c) + buffer.writeLong(message.d) + buffer.writeFloat(message.e) + buffer.writeDouble(message.f) + buffer.writeBool(message.g) + buffer.writeString(message.jj) + buffer.writePacket(message.kk, 102) + buffer.writeIntList(message.l) + buffer.writeLongList(message.ll) + buffer.writePacketList(message.lll, 102) + buffer.writeStringList(message.llll) + buffer.writeIntStringMap(message.m) + buffer.writeIntPacketMap(message.mm, 102) + buffer.writeIntSet(message.s) + buffer.writeStringSet(message.ssss) + buffer.writeInt(message.outCompatibleValue) + buffer.writeInt(message.outCompatibleValue2) + buffer.adjustPadding(857, beforeWriteIndex) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = NormalObject() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + val result0 = buffer.readByte() + packet.a = result0 + val array1 = buffer.readByteArray() + packet.aaa = array1 + val result2 = buffer.readShort() + packet.b = result2 + val result3 = buffer.readInt() + packet.c = result3 + val result4 = buffer.readLong() + packet.d = result4 + val result5 = buffer.readFloat() + packet.e = result5 + val result6 = buffer.readDouble() + packet.f = result6 + val result7 = buffer.readBool() + packet.g = result7 + val result8 = buffer.readString() + packet.jj = result8 + val result9 = buffer.readPacket(102) as ObjectA + packet.kk = result9 + val list10 = buffer.readIntList() + packet.l = list10 + val list11 = buffer.readLongList() + packet.ll = list11 + val list12 = buffer.readPacketList(ObjectA::class.java, 102) + packet.lll = list12 + val list13 = buffer.readStringList() + packet.llll = list13 + val map14 = buffer.readIntStringMap() + packet.m = map14 + val map15 = buffer.readIntPacketMap(ObjectA::class.java, 102) + packet.mm = map15 + val set16 = buffer.readIntSet() + packet.s = set16 + val set17 = buffer.readStringSet() + packet.ssss = set17 + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result18 = buffer.readInt() + packet.outCompatibleValue = result18 + } + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result19 = buffer.readInt() + packet.outCompatibleValue2 = result19 + } + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectA.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectA.kt new file mode 100644 index 00000000..ddf63123 --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectA.kt @@ -0,0 +1,58 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.packet.ObjectB +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer + +class ObjectA { + var a: Int = 0 + var m: Map = emptyMap() + var objectB: ObjectB? = null + var innerCompatibleValue: Int = 0 + + companion object { + @JvmField + val registrationObjectA: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 102 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as ObjectA + val beforeWriteIndex = buffer.writeOffset() + buffer.writeInt(201) + buffer.writeInt(message.a) + buffer.writeIntStringMap(message.m) + buffer.writePacket(message.objectB, 103) + buffer.writeInt(message.innerCompatibleValue) + buffer.adjustPadding(201, beforeWriteIndex) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = ObjectA() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + val result0 = buffer.readInt() + packet.a = result0 + val map1 = buffer.readIntStringMap() + packet.m = map1 + val result2 = buffer.readPacket(103) as ObjectB + packet.objectB = result2 + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result3 = buffer.readInt() + packet.innerCompatibleValue = result3 + } + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectB.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectB.kt new file mode 100644 index 00000000..bc423fcf --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/ObjectB.kt @@ -0,0 +1,49 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer + +class ObjectB { + var flag: Boolean = false + var innerCompatibleValue: Int = 0 + + companion object { + @JvmField + val registrationObjectB: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 103 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as ObjectB + val beforeWriteIndex = buffer.writeOffset() + buffer.writeInt(4) + buffer.writeBool(message.flag) + buffer.writeInt(message.innerCompatibleValue) + buffer.adjustPadding(4, beforeWriteIndex) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = ObjectB() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + val result0 = buffer.readBool() + packet.flag = result0 + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result1 = buffer.readInt() + packet.innerCompatibleValue = result1 + } + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file diff --git a/protocol/src/test/kotlin/com/zfoo/kotlin/packet/SimpleObject.kt b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/SimpleObject.kt new file mode 100644 index 00000000..35cb3026 --- /dev/null +++ b/protocol/src/test/kotlin/com/zfoo/kotlin/packet/SimpleObject.kt @@ -0,0 +1,45 @@ +package com.zfoo.kotlin.packet +import com.zfoo.kotlin.IProtocolRegistration +import com.zfoo.kotlin.ByteBuffer + +class SimpleObject { + var c: Int = 0 + var g: Boolean = false + + companion object { + @JvmField + val registrationSimpleObject: IProtocolRegistration = object : IProtocolRegistration { + override fun protocolId(): Short { + return 104 + } + + override fun write(buffer: ByteBuffer, packet: Any?) { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet as SimpleObject + buffer.writeInt(-1) + buffer.writeInt(message.c) + buffer.writeBool(message.g) + } + + override fun read(buffer: ByteBuffer): Any { + val length = buffer.readInt() + val packet = SimpleObject() + if (length == 0) { + return packet + } + val beforeReadIndex = buffer.readOffset() + val result0 = buffer.readInt() + packet.c = result0 + val result1 = buffer.readBool() + packet.g = result1 + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } + } + } +} \ No newline at end of file