diff --git a/protocol/src/test/scala/Main.scala b/protocol/src/test/scala/Main.scala new file mode 100644 index 00000000..ad1e6ec5 --- /dev/null +++ b/protocol/src/test/scala/Main.scala @@ -0,0 +1,181 @@ + +import com.zfoo.scala.{ByteBuffer, ProtocolManager} + +import java.io.IOException +import java.nio.file.{Files, Paths} + +object Main { + + def main(args: Array[String]): Unit = { + System.out.println("zfoo test") + ProtocolManager.initProtocol + byteBufferTest() + compatibleTest() + normalReadTest() + } + + + def byteBufferTest(): Unit = { + byteTest() + bytesTest() + shortTest() + intTest() + longTest() + floatTest() + doubleTest() + stringTest() + } + + def byteTest(): Unit = { + val value: Byte = 9 + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeByte(value) + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(writerByteBuffer.toBytes) + val readValue = readerByteBuffer.readByte + assertEquals(value, readValue) + } + + def bytesTest(): Unit = { + val value = Array[Byte](1, 2, 3) + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeBytes(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readBytes(3) + assertEquals(value, readValue) + } + + def shortTest(): Unit = { + val value: Short = 9999 + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeShort(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readShort + assertEquals(value, readValue) + } + + def intTest(): Unit = { + val value = 99999999 + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeInt(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readInt + assertEquals(value, readValue) + } + + def longTest(): Unit = { + val value = 9999999999999999L + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeLong(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readLong + assertEquals(value, readValue) + } + + def floatTest(): Unit = { + val value = 999999.56F + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeFloat(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readFloat + assertEquals(value, readValue) + } + + def doubleTest(): Unit = { + val value = 999999.56 + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeDouble(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readDouble + assertEquals(value, readValue) + } + + def stringTest(): Unit = { + val value = "aaa" + val writerByteBuffer = new ByteBuffer + writerByteBuffer.writeString(value) + val bytes = writerByteBuffer.toBytes + val readerByteBuffer = new ByteBuffer + readerByteBuffer.writeBytes(bytes) + val readValue = readerByteBuffer.readString + assertEquals(value, readValue) + } + + def assertEquals(a: Any, b: Any): Unit = { + if (a.equals(b)) return + throw new RuntimeException("a is not equals b") + } + + def assertEquals(a: Array[Byte], b: Array[Byte]): Unit = { + if (a eq b) return + if (a != null && b != null && a.length == b.length) { + for (i <- 0 until a.length) { + assertEquals(a(i), b(i)) + } + return + } + throw new RuntimeException("a is not equals b") + } + + // ----------------------------------------------------------------------------------------------------------------- + // ----------------------------------------------------------------------------------------------------------------- + @throws[IOException] + def compatibleTest(): Unit = { + val bytes = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\complexObject.bytes")); + val buffer = new ByteBuffer + buffer.writeBytes(bytes) + val packet = ProtocolManager.read(buffer) + val newBuffer = new ByteBuffer + ProtocolManager.write(newBuffer, packet) + buffer.setReadOffset(0) + newBuffer.setReadOffset(0) + var equal = 0 + var notEqual = 0 + var i = 0 + while (i < buffer.getWriteOffset) { + val a = buffer.readByte + val b = newBuffer.readByte + if (a == b) equal += 1 + else notEqual += 1 + + i += 1 + } + println("equal: " + equal) + println("note equal: " + notEqual) + } + + + @throws[IOException] + def normalReadTest(): Unit = { + // var bytes = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-inner-compatible.bytes")) + // var bytes = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-compatible.bytes")) + // var bytes = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-inner-compatible.bytes")) + // var bytes = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-inner-compatible.bytes")) + val bytes: Array[Byte] = Files.readAllBytes(Paths.get("C:\\github\\zfoo\\protocol\\src\\test\\resources\\compatible\\normal-out-inner-inner-compatible.bytes")) + val buffer: ByteBuffer = new ByteBuffer + buffer.writeBytes(bytes) + val packet = ProtocolManager.read(buffer) + val newBuffer = new ByteBuffer() + ProtocolManager.write(newBuffer, packet) + val newPacket = ProtocolManager.read(newBuffer) + + println(packet) + println(newPacket) + } + + + // ----------------------------------------------------------------------------------------------------------------- + +} diff --git a/protocol/src/test/scala/com/zfoo/scala/ByteBuffer.scala b/protocol/src/test/scala/com/zfoo/scala/ByteBuffer.scala new file mode 100644 index 00000000..e1bde998 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/ByteBuffer.scala @@ -0,0 +1,1207 @@ +package com.zfoo.scala +import java.nio.charset.Charset +import scala.collection.mutable +import scala.collection.mutable.{ArrayBuffer, ListBuffer} + +class ByteBuffer { + val INIT_SIZE: Int = 128 + val MAX_SIZE: Int = 655537 + // *******************************************String*************************************************** + val DEFAULT_CHARSET_NAME: String = "UTF-8" + val DEFAULT_CHARSET: Charset = Charset.forName(DEFAULT_CHARSET_NAME) + + private var buffer: Array[Byte] = new Array[Byte](INIT_SIZE) + private var writeOffset: Int = 0 + private var readOffset: Int = 0 + + def adjustPadding(predictionLength: Int, beforewriteIndex: Int): Unit = { + // 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置 + val currentwriteIndex: Int = writeOffset + val predictionCount: Int = writeIntCount(predictionLength) + val length: Int = currentwriteIndex - beforewriteIndex - predictionCount + val lengthCount: Int = writeIntCount(length) + val padding: Int = lengthCount - predictionCount + if (padding == 0) { + writeOffset = beforewriteIndex + writeInt(length) + writeOffset = currentwriteIndex + } + else { + val bytes: Array[Byte] = new Array[Byte](length) + System.arraycopy(buffer, currentwriteIndex - length, bytes, 0, length) + writeOffset = beforewriteIndex + writeInt(length) + writeBytes(bytes) + } + } + + def compatibleRead(beforeReadIndex: Int, length: Int): Boolean = length != -1 && readOffset < length + beforeReadIndex + + // -------------------------------------------------get/set------------------------------------------------- + def getWriteOffset: Int = writeOffset + + def setWriteOffset(writeIndex: Int): Unit = { + if (writeIndex > buffer.length) throw new RuntimeException("writeIndex[" + writeIndex + "] out of bounds exception: readerIndex: " + readOffset + ", writerIndex: " + writeOffset + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + buffer.length) + writeOffset = writeIndex + } + + def getReadOffset: Int = readOffset + + def setReadOffset(readIndex: Int): Unit = { + if (readIndex > writeOffset) throw new RuntimeException("readIndex[" + readIndex + "] out of bounds exception: readerIndex: " + readOffset + ", writerIndex: " + writeOffset + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + buffer.length) + readOffset = readIndex + } + + def getBytes: Array[Byte] = buffer + + def toBytes: Array[Byte] = buffer.slice(0, writeOffset) + + def isReadable: Boolean = writeOffset > readOffset + + // -------------------------------------------------write/read------------------------------------------------- + def writeBool(value: Boolean): Unit = { + ensureCapacity(1) + buffer(writeOffset) = if (value) 1.toByte else 0.toByte + writeOffset += 1 + } + + def readBool: Boolean = { + val byteValue: Byte = buffer(readOffset) + readOffset += 1 + byteValue == 1 + } + + def writeByte(value: Byte): Unit = { + ensureCapacity(1) + buffer(writeOffset) = value + writeOffset += 1 + } + + def readByte: Byte = buffer({ + readOffset += 1; + readOffset - 1 + }) + + def getCapacity: Int = buffer.length - writeOffset + + def ensureCapacity(capacity: Int): Unit = { + while (capacity - getCapacity > 0) { + val newSize: Int = buffer.length * 2 + if (newSize > MAX_SIZE) throw new RuntimeException("Bytebuf max size is [655537], out of memory error") + val newBytes: Array[Byte] = new Array[Byte](newSize) + System.arraycopy(buffer, 0, newBytes, 0, buffer.length) + this.buffer = newBytes + } + } + + def writeBytes(bytes: Array[Byte]): Unit = { + writeBytes(bytes, bytes.length) + } + + def writeBytes(bytes: Array[Byte], length: Int): Unit = { + ensureCapacity(length) + System.arraycopy(bytes, 0, buffer, writeOffset, length) + writeOffset += length + } + + def readBytes(count: Int): Array[Byte] = { + val bytes: Array[Byte] = new Array[Byte](count) + System.arraycopy(buffer, readOffset, bytes, 0, count) + readOffset += count + bytes + } + + def writeShort(value: Short): Unit = { + ensureCapacity(2) + buffer(writeOffset) = (value >>> 8).toByte + writeOffset = writeOffset + 1 + buffer(writeOffset) = value.toByte + writeOffset = writeOffset + 1 + } + + def readShort: Short = (buffer({ + readOffset += 1; + readOffset - 1 + }) << 8 | buffer({ + readOffset += 1; + readOffset - 1 + }) & 255).toShort + + // *******************************************int*************************************************** + def writeInt(value: Int): Int = writeVarInt((value << 1) ^ (value >> 31)) + + def writeVarInt(value: Int): Int = { + var a: Int = value >>> 7 + if (a == 0) { + writeByte(value.toByte) + return 1 + } + ensureCapacity(5) + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value | 0x80).toByte + var b: Int = value >>> 14 + if (b == 0) { + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = a.toByte + return 2 + } + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (a | 0x80).toByte + a = value >>> 21 + if (a == 0) { + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = b.toByte + return 3 + } + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (b | 0x80).toByte + b = value >>> 28 + if (b == 0) { + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = a.toByte + return 4 + } + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (a | 0x80).toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = b.toByte + 5 + } + + def readInt: Int = { + var b: Int = readByte + var value: Int = b + if (b < 0) { + b = readByte + value = value & 0x0000007F | b << 7 + if (b < 0) { + b = readByte + value = value & 0x00003FFF | b << 14 + if (b < 0) { + b = readByte + value = value & 0x001FFFFF | b << 21 + if (b < 0) value = value & 0x0FFFFFFF | readByte << 28 + } + } + } + (value >>> 1) ^ -(value & 1) + } + + def writeIntCount(value: Int): Int = { + val v = (value << 1) ^ (value >> 31) + if (v >>> 7 == 0) return 1 + if (v >>> 14 == 0) return 2 + if (v >>> 21 == 0) return 3 + if (v >>> 28 == 0) return 4 + 5 + } + + // 写入没有压缩的int + def writeRawInt(value: Int): Unit = { + ensureCapacity(4) + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 24).toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 16).toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 8).toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = value.toByte + } + + // 读取没有压缩的int + def readRawInt: Int = (buffer({ + readOffset += 1; + readOffset - 1 + }) & 255) << 24 | (buffer({ + readOffset += 1; + readOffset - 1 + }) & 255) << 16 | (buffer({ + readOffset += 1; + readOffset - 1 + }) & 255) << 8 | buffer({ + readOffset += 1; + readOffset - 1 + }) & 255 + + // *******************************************long************************************************** + def writeLong(value: Long): Unit = { + val mask: Long = (value << 1) ^ (value >> 63) + if (mask >>> 32 == 0) { + writeVarInt(mask.toInt) + return + } + val bytes: Array[Byte] = new Array[Byte](9) + bytes(0) = (mask | 0x80).toByte + bytes(1) = (mask >>> 7 | 0x80).toByte + bytes(2) = (mask >>> 14 | 0x80).toByte + bytes(3) = (mask >>> 21 | 0x80).toByte + var a: Int = (mask >>> 28).toInt + var b: Int = (mask >>> 35).toInt + if (b == 0) { + bytes(4) = a.toByte + writeBytes(bytes, 5) + return + } + bytes(4) = (a | 0x80).toByte + a = (mask >>> 42).toInt + if (a == 0) { + bytes(5) = b.toByte + writeBytes(bytes, 6) + return + } + bytes(5) = (b | 0x80).toByte + b = (mask >>> 49).toInt + if (b == 0) { + bytes(6) = a.toByte + writeBytes(bytes, 7) + return + } + bytes(6) = (a | 0x80).toByte + a = (mask >>> 56).toInt + if (a == 0) { + bytes(7) = b.toByte + writeBytes(bytes, 8) + return + } + bytes(7) = (b | 0x80).toByte + bytes(8) = a.toByte + writeBytes(bytes, 9) + } + + def readLong: Long = { + var b: Long = readByte + var value: Long = b + if (b < 0) { + b = readByte + value = value & 0x00000000_0000007FL | b << 7 + if (b < 0) { + b = readByte + value = value & 0x00000000_00003FFFL | b << 14 + if (b < 0) { + b = readByte + value = value & 0x00000000_001FFFFFL | b << 21 + if (b < 0) { + b = readByte + value = value & 0x00000000_0FFFFFFFL | b << 28 + if (b < 0) { + b = readByte + value = value & 0x00000007_FFFFFFFFL | b << 35 + if (b < 0) { + b = readByte + value = value & 0x000003FF_FFFFFFFFL | b << 42 + if (b < 0) { + b = readByte + value = value & 0x0001FFFF_FFFFFFFFL | b << 49 + if (b < 0) { + b = readByte + value = value & 0x00FFFFFF_FFFFFFFFL | b << 56 + } + } + } + } + } + } + } + } + (value >>> 1) ^ -(value & 1) + } + + def writeRawLong(value: Long): Unit = { + ensureCapacity(8) + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 56).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 48).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 40).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 32).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 24).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 16).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = (value >>> 8).toInt.toByte + buffer({ + writeOffset += 1; + writeOffset - 1 + }) = value.toInt.toByte + } + + def readRawLong: Long = (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 56 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 48 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 40 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 32 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 24 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 16 | (buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L) << 8 | buffer({ + readOffset += 1; + readOffset - 1 + }).toLong & 255L + + // *******************************************float*************************************************** + def writeFloat(value: Float): Unit = { + writeRawInt(java.lang.Float.floatToRawIntBits(value)) + } + + def readFloat: Float = java.lang.Float.intBitsToFloat(readRawInt) + + // *******************************************double*************************************************** + def writeDouble(value: Double): Unit = { + writeRawLong(java.lang.Double.doubleToRawLongBits(value)) + } + + def readDouble: Double = java.lang.Double.longBitsToDouble(readRawLong) + + def writeString(value: String): Unit = { + if (value == null || value.isEmpty) { + writeInt(0) + return + } + val bytes: Array[Byte] = value.getBytes(DEFAULT_CHARSET) + writeInt(bytes.length) + writeBytes(bytes) + } + + def readString: String = { + val length: Int = readInt + if (length <= 0) return "" + val bytes: Array[Byte] = readBytes(length) + new String(bytes, DEFAULT_CHARSET) + } + + def writeBooleanArray(array: Array[Boolean]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeBool(array(index)) + } + } + } + + def readBooleanArray: Array[Boolean] = { + val size: Int = readInt + val array: Array[Boolean] = new Array[Boolean](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readBool + } + array + } + + def writeByteArray(array: Array[Byte]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeByte(array(index)) + } + } + } + + def readByteArray: Array[Byte] = { + val size: Int = readInt + val array: Array[Byte] = new Array[Byte](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readByte + } + array + } + + def writeShortArray(array: Array[Short]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeShort(array(index)) + } + } + } + + def readShortArray: Array[Short] = { + val size: Int = readInt + val array: Array[Short] = new Array[Short](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readShort + } + array + } + + def writeIntArray(array: Array[Int]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeInt(array(index)) + } + } + } + + def readIntArray: Array[Int] = { + val size: Int = readInt + val array: Array[Int] = new Array[Int](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readInt + } + array + } + + def writeLongArray(array: Array[Long]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeLong(array(index)) + } + } + } + + def readLongArray: Array[Long] = { + val size: Int = readInt + val array: Array[Long] = new Array[Long](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readLong + } + array + } + + def writeFloatArray(array: Array[Float]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeFloat(array(index)) + } + } + } + + def readFloatArray: Array[Float] = { + val size: Int = readInt + val array: Array[Float] = new Array[Float](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readFloat + } + array + } + + def writeDoubleArray(array: Array[Double]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeDouble(array(index)) + } + } + } + + def readDoubleArray: Array[Double] = { + val size: Int = readInt + val array: Array[Double] = new Array[Double](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readDouble + } + array + } + + def writeStringArray(array: Array[String]): Unit = { + if ((array == null) || (array.length == 0)) writeInt(0) + else { + writeInt(array.length) + val length: Int = array.length + for (index <- 0 until length) { + writeString(array(index)) + } + } + } + + def readStringArray: Array[String] = { + val size: Int = readInt + val array: Array[String] = new Array[String](size) + if (size > 0) for (index <- 0 until size) { + array(index) = readString + } + array + } + + def writeBooleanList(list: List[Boolean]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeBool(ele) + } + } + } + + def readBooleanList: List[Boolean] = { + val size: Int = readInt + var list: List[Boolean] = List() + if (size > 0) { + for (index <- 0 until size) { + list = list :+ readBool + } + } + list + } + + def writeByteList(list: List[Byte]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeByte(ele) + } + } + } + + def readByteList: List[Byte] = { + val size: Int = readInt + val list: ListBuffer[Byte] = new ListBuffer[Byte] + if (size > 0) { + for (index <- 0 until size) { + list.addOne(readByte) + } + } + list.toList + } + + def writeShortList(list: List[Short]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeShort(ele) + } + } + } + + def readShortList: List[Short] = { + val size: Int = readInt + val list: ListBuffer[Short] = new ListBuffer[Short] + if (size > 0) for (index <- 0 until size) { + list.addOne(readShort) + } + list.toList + } + + def writeIntList(list: List[Int]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeInt(ele) + } + } + } + + def readIntList: List[Int] = { + val size: Int = readInt + val list: ArrayBuffer[Int] = new ArrayBuffer[Int] + if (size > 0) for (index <- 0 until size) { + list.addOne(readInt) + } + list.toList + } + + def writeLongList(list: List[Long]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeLong(ele) + } + } + } + + def readLongList: List[Long] = { + val size: Int = readInt + val list: ArrayBuffer[Long] = new ArrayBuffer[Long] + if (size > 0) for (index <- 0 until size) { + list.addOne(readLong) + } + list.toList + } + + def writeFloatList(list: List[Float]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeFloat(ele) + } + } + } + + def readFloatList: List[Float] = { + val size: Int = readInt + val list: ArrayBuffer[Float] = new ArrayBuffer[Float] + if (size > 0) for (index <- 0 until size) { + list.addOne(readFloat) + } + list.toList + } + + def writeDoubleList(list: List[Double]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeDouble(ele) + } + } + } + + def readDoubleList: List[Double] = { + val size: Int = readInt + val list: ArrayBuffer[Double] = new ArrayBuffer[Double] + if (size > 0) for (index <- 0 until size) { + list.addOne(readDouble) + } + list.toList + } + + def writeStringList(list: List[String]): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + writeInt(list.size) + for (ele <- list) { + writeString(ele) + } + } + } + + def readStringList: List[String] = { + val size: Int = readInt + val list: ArrayBuffer[String] = new ArrayBuffer[String] + if (size > 0) for (index <- 0 until size) { + list.addOne(readString) + } + list.toList + } + + def writePacketList(list: List[_], protocolId: Short): Unit = { + if ((list == null) || list.isEmpty) writeInt(0) + else { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(list.size) + for (ele <- list) { + protocolRegistration.write(this, ele) + } + } + } + + def readPacketList[T](clazz: Class[T], protocolId: Short): List[T] = { + val size: Int = readInt + val list: ArrayBuffer[T] = new ArrayBuffer[T] + if (size > 0) { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index <- 0 until size) { + list.addOne(protocolRegistration.read(this).asInstanceOf[T]) + } + } + list.toList + } + + def writeBooleanSet(set: Set[Boolean]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeBool(ele) + } + } + } + + def readBooleanSet: Set[Boolean] = { + val size: Int = readInt + val set: ArrayBuffer[Boolean] = new ArrayBuffer[Boolean] + if (size > 0) for (index <- 0 until size) { + set.addOne(readBool) + } + set.toSet + } + + def writeShortSet(set: Set[Short]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeShort(ele) + } + } + } + + def readShortSet: Set[Short] = { + val size: Int = readInt + val set: ArrayBuffer[Short] = new ArrayBuffer[Short] + if (size > 0) for (index <- 0 until size) { + set.addOne(readShort) + } + set.toSet + } + + def writeIntSet(set: Set[Int]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeInt(ele) + } + } + } + + def readIntSet: Set[Int] = { + val size: Int = readInt + val set: ArrayBuffer[Int] = new ArrayBuffer[Int] + if (size > 0) for (index <- 0 until size) { + set.addOne(readInt) + } + set.toSet + } + + def writeLongSet(set: Set[Long]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeLong(ele) + } + } + } + + def readLongSet: Set[Long] = { + val size: Int = readInt + val set: ArrayBuffer[Long] = new ArrayBuffer[Long] + if (size > 0) for (index <- 0 until size) { + set.addOne(readLong) + } + set.toSet + } + + def writeFloatSet(set: Set[Float]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeFloat(ele) + } + } + } + + def readFloatSet: Set[Float] = { + val size: Int = readInt + val set: ArrayBuffer[Float] = new ArrayBuffer[Float] + if (size > 0) for (index <- 0 until size) { + set.addOne(readFloat) + } + set.toSet + } + + def writeDoubleSet(set: Set[Double]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeDouble(ele) + } + } + } + + def readDoubleSet: Set[Double] = { + val size: Int = readInt + val set: ArrayBuffer[Double] = new ArrayBuffer[Double] + if (size > 0) for (index <- 0 until size) { + set.addOne(readDouble) + } + set.toSet + } + + def writeStringSet(set: Set[String]): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + writeInt(set.size) + for (ele <- set) { + writeString(ele) + } + } + } + + def readStringSet: Set[String] = { + val size: Int = readInt + val set: ArrayBuffer[String] = new ArrayBuffer[String] + if (size > 0) for (index <- 0 until size) { + set.addOne(readString) + } + set.toSet + } + + def writePacketSet(set: Set[_], protocolId: Short): Unit = { + if ((set == null) || set.isEmpty) writeInt(0) + else { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(set.size) + for (element <- set) { + protocolRegistration.write(this, element) + } + } + } + + def readPacketSet[T](clazz: Class[T], protocolId: Short): Set[T] = { + val size: Int = readInt + val set: ArrayBuffer[T] = new ArrayBuffer[T] + if (size > 0) { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index <- 0 until size) { + set.addOne(protocolRegistration.read(this).asInstanceOf[T]) + } + } + set.toSet + } + + def writeIntIntMap(map: Map[Int, Int]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeInt(key) + writeInt(value) + } + } + } + + def readIntIntMap: Map[Int, Int] = { + val size: Int = readInt + val map = mutable.Map[Int, Int]() + if (size > 0) for (index <- 0 until size) { + val key: Int = readInt + val value: Int = readInt + map.put(key, value) + } + map.toMap + } + + def writeIntLongMap(map: Map[Int, Long]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeInt(key) + writeLong(value) + } + } + } + + def readIntLongMap: Map[Int, Long] = { + val size: Int = readInt + val map = mutable.Map[Int, Long]() + if (size > 0) for (index <- 0 until size) { + val key: Int = readInt + val value: Long = readLong + map.put(key, value) + } + map.toMap + } + + def writeIntStringMap(map: Map[Int, String]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeInt(key) + writeString(value) + } + } + } + + def readIntStringMap: Map[Int, String] = { + val size: Int = readInt + val map = mutable.Map[Int, String]() + if (size > 0) for (index <- 0 until size) { + val key: Int = readInt + val value: String = readString + map.put(key, value) + } + map.toMap + } + + def writeIntPacketMap(map: Map[Int, _], protocolId: Short): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) <- map) { + writeInt(key) + protocolRegistration.write(this, value) + } + } + } + + def readIntPacketMap[T](clazz: Class[T], protocolId: Short): Map[Int, T] = { + val size: Int = readInt + val map = mutable.Map[Int, T]() + if (size > 0) { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index <- 0 until size) { + val key: Int = readInt + val value: T = protocolRegistration.read(this).asInstanceOf[T] + map.put(key, value) + } + } + map.toMap + } + + def writeLongIntMap(map: Map[Long, Int]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeLong(key) + writeInt(value) + } + } + } + + def readLongIntMap: Map[Long, Int] = { + val size: Int = readInt + val map = mutable.Map[Long, Int]() + if (size > 0) for (index <- 0 until size) { + val key: Long = readLong + val value: Int = readInt + map.put(key, value) + } + map.toMap + } + + def writeLongLongMap(map: Map[Long, Long]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeLong(key) + writeLong(value) + } + } + } + + def readLongLongMap: Map[Long, Long] = { + val size: Int = readInt + val map = mutable.Map[Long, Long]() + if (size > 0) for (index <- 0 until size) { + val key: Long = readLong + val value: Long = readLong + map.put(key, value) + } + map.toMap + } + + def writeLongStringMap(map: Map[Long, String]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeLong(key) + writeString(value) + } + } + } + + def readLongStringMap: Map[Long, String] = { + val size: Int = readInt + val map = mutable.Map[Long, String]() + if (size > 0) for (index <- 0 until size) { + val key: Long = readLong + val value: String = readString + map.put(key, value) + } + map.toMap + } + + def writeLongPacketMap(map: Map[Long, _], protocolId: Short): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) <- map) { + writeLong(key) + protocolRegistration.write(this, value) + } + } + } + + def readLongPacketMap[T](clazz: Class[T], protocolId: Short): Map[Long, T] = { + val size: Int = readInt + val map = mutable.Map[Long, T]() + if (size > 0) { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index <- 0 until size) { + val key: Long = readLong + val value: T = protocolRegistration.read(this).asInstanceOf[T] + map.put(key, value) + } + } + map.toMap + } + + def writeStringIntMap(map: Map[String, Int]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeString(key) + writeInt(value) + } + } + } + + def readStringIntMap: Map[String, Int] = { + val size: Int = readInt + val map = mutable.Map[String, Int]() + if (size > 0) for (index <- 0 until size) { + val key: String = readString + val value: Int = readInt + map.put(key, value) + } + map.toMap + } + + def writeStringLongMap(map: Map[String, Long]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeString(key) + writeLong(value) + } + } + } + + def readStringLongMap: Map[String, Long] = { + val size: Int = readInt + val map = mutable.Map[String, Long]() + if (size > 0) for (index <- 0 until size) { + val key: String = readString + val value: Long = readLong + map.put(key, value) + } + map.toMap + } + + def writeStringStringMap(map: Map[String, String]): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + writeInt(map.size) + for ((key, value) <- map) { + writeString(key) + writeString(value) + } + } + } + + def readStringStringMap: Map[String, String] = { + val size: Int = readInt + val map = mutable.Map[String, String]() + if (size > 0) for (index <- 0 until size) { + val key: String = readString + val value: String = readString + map.put(key, value) + } + map.toMap + } + + def writeStringPacketMap(map: Map[String, _], protocolId: Short): Unit = { + if ((map == null) || map.isEmpty) writeInt(0) + else { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + writeInt(map.size) + for ((key, value) <- map) { + writeString(key) + protocolRegistration.write(this, value) + } + } + } + + def readStringPacketMap[T](clazz: Class[T], protocolId: Short): Map[String, T] = { + val size: Int = readInt + val map = mutable.Map[String, T]() + if (size > 0) { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + for (index <- 0 until size) { + val key: String = readString + val value: T = protocolRegistration.read(this).asInstanceOf[T] + map.put(key, value) + } + } + map.toMap + } + + def writePacket(packet: Any, protocolId: Short): Unit = { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + protocolRegistration.write(this, packet) + } + + def readPacket(protocolId: Short): Any = { + val protocolRegistration: IProtocolRegistration = ProtocolManager.getProtocol(protocolId) + protocolRegistration.read(this) + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/IProtocolRegistration.scala b/protocol/src/test/scala/com/zfoo/scala/IProtocolRegistration.scala new file mode 100644 index 00000000..b37ee244 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/IProtocolRegistration.scala @@ -0,0 +1,8 @@ +package com.zfoo.scala +trait IProtocolRegistration { + def protocolId: Short + + def write(buffer: ByteBuffer, packet: Any): Unit + + def read(buffer: ByteBuffer): Any +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/ProtocolManager.scala b/protocol/src/test/scala/com/zfoo/scala/ProtocolManager.scala new file mode 100644 index 00000000..f28d3b5e --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/ProtocolManager.scala @@ -0,0 +1,57 @@ +package com.zfoo.scala +import com.zfoo.scala.packet.EmptyObject +import com.zfoo.scala.packet.RegistrationEmptyObject +import com.zfoo.scala.packet.ComplexObject +import com.zfoo.scala.packet.RegistrationComplexObject +import com.zfoo.scala.packet.NormalObject +import com.zfoo.scala.packet.RegistrationNormalObject +import com.zfoo.scala.packet.ObjectA +import com.zfoo.scala.packet.RegistrationObjectA +import com.zfoo.scala.packet.ObjectB +import com.zfoo.scala.packet.RegistrationObjectB +import com.zfoo.scala.packet.SimpleObject +import com.zfoo.scala.packet.RegistrationSimpleObject +import scala.collection.mutable + +object ProtocolManager { + val MAX_PROTOCOL_NUM: Short = Short.MaxValue + val protocols = new Array[IProtocolRegistration](MAX_PROTOCOL_NUM) + val protocolIdMap = mutable.Map[Class[_], Short]() + + def initProtocol(): Unit = { + // initProtocol + protocols(0) = RegistrationEmptyObject + protocolIdMap.put(classOf[EmptyObject], 0) + protocols(100) = RegistrationComplexObject + protocolIdMap.put(classOf[ComplexObject], 100) + protocols(101) = RegistrationNormalObject + protocolIdMap.put(classOf[NormalObject], 101) + protocols(102) = RegistrationObjectA + protocolIdMap.put(classOf[ObjectA], 102) + protocols(103) = RegistrationObjectB + protocolIdMap.put(classOf[ObjectB], 103) + protocols(104) = RegistrationSimpleObject + protocolIdMap.put(classOf[SimpleObject], 104) + } + + def getProtocolId(clazz: Class[_]): Short = protocolIdMap.getOrElse(clazz, -1) + + def getProtocol(protocolId: Short): IProtocolRegistration = { + val protocol = protocols(protocolId) + if (protocol == null) throw new RuntimeException("[protocolId:" + protocolId + "] not exist") + protocol + } + + def write(buffer: ByteBuffer, packet: Any): Unit = { + val protocolId = getProtocolId(packet.getClass) + // write protocol id to buffer + buffer.writeShort(protocolId) + // write packet + getProtocol(protocolId).write(buffer, packet) + } + + def read(buffer: ByteBuffer): Any = { + val protocolId = buffer.readShort + getProtocol(protocolId).read(buffer) + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/ComplexObject.scala b/protocol/src/test/scala/com/zfoo/scala/packet/ComplexObject.scala new file mode 100644 index 00000000..35e2fcf0 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/ComplexObject.scala @@ -0,0 +1,416 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.packet.ObjectA +import com.zfoo.scala.packet.ObjectB +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + +// 复杂的对象,包括了各种复杂的结构,数组,List,Set,Map +class ComplexObject { + // byte类型,最简单的整形 + var a: Byte = 0 + // byte的包装类型,优先使用基础类型,包装类型会有装箱拆箱 + var aa: Byte = 0 + // 数组类型 + var aaa: Array[Byte] = _ + var aaaa: Array[Byte] = _ + var b: Short = 0 + var bb: Short = 0 + var bbb: Array[Short] = _ + var bbbb: Array[Short] = _ + var c: Int = 0 + var cc: Int = 0 + var ccc: Array[Int] = _ + var cccc: Array[Int] = _ + var d: Long = 0L + var dd: Long = 0L + var ddd: Array[Long] = _ + var dddd: Array[Long] = _ + var e: Float = 0f + var ee: Float = 0f + var eee: Array[Float] = _ + var eeee: Array[Float] = _ + var f: Double = 0D + var ff: Double = 0D + var fff: Array[Double] = _ + var ffff: Array[Double] = _ + var g: Boolean = false + var gg: Boolean = false + var ggg: Array[Boolean] = _ + var gggg: Array[Boolean] = _ + var jj: String = _ + var jjj: Array[String] = _ + var kk: ObjectA = _ + var kkk: Array[ObjectA] = _ + var l: List[Int] = _ + var ll: List[List[List[Int]]] = _ + var lll: List[List[ObjectA]] = _ + var llll: List[String] = _ + var lllll: List[Map[Int, String]] = _ + var m: Map[Int, String] = _ + var mm: Map[Int, ObjectA] = _ + var mmm: Map[ObjectA, List[Int]] = _ + var mmmm: Map[List[List[ObjectA]], List[List[List[Int]]]] = _ + var mmmmm: Map[List[Map[Int, String]], Set[Map[Int, String]]] = _ + var s: Set[Int] = _ + var ss: Set[Set[List[Int]]] = _ + var sss: Set[Set[ObjectA]] = _ + var ssss: Set[String] = _ + var sssss: Set[Map[Int, String]] = _ + // 如果要修改协议并且兼容老协议,需要加上Compatible注解,保持Compatible注解的value自增 + var myCompatible: Int = 0 + var myObject: ObjectA = _ +} + +object RegistrationComplexObject extends IProtocolRegistration { + override def protocolId: Short = 100 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[ComplexObject] + val beforeWriteIndex = buffer.getWriteOffset + 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.length) + val length0 = message.kkk.length + for (i1 <- 0 until length0) { + val element2 = message.kkk(i1) + buffer.writePacket(element2, 102) + } + buffer.writeIntList(message.l) + buffer.writeInt(message.ll.size) + for (element3 <- message.ll) { + buffer.writeInt(element3.size) + for (element4 <- element3) { + buffer.writeIntList(element4) + } + } + buffer.writeInt(message.lll.size) + for (element5 <- message.lll) { + buffer.writePacketList(element5, 102) + } + buffer.writeStringList(message.llll) + buffer.writeInt(message.lllll.size) + for (element6 <- message.lllll) { + buffer.writeIntStringMap(element6) + } + buffer.writeIntStringMap(message.m) + buffer.writeIntPacketMap(message.mm, 102) + buffer.writeInt(message.mmm.size) + for ((keyElement7, valueElement8) <- message.mmm) { + buffer.writePacket(keyElement7, 102) + buffer.writeIntList(valueElement8) + } + buffer.writeInt(message.mmmm.size) + for ((keyElement9, valueElement10) <- message.mmmm) { + buffer.writeInt(keyElement9.size) + for (element11 <- keyElement9) { + buffer.writePacketList(element11, 102) + } + buffer.writeInt(valueElement10.size) + for (element12 <- valueElement10) { + buffer.writeInt(element12.size) + for (element13 <- element12) { + buffer.writeIntList(element13) + } + } + } + buffer.writeInt(message.mmmmm.size) + for ((keyElement14, valueElement15) <- message.mmmmm) { + buffer.writeInt(keyElement14.size) + for (element16 <- keyElement14) { + buffer.writeIntStringMap(element16) + } + buffer.writeInt(valueElement15.size) + for (i17 <- valueElement15) { + buffer.writeIntStringMap(i17) + } + } + buffer.writeIntSet(message.s) + buffer.writeInt(message.ss.size) + for (i18 <- message.ss) { + buffer.writeInt(i18.size) + for (i19 <- i18) { + buffer.writeIntList(i19) + } + } + buffer.writeInt(message.sss.size) + for (i20 <- message.sss) { + buffer.writePacketSet(i20, 102) + } + buffer.writeStringSet(message.ssss) + buffer.writeInt(message.sssss.size) + for (i21 <- message.sssss) { + buffer.writeIntStringMap(i21) + } + buffer.writeInt(message.myCompatible) + buffer.writePacket(message.myObject, 102) + buffer.adjustPadding(36962, beforeWriteIndex) + } + + override def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: ComplexObject = new ComplexObject + 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).asInstanceOf[ObjectA] + packet.kk = result30 + val size34 = buffer.readInt + val result31 = new mutable.ArrayBuffer[ObjectA]() + if (size34 > 0) { + for (index32 <- 0 until size34) { + val result35 = buffer.readPacket(102).asInstanceOf[ObjectA] + result31.addOne(result35) + } + } + packet.kkk = result31.toArray + val list36 = buffer.readIntList + packet.l = list36 + val size39 = buffer.readInt + val result37 = new mutable.ListBuffer[List[List[Int]]]() + if (size39 > 0) { + for (index38 <- 0 until size39) { + val size42 = buffer.readInt + val result40 = new mutable.ListBuffer[List[Int]]() + if (size42 > 0) { + for (index41 <- 0 until size42) { + val list43 = buffer.readIntList + result40.addOne(list43) + } + } + result37.addOne(result40.toList) + } + } + packet.ll = result37.toList + val size46 = buffer.readInt + val result44 = new mutable.ListBuffer[List[ObjectA]]() + if (size46 > 0) { + for (index45 <- 0 until size46) { + val list47 = buffer.readPacketList(classOf[ObjectA], 102) + result44.addOne(list47) + } + } + packet.lll = result44.toList + val list48 = buffer.readStringList + packet.llll = list48 + val size51 = buffer.readInt + val result49 = new mutable.ListBuffer[Map[Int, String]]() + if (size51 > 0) { + for (index50 <- 0 until size51) { + val map52 = buffer.readIntStringMap + result49.addOne(map52) + } + } + packet.lllll = result49.toList + val map53 = buffer.readIntStringMap + packet.m = map53 + val map54 = buffer.readIntPacketMap(classOf[ObjectA], 102) + packet.mm = map54 + val size56 = buffer.readInt + val result55 = new mutable.HashMap[ObjectA, List[Int]]() + if (size56 > 0) { + for (index57 <- 0 until size56) { + val result58 = buffer.readPacket(102).asInstanceOf[ObjectA] + val list59 = buffer.readIntList + result55.put(result58, list59) + } + } + packet.mmm = result55.toMap + val size61 = buffer.readInt + val result60 = new mutable.HashMap[List[List[ObjectA]], List[List[List[Int]]]]() + if (size61 > 0) { + for (index62 <- 0 until size61) { + val size65 = buffer.readInt + val result63 = new mutable.ListBuffer[List[ObjectA]]() + if (size65 > 0) { + for (index64 <- 0 until size65) { + val list66 = buffer.readPacketList(classOf[ObjectA], 102) + result63.addOne(list66) + } + } + val size69 = buffer.readInt + val result67 = new mutable.ListBuffer[List[List[Int]]]() + if (size69 > 0) { + for (index68 <- 0 until size69) { + val size72 = buffer.readInt + val result70 = new mutable.ListBuffer[List[Int]]() + if (size72 > 0) { + for (index71 <- 0 until size72) { + val list73 = buffer.readIntList + result70.addOne(list73) + } + } + result67.addOne(result70.toList) + } + } + result60.put(result63.toList, result67.toList) + } + } + packet.mmmm = result60.toMap + val size75 = buffer.readInt + val result74 = new mutable.HashMap[List[Map[Int, String]], Set[Map[Int, String]]]() + if (size75 > 0) { + for (index76 <- 0 until size75) { + val size79 = buffer.readInt + val result77 = new mutable.ListBuffer[Map[Int, String]]() + if (size79 > 0) { + for (index78 <- 0 until size79) { + val map80 = buffer.readIntStringMap + result77.addOne(map80) + } + } + val size83 = buffer.readInt + val result81 = new mutable.HashSet[Map[Int, String]]() + if (size83 > 0) { + for (index82 <- 0 until size83) { + val map84 = buffer.readIntStringMap + result81.add(map84) + } + } + result74.put(result77.toList, result81.toSet) + } + } + packet.mmmmm = result74.toMap + val set85 = buffer.readIntSet + packet.s = set85 + val size88 = buffer.readInt + val result86 = new mutable.HashSet[Set[List[Int]]]() + if (size88 > 0) { + for (index87 <- 0 until size88) { + val size91 = buffer.readInt + val result89 = new mutable.HashSet[List[Int]]() + if (size91 > 0) { + for (index90 <- 0 until size91) { + val list92 = buffer.readIntList + result89.add(list92) + } + } + result86.add(result89.toSet) + } + } + packet.ss = result86.toSet + val size95 = buffer.readInt + val result93 = new mutable.HashSet[Set[ObjectA]]() + if (size95 > 0) { + for (index94 <- 0 until size95) { + val set96 = buffer.readPacketSet(classOf[ObjectA], 102) + result93.add(set96) + } + } + packet.sss = result93.toSet + val set97 = buffer.readStringSet + packet.ssss = set97 + val size100 = buffer.readInt + val result98 = new mutable.HashSet[Map[Int, String]]() + if (size100 > 0) { + for (index99 <- 0 until size100) { + val map101 = buffer.readIntStringMap + result98.add(map101) + } + } + packet.sssss = result98.toSet + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result102 = buffer.readInt + packet.myCompatible = result102 + } + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result103 = buffer.readPacket(102).asInstanceOf[ObjectA] + packet.myObject = result103 + } + if (length > 0) buffer.setReadOffset(beforeReadIndex + length) + packet + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/EmptyObject.scala b/protocol/src/test/scala/com/zfoo/scala/packet/EmptyObject.scala new file mode 100644 index 00000000..0f00e0cf --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/EmptyObject.scala @@ -0,0 +1,32 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + + +class EmptyObject { + +} + +object RegistrationEmptyObject extends IProtocolRegistration { + override def protocolId: Short = 0 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[EmptyObject] + buffer.writeInt(-1) + } + + override def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: EmptyObject = new EmptyObject + + if (length > 0) buffer.setReadOffset(beforeReadIndex + length) + packet + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/NormalObject.scala b/protocol/src/test/scala/com/zfoo/scala/packet/NormalObject.scala new file mode 100644 index 00000000..81b01246 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/NormalObject.scala @@ -0,0 +1,119 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.packet.ObjectA +import com.zfoo.scala.packet.ObjectB +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + +// 常规的对象,取所有语言语法的交集,基本上所有语言都支持下面的语法 +class NormalObject { + var a: Byte = 0 + var aaa: Array[Byte] = _ + var b: Short = 0 + // 整数类型 + var c: Int = 0 + var d: Long = 0L + var e: Float = 0f + var f: Double = 0D + var g: Boolean = false + var jj: String = _ + var kk: ObjectA = _ + var l: List[Int] = _ + var ll: List[Long] = _ + var lll: List[ObjectA] = _ + var llll: List[String] = _ + var m: Map[Int, String] = _ + var mm: Map[Int, ObjectA] = _ + var s: Set[Int] = _ + var ssss: Set[String] = _ + var outCompatibleValue: Int = 0 + var outCompatibleValue2: Int = 0 +} + +object RegistrationNormalObject extends IProtocolRegistration { + override def protocolId: Short = 101 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[NormalObject] + val beforeWriteIndex = buffer.getWriteOffset + 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 def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: NormalObject = new NormalObject + 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).asInstanceOf[ObjectA] + packet.kk = result9 + val list10 = buffer.readIntList + packet.l = list10 + val list11 = buffer.readLongList + packet.ll = list11 + val list12 = buffer.readPacketList(classOf[ObjectA], 102) + packet.lll = list12 + val list13 = buffer.readStringList + packet.llll = list13 + val map14 = buffer.readIntStringMap + packet.m = map14 + val map15 = buffer.readIntPacketMap(classOf[ObjectA], 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) + packet + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/ObjectA.scala b/protocol/src/test/scala/com/zfoo/scala/packet/ObjectA.scala new file mode 100644 index 00000000..8ce2cf12 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/ObjectA.scala @@ -0,0 +1,51 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.packet.ObjectB +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + + +class ObjectA { + var a: Int = 0 + var m: Map[Int, String] = _ + var objectB: ObjectB = _ + var innerCompatibleValue: Int = 0 +} + +object RegistrationObjectA extends IProtocolRegistration { + override def protocolId: Short = 102 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[ObjectA] + val beforeWriteIndex = buffer.getWriteOffset + 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 def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: ObjectA = new ObjectA + val result0 = buffer.readInt + packet.a = result0 + val map1 = buffer.readIntStringMap + packet.m = map1 + val result2 = buffer.readPacket(103).asInstanceOf[ObjectB] + packet.objectB = result2 + if (buffer.compatibleRead(beforeReadIndex, length)) { + val result3 = buffer.readInt + packet.innerCompatibleValue = result3 + } + if (length > 0) buffer.setReadOffset(beforeReadIndex + length) + packet + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/ObjectB.scala b/protocol/src/test/scala/com/zfoo/scala/packet/ObjectB.scala new file mode 100644 index 00000000..3750e7aa --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/ObjectB.scala @@ -0,0 +1,42 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + + +class ObjectB { + var flag: Boolean = false + var innerCompatibleValue: Int = 0 +} + +object RegistrationObjectB extends IProtocolRegistration { + override def protocolId: Short = 103 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[ObjectB] + val beforeWriteIndex = buffer.getWriteOffset + buffer.writeInt(4) + buffer.writeBool(message.flag) + buffer.writeInt(message.innerCompatibleValue) + buffer.adjustPadding(4, beforeWriteIndex) + } + + override def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: ObjectB = new ObjectB + 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) + packet + } +} \ No newline at end of file diff --git a/protocol/src/test/scala/com/zfoo/scala/packet/SimpleObject.scala b/protocol/src/test/scala/com/zfoo/scala/packet/SimpleObject.scala new file mode 100644 index 00000000..829892a4 --- /dev/null +++ b/protocol/src/test/scala/com/zfoo/scala/packet/SimpleObject.scala @@ -0,0 +1,38 @@ +package com.zfoo.scala.packet +import com.zfoo.scala.IProtocolRegistration +import com.zfoo.scala.ByteBuffer +import scala.collection.mutable + + +class SimpleObject { + var c: Int = 0 + var g: Boolean = false +} + +object RegistrationSimpleObject extends IProtocolRegistration { + override def protocolId: Short = 104 + + override def write(buffer: ByteBuffer, packet: Any): Unit = { + if (packet == null) { + buffer.writeInt(0) + return + } + val message = packet.asInstanceOf[SimpleObject] + buffer.writeInt(-1) + buffer.writeInt(message.c) + buffer.writeBool(message.g) + } + + override def read(buffer: ByteBuffer): AnyRef = { + val length: Int = buffer.readInt + if (length == 0) return null + val beforeReadIndex: Int = buffer.getReadOffset + val packet: SimpleObject = new SimpleObject + val result0 = buffer.readInt + packet.c = result0 + val result1 = buffer.readBool + packet.g = result1 + if (length > 0) buffer.setReadOffset(beforeReadIndex + length) + packet + } +} \ No newline at end of file