From 3ae5d567e34dd11f9c5b6607ccef109ec22e2a01 Mon Sep 17 00:00:00 2001 From: cfig Date: Fri, 18 Feb 2022 16:29:20 +0800 Subject: [PATCH] vendor_boot: allow null bootconfig --- .../src/main/kotlin/avb/alg/Algorithms.kt | 2 +- bbootimg/src/main/kotlin/avb/blob/AuthBlob.kt | 2 +- bbootimg/src/main/kotlin/avb/blob/AuxBlob.kt | 2 +- bbootimg/src/main/kotlin/avb/blob/Footer.kt | 2 +- bbootimg/src/main/kotlin/avb/blob/Header.kt | 2 +- .../avb/desc/ChainPartitionDescriptor.kt | 2 +- .../main/kotlin/avb/desc/HashDescriptor.kt | 2 +- .../kotlin/avb/desc/HashTreeDescriptor.kt | 2 +- .../avb/desc/KernelCmdlineDescriptor.kt | 2 +- .../kotlin/avb/desc/PropertyDescriptor.kt | 2 +- .../main/kotlin/avb/desc/UnknownDescriptor.kt | 2 +- bbootimg/src/main/kotlin/bcb/BootloaderMsg.kt | 2 +- .../src/main/kotlin/bcb/BootloaderMsgAB.kt | 2 +- bbootimg/src/main/kotlin/bcb/VirtualABMsg.kt | 2 +- bbootimg/src/main/kotlin/bootimg/Common.kt | 14 +- .../main/kotlin/bootimg/cpio/NewAsciiCpio.kt | 2 +- .../main/kotlin/bootimg/v2/BootHeaderV2.kt | 2 +- .../main/kotlin/bootimg/v3/BootHeaderV3.kt | 2 +- .../src/main/kotlin/bootimg/v3/VendorBoot.kt | 10 +- .../kotlin/bootimg/v3/VendorBootHeader.kt | 2 +- bbootimg/src/main/kotlin/utils/Dtbo.kt | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../main/kotlin/cfig/helper/CryptoHelper.kt | 3 +- helper/src/main/kotlin/cfig/helper/Helper.kt | 2 +- .../src/main/kotlin/cfig/helper/ZipHelper.kt | 2 +- helper/src/main/kotlin/cfig/io/Struct3.kt | 68 ++- .../src/main/kotlin/cfig/io/Struct3Retire.kt | 530 ------------------ .../test/kotlin/cfig/io/Struct3RetireTest.kt | 511 ----------------- helper/src/test/kotlin/cfig/io/Struct3Test.kt | 2 +- 29 files changed, 72 insertions(+), 1110 deletions(-) delete mode 100644 helper/src/main/kotlin/cfig/io/Struct3Retire.kt delete mode 100644 helper/src/test/kotlin/cfig/io/Struct3RetireTest.kt diff --git a/bbootimg/src/main/kotlin/avb/alg/Algorithms.kt b/bbootimg/src/main/kotlin/avb/alg/Algorithms.kt index 0d3e33c..a6754e7 100644 --- a/bbootimg/src/main/kotlin/avb/alg/Algorithms.kt +++ b/bbootimg/src/main/kotlin/avb/alg/Algorithms.kt @@ -14,7 +14,7 @@ package avb.alg -import cfig.io.Struct3 +import cc.cfig.io.Struct3 class Algorithms { companion object { diff --git a/bbootimg/src/main/kotlin/avb/blob/AuthBlob.kt b/bbootimg/src/main/kotlin/avb/blob/AuthBlob.kt index 7dee7e0..d8080cd 100644 --- a/bbootimg/src/main/kotlin/avb/blob/AuthBlob.kt +++ b/bbootimg/src/main/kotlin/avb/blob/AuthBlob.kt @@ -17,7 +17,7 @@ package avb.blob import avb.alg.Algorithms import cfig.helper.CryptoHelper import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.slf4j.LoggerFactory import java.nio.file.Files import java.nio.file.Paths diff --git a/bbootimg/src/main/kotlin/avb/blob/AuxBlob.kt b/bbootimg/src/main/kotlin/avb/blob/AuxBlob.kt index fd94148..9f80b9a 100644 --- a/bbootimg/src/main/kotlin/avb/blob/AuxBlob.kt +++ b/bbootimg/src/main/kotlin/avb/blob/AuxBlob.kt @@ -18,7 +18,7 @@ import avb.alg.Algorithm import avb.desc.* import cfig.helper.CryptoHelper import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import com.fasterxml.jackson.annotation.JsonIgnoreProperties import org.bouncycastle.asn1.pkcs.RSAPrivateKey import org.slf4j.LoggerFactory diff --git a/bbootimg/src/main/kotlin/avb/blob/Footer.kt b/bbootimg/src/main/kotlin/avb/blob/Footer.kt index d652464..c37510b 100644 --- a/bbootimg/src/main/kotlin/avb/blob/Footer.kt +++ b/bbootimg/src/main/kotlin/avb/blob/Footer.kt @@ -14,7 +14,7 @@ package avb.blob -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import java.io.File import java.io.FileInputStream import java.io.InputStream diff --git a/bbootimg/src/main/kotlin/avb/blob/Header.kt b/bbootimg/src/main/kotlin/avb/blob/Header.kt index 67c4340..e4814fe 100644 --- a/bbootimg/src/main/kotlin/avb/blob/Header.kt +++ b/bbootimg/src/main/kotlin/avb/blob/Header.kt @@ -15,7 +15,7 @@ package avb.blob import cfig.Avb -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import java.io.InputStream //avbtool::AvbVBMetaHeader diff --git a/bbootimg/src/main/kotlin/avb/desc/ChainPartitionDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/ChainPartitionDescriptor.kt index db398c2..9c57f65 100644 --- a/bbootimg/src/main/kotlin/avb/desc/ChainPartitionDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/ChainPartitionDescriptor.kt @@ -17,7 +17,7 @@ package avb.desc import avb.AVBInfo import cfig.Avb import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import java.io.File import java.io.InputStream import java.security.MessageDigest diff --git a/bbootimg/src/main/kotlin/avb/desc/HashDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/HashDescriptor.kt index 1088d80..4ccaa4f 100644 --- a/bbootimg/src/main/kotlin/avb/desc/HashDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/HashDescriptor.kt @@ -16,7 +16,7 @@ package avb.desc import avb.blob.Header import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.apache.commons.codec.binary.Hex import org.slf4j.LoggerFactory import java.io.File diff --git a/bbootimg/src/main/kotlin/avb/desc/HashTreeDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/HashTreeDescriptor.kt index 4977cd6..ae02d4e 100644 --- a/bbootimg/src/main/kotlin/avb/desc/HashTreeDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/HashTreeDescriptor.kt @@ -17,7 +17,7 @@ package avb.desc import avb.blob.Header import cfig.helper.CryptoHelper import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.* import java.security.MessageDigest diff --git a/bbootimg/src/main/kotlin/avb/desc/KernelCmdlineDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/KernelCmdlineDescriptor.kt index ac790cf..6f29b24 100644 --- a/bbootimg/src/main/kotlin/avb/desc/KernelCmdlineDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/KernelCmdlineDescriptor.kt @@ -15,7 +15,7 @@ package avb.desc import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import java.io.InputStream class KernelCmdlineDescriptor( diff --git a/bbootimg/src/main/kotlin/avb/desc/PropertyDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/PropertyDescriptor.kt index c9dfab0..4f6687f 100644 --- a/bbootimg/src/main/kotlin/avb/desc/PropertyDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/PropertyDescriptor.kt @@ -15,7 +15,7 @@ package avb.desc import cfig.helper.Helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import java.io.InputStream class PropertyDescriptor( diff --git a/bbootimg/src/main/kotlin/avb/desc/UnknownDescriptor.kt b/bbootimg/src/main/kotlin/avb/desc/UnknownDescriptor.kt index eec2fa1..beb117b 100644 --- a/bbootimg/src/main/kotlin/avb/desc/UnknownDescriptor.kt +++ b/bbootimg/src/main/kotlin/avb/desc/UnknownDescriptor.kt @@ -14,8 +14,8 @@ package avb.desc +import cc.cfig.io.Struct3 import cfig.helper.Helper -import cfig.io.Struct3 import org.apache.commons.codec.binary.Hex import org.slf4j.LoggerFactory import java.io.ByteArrayInputStream diff --git a/bbootimg/src/main/kotlin/bcb/BootloaderMsg.kt b/bbootimg/src/main/kotlin/bcb/BootloaderMsg.kt index 6b9bf07..03fb499 100644 --- a/bbootimg/src/main/kotlin/bcb/BootloaderMsg.kt +++ b/bbootimg/src/main/kotlin/bcb/BootloaderMsg.kt @@ -14,7 +14,7 @@ package cfig.bcb -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.File import java.io.FileInputStream diff --git a/bbootimg/src/main/kotlin/bcb/BootloaderMsgAB.kt b/bbootimg/src/main/kotlin/bcb/BootloaderMsgAB.kt index ad202cb..100fa0f 100644 --- a/bbootimg/src/main/kotlin/bcb/BootloaderMsgAB.kt +++ b/bbootimg/src/main/kotlin/bcb/BootloaderMsgAB.kt @@ -14,7 +14,7 @@ package cfig.bcb -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.FileInputStream diff --git a/bbootimg/src/main/kotlin/bcb/VirtualABMsg.kt b/bbootimg/src/main/kotlin/bcb/VirtualABMsg.kt index 43ef411..a7bd4fe 100644 --- a/bbootimg/src/main/kotlin/bcb/VirtualABMsg.kt +++ b/bbootimg/src/main/kotlin/bcb/VirtualABMsg.kt @@ -14,8 +14,8 @@ package cfig.bcb +import cc.cfig.io.Struct3 import cfig.helper.Helper -import cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.FileInputStream diff --git a/bbootimg/src/main/kotlin/bootimg/Common.kt b/bbootimg/src/main/kotlin/bootimg/Common.kt index 827db39..2ec21e1 100644 --- a/bbootimg/src/main/kotlin/bootimg/Common.kt +++ b/bbootimg/src/main/kotlin/bootimg/Common.kt @@ -14,12 +14,12 @@ package cfig.bootimg +import cc.cfig.io.Struct3 import cfig.utils.EnvironmentVerifier import cfig.bootimg.cpio.AndroidCpio import cfig.utils.DTC import cfig.helper.Helper import cfig.helper.ZipHelper -import cfig.io.Struct3 import cfig.utils.KernelExtractor import org.apache.commons.exec.CommandLine import org.apache.commons.exec.DefaultExecutor @@ -66,9 +66,9 @@ class Common { if (m.groupCount() == 3) { c = Integer.decode(m.group(3)) } - assert(a < 128) - assert(b < 128) - assert(c < 128) + check(a < 128) + check(b < 128) + check(c < 128) return (a shl 14) or (b shl 7) or c } else { throw IllegalArgumentException("invalid os_version") @@ -91,8 +91,8 @@ class Common { val y = Integer.parseInt(matcher.group(1), 10) - 2000 val m = Integer.parseInt(matcher.group(2), 10) // 7 bits allocated for the year, 4 bits for the month - assert(y in 0..127) - assert(m in 1..12) + check(y in 0..127) + check(m in 1..12) ret = (y shl 4) or m } else { throw IllegalArgumentException("invalid os_patch_level") @@ -307,7 +307,7 @@ class Common { fun writePaddedFile(inBF: ByteBuffer, srcFile: String, padding: UInt) { log.info("adding $srcFile into buffer ...") - assert(padding < Int.MAX_VALUE.toUInt()) + check(padding < Int.MAX_VALUE.toUInt()) writePaddedFile(inBF, srcFile, padding.toInt()) } diff --git a/bbootimg/src/main/kotlin/bootimg/cpio/NewAsciiCpio.kt b/bbootimg/src/main/kotlin/bootimg/cpio/NewAsciiCpio.kt index 3467727..350bc6c 100644 --- a/bbootimg/src/main/kotlin/bootimg/cpio/NewAsciiCpio.kt +++ b/bbootimg/src/main/kotlin/bootimg/cpio/NewAsciiCpio.kt @@ -14,7 +14,7 @@ package cfig.bootimg.cpio -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.apache.commons.compress.archivers.cpio.CpioConstants import java.util.* diff --git a/bbootimg/src/main/kotlin/bootimg/v2/BootHeaderV2.kt b/bbootimg/src/main/kotlin/bootimg/v2/BootHeaderV2.kt index cec7e4c..6e8fa9a 100644 --- a/bbootimg/src/main/kotlin/bootimg/v2/BootHeaderV2.kt +++ b/bbootimg/src/main/kotlin/bootimg/v2/BootHeaderV2.kt @@ -14,9 +14,9 @@ package cfig.bootimg.v2 +import cc.cfig.io.Struct3 import cfig.helper.Helper import cfig.bootimg.Common -import cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.InputStream import kotlin.math.pow diff --git a/bbootimg/src/main/kotlin/bootimg/v3/BootHeaderV3.kt b/bbootimg/src/main/kotlin/bootimg/v3/BootHeaderV3.kt index 0bbc3a2..e86dcf4 100644 --- a/bbootimg/src/main/kotlin/bootimg/v3/BootHeaderV3.kt +++ b/bbootimg/src/main/kotlin/bootimg/v3/BootHeaderV3.kt @@ -14,8 +14,8 @@ package cfig.bootimg.v3 +import cc.cfig.io.Struct3 import cfig.bootimg.Common -import cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.InputStream diff --git a/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt b/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt index c16cf7e..92b91e1 100644 --- a/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt +++ b/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt @@ -15,12 +15,12 @@ package cfig.bootimg.v3 import avb.AVBInfo +import cc.cfig.io.Struct3 import cfig.Avb import cfig.utils.EnvironmentVerifier import cfig.bootimg.Common.Companion.deleleIfExists import cfig.bootimg.Signer import cfig.helper.Helper -import cfig.io.Struct3 import cfig.packable.VBMetaParser import com.fasterxml.jackson.databind.ObjectMapper import de.vandermeer.asciitable.AsciiTable @@ -287,7 +287,9 @@ data class VendorBoot( //2. vrt it.put(this.ramdisk_table.update().encode(this.info.pageSize)) //3. bootconfig - C.writePaddedFile(it, this.bootconfig.file, this.info.pageSize) + if (this.bootconfig.file.isNotBlank()) { + C.writePaddedFile(it, this.bootconfig.file, this.info.pageSize) + } it } } @@ -451,7 +453,9 @@ data class VendorBoot( addArgument("--ramdisk_name").addArgument(it.name, true) addArgument("--vendor_ramdisk_fragment").addArgument(it.file) } - addArgument("--vendor_bootconfig").addArgument(bootconfig.file) + if (bootconfig.file.isNotBlank()) { + addArgument("--vendor_bootconfig").addArgument(bootconfig.file) + } } } addArgument("--dtb").addArgument(dtb.file) diff --git a/bbootimg/src/main/kotlin/bootimg/v3/VendorBootHeader.kt b/bbootimg/src/main/kotlin/bootimg/v3/VendorBootHeader.kt index 2c4dc77..8fff635 100644 --- a/bbootimg/src/main/kotlin/bootimg/v3/VendorBootHeader.kt +++ b/bbootimg/src/main/kotlin/bootimg/v3/VendorBootHeader.kt @@ -14,7 +14,7 @@ package cfig.bootimg.v3 -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.slf4j.LoggerFactory import java.io.InputStream diff --git a/bbootimg/src/main/kotlin/utils/Dtbo.kt b/bbootimg/src/main/kotlin/utils/Dtbo.kt index b01ef4d..9e370d9 100644 --- a/bbootimg/src/main/kotlin/utils/Dtbo.kt +++ b/bbootimg/src/main/kotlin/utils/Dtbo.kt @@ -1,12 +1,12 @@ package utils import avb.AVBInfo +import cc.cfig.io.Struct3 import cfig.Avb import cfig.bootimg.Common import cfig.bootimg.Signer import cfig.bootimg.v3.VendorBoot import cfig.helper.Helper -import cfig.io.Struct3 import cfig.packable.VBMetaParser import cfig.utils.DTC import com.fasterxml.jackson.databind.ObjectMapper diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/helper/src/main/kotlin/cfig/helper/CryptoHelper.kt b/helper/src/main/kotlin/cfig/helper/CryptoHelper.kt index c31b562..98c723a 100644 --- a/helper/src/main/kotlin/cfig/helper/CryptoHelper.kt +++ b/helper/src/main/kotlin/cfig/helper/CryptoHelper.kt @@ -1,6 +1,7 @@ +@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE") package cfig.helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import com.google.common.math.BigIntegerMath import org.apache.commons.exec.CommandLine import org.apache.commons.exec.DefaultExecutor diff --git a/helper/src/main/kotlin/cfig/helper/Helper.kt b/helper/src/main/kotlin/cfig/helper/Helper.kt index ebc0c03..4b1fd55 100644 --- a/helper/src/main/kotlin/cfig/helper/Helper.kt +++ b/helper/src/main/kotlin/cfig/helper/Helper.kt @@ -14,7 +14,7 @@ package cfig.helper -import cfig.io.Struct3 +import cc.cfig.io.Struct3 import org.apache.commons.exec.CommandLine import org.apache.commons.exec.DefaultExecutor import org.apache.commons.exec.ExecuteException diff --git a/helper/src/main/kotlin/cfig/helper/ZipHelper.kt b/helper/src/main/kotlin/cfig/helper/ZipHelper.kt index ba136bc..05aba7f 100644 --- a/helper/src/main/kotlin/cfig/helper/ZipHelper.kt +++ b/helper/src/main/kotlin/cfig/helper/ZipHelper.kt @@ -14,9 +14,9 @@ package cfig.helper +import cc.cfig.io.Struct3 import cfig.helper.Helper.Companion.check_call import cfig.helper.Helper.Companion.check_output -import cfig.io.Struct3 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream diff --git a/helper/src/main/kotlin/cfig/io/Struct3.kt b/helper/src/main/kotlin/cfig/io/Struct3.kt index 7a782de..77edc40 100644 --- a/helper/src/main/kotlin/cfig/io/Struct3.kt +++ b/helper/src/main/kotlin/cfig/io/Struct3.kt @@ -1,7 +1,19 @@ -package cfig.io +// Copyright 2022 yuyezhong@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cc.cfig.io -import org.slf4j.Logger -import org.slf4j.LoggerFactory import java.io.IOException import java.io.InputStream import java.nio.ByteBuffer @@ -72,7 +84,7 @@ class Struct3(inFormatString: String) { return ByteBuffer.allocate(this.calcSize()).let { bf -> bf.order(this.byteOrder) args.forEachIndexed { index, arg -> - warships.get(index).put(bf, arg) + warships[index].put(bf, arg) } bf.array() } @@ -86,7 +98,6 @@ class Struct3(inFormatString: String) { private interface IWarShip { val sz: Int var multiple: Int - val log: Logger fun get(stream: InputStream, byteOrder: ByteOrder): T fun get(ba: ByteArray, byteOrder: ByteOrder): T fun put(bf: ByteBuffer, arg: Any?) @@ -112,7 +123,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getShort() + it.short } } @@ -133,7 +144,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = Short.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(ShortShip::class.java) } private class UShortShip : IBaseShip { @@ -150,7 +160,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getShort().toUShort() + it.short.toUShort() } } @@ -175,7 +185,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = UShort.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(UShortShip::class.java) } //i, l: Int @@ -193,7 +202,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getInt() + it.int } } @@ -207,7 +216,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = Int.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(IntShip::class.java) } //I, L: UInt @@ -225,7 +233,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getInt().toUInt() + it.int.toUInt() } } @@ -249,7 +257,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = UInt.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(UIntShip::class.java) } //q: Long @@ -267,7 +274,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getLong() + it.long } } @@ -284,7 +291,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = Long.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(LongShip::class.java) } //Q: ULong @@ -302,7 +308,7 @@ class Struct3(inFormatString: String) { it.order(byteOrder) it.put(ba) it.flip() - it.getLong().toULong() + it.long.toULong() } } @@ -326,7 +332,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = ULong.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(ULongShip::class.java) } //c: character @@ -338,7 +343,7 @@ class Struct3(inFormatString: String) { } override fun get(ba: ByteArray, byteOrder: ByteOrder): Char { - return ba.get(0).toInt().toChar() + return ba[0].toInt().toChar() } override fun put(bf: ByteBuffer, arg: Any?) { @@ -354,21 +359,20 @@ class Struct3(inFormatString: String) { } override val sz: Int = 1 - override val log: Logger = LoggerFactory.getLogger(CharShip::class.java) } private interface IBaseFleet : IWarShip { fun appendPadding(bf: ByteBuffer, b: Byte, bufSize: Int) { when { bufSize == 0 -> { - log.debug("paddingSize is zero, perfect match") + //"paddingSize is zero, perfect match" return } bufSize < 0 -> { throw IllegalArgumentException("illegal padding size: $bufSize") } else -> { - log.debug("paddingSize $bufSize") + //"paddingSize $bufSize" } } val padding = ByteArray(bufSize) @@ -382,9 +386,8 @@ class Struct3(inFormatString: String) { if (paddingSize < 0) throw IllegalArgumentException("arg length [${inByteArray.size}] exceeds limit: $bufSize") //data bf.put(inByteArray) - //padding + //padding: "paddingSize $paddingSize" appendPadding(bf, 0.toByte(), paddingSize) - log.debug("paddingSize $paddingSize") } fun appendByteArray(bf: ByteBuffer, inIntArray: IntArray, bufSize: Int) { @@ -429,7 +432,7 @@ class Struct3(inFormatString: String) { } override fun get(ba: ByteArray, byteOrder: ByteOrder): Byte { - TODO("Not yet implemented") + return ba[0] } override fun put(bf: ByteBuffer, arg: Any?) { @@ -444,8 +447,6 @@ class Struct3(inFormatString: String) { override fun toString(): String { return "${multiple}x" } - - override val log: Logger = LoggerFactory.getLogger(PaddingFleet::class.java) } //b: byte array @@ -457,7 +458,8 @@ class Struct3(inFormatString: String) { } override fun get(ba: ByteArray, byteOrder: ByteOrder): ByteArray { - TODO("Not yet implemented") + check(multiple == ba.size) + return ba } override fun put(bf: ByteBuffer, arg: Any?) { @@ -473,7 +475,6 @@ class Struct3(inFormatString: String) { } override val sz: Int = Byte.SIZE_BYTES - override val log: Logger = LoggerFactory.getLogger(ByteFleet::class.java) } //B: UByte array @@ -486,6 +487,10 @@ class Struct3(inFormatString: String) { return innerData2.toUByteArray() } + override fun get(ba: ByteArray, byteOrder: ByteOrder): UByteArray { + return ba.toUByteArray() + } + override fun put(bf: ByteBuffer, arg: Any?) { when (arg) { is ByteArray -> appendByteArray(bf, arg, multiple) @@ -501,12 +506,6 @@ class Struct3(inFormatString: String) { override val sz: Int get() = UByte.SIZE_BYTES - - override fun get(ba: ByteArray, byteOrder: ByteOrder): UByteArray { - TODO("Not yet implemented") - } - - override val log: Logger = LoggerFactory.getLogger(UByteFleet::class.java) } //s: String @@ -536,6 +535,5 @@ class Struct3(inFormatString: String) { } override val sz: Int = 1 - override val log: Logger = LoggerFactory.getLogger(StringFleet::class.java) } } diff --git a/helper/src/main/kotlin/cfig/io/Struct3Retire.kt b/helper/src/main/kotlin/cfig/io/Struct3Retire.kt deleted file mode 100644 index 5fd2cc9..0000000 --- a/helper/src/main/kotlin/cfig/io/Struct3Retire.kt +++ /dev/null @@ -1,530 +0,0 @@ -// Copyright 2021 yuyezhong@gmail.com -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cfig.io - -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toCString -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toInt -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toLong -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toShort -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toUInt -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toULong -import cfig.io.Struct3Retire.ByteArrayExt.Companion.toUShort -import cfig.io.Struct3Retire.ByteBufferExt.Companion.appendByteArray -import cfig.io.Struct3Retire.ByteBufferExt.Companion.appendPadding -import cfig.io.Struct3Retire.ByteBufferExt.Companion.appendUByteArray -import cfig.io.Struct3Retire.InputStreamExt.Companion.getByteArray -import cfig.io.Struct3Retire.InputStreamExt.Companion.getCString -import cfig.io.Struct3Retire.InputStreamExt.Companion.getChar -import cfig.io.Struct3Retire.InputStreamExt.Companion.getInt -import cfig.io.Struct3Retire.InputStreamExt.Companion.getLong -import cfig.io.Struct3Retire.InputStreamExt.Companion.getPadding -import cfig.io.Struct3Retire.InputStreamExt.Companion.getShort -import cfig.io.Struct3Retire.InputStreamExt.Companion.getUByteArray -import cfig.io.Struct3Retire.InputStreamExt.Companion.getUInt -import cfig.io.Struct3Retire.InputStreamExt.Companion.getULong -import cfig.io.Struct3Retire.InputStreamExt.Companion.getUShort -import org.slf4j.LoggerFactory -import java.io.IOException -import java.io.InputStream -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.charset.StandardCharsets -import java.util.* -import java.util.regex.Pattern -import kotlin.random.Random - -class Struct3Retire { - private val formatString: String - private var byteOrder = ByteOrder.LITTLE_ENDIAN - private val formats = ArrayList>() - - constructor(inFormatString: String) { - assert(inFormatString.isNotEmpty()) { "FORMAT_STRING must not be empty" } - formatString = inFormatString - val m = Pattern.compile("(\\d*)([a-zA-Z])").matcher(formatString) - when (formatString[0]) { - '>', '!' -> this.byteOrder = ByteOrder.BIG_ENDIAN - '@', '=' -> this.byteOrder = ByteOrder.nativeOrder() - else -> this.byteOrder = ByteOrder.LITTLE_ENDIAN - } - while (m.find()) { - //item[0]: Type, item[1]: multiple - // if need to expand format items, explode it - // eg: "4L" will be exploded to "1L 1L 1L 1L", so it's treated as primitive - // eg: "10x" won't be exploded, it's still "10x", so it's treated as non-primitive - val typeName: Any = when (m.group(2)) { - //primitive types - "x" -> Random //byte 1 (exploded) - "b" -> Byte //byte 1 (exploded) - "B" -> UByte //UByte 1 (exploded) - "s" -> String //string (exploded) - //zippable types, which need to be exploded with multiple=1 - "c" -> Char - "h" -> Short //2 - "H" -> UShort //2 - "i", "l" -> Int //4 - "I", "L" -> UInt //4 - "q" -> Long //8 - "Q" -> ULong //8 - else -> throw IllegalArgumentException("type [" + m.group(2) + "] not supported") - } - val bPrimitive = m.group(2) in listOf("x", "b", "B", "s") - val multiple = if (m.group(1).isEmpty()) 1 else Integer.decode(m.group(1)) - if (bPrimitive) { - formats.add(arrayOf(typeName, multiple)) - } else { - for (i in 0 until multiple) { - formats.add(arrayOf(typeName, 1)) - } - } - } - } - - private fun getFormatInfo(inCursor: Int): String { - return ("type=" + formats.get(inCursor)[0] + ", value=" + formats.get(inCursor)[1]) - } - - override fun toString(): String { - val formatStr = mutableListOf() - formats.forEach { - val fs = StringBuilder() - when (it[0]) { - Random -> fs.append("x") - Byte -> fs.append("b") - UByte -> fs.append("B") - String -> fs.append("s") - Char -> fs.append("c") - Short -> fs.append("h") - UShort -> fs.append("H") - Int -> fs.append("i") - UInt -> fs.append("I") - Long -> fs.append("q") - ULong -> fs.append("Q") - else -> throw IllegalArgumentException("type [" + it[0] + "] not supported") - } - fs.append(":" + it[1]) - formatStr.add(fs.toString()) - } - return "Struct3Retire(formatString='$formatString', byteOrder=$byteOrder, formats=$formatStr)" - } - - fun calcSize(): Int { - var ret = 0 - for (format in formats) { - ret += when (val formatType = format[0]) { - Random, Byte, UByte, Char, String -> format[1] as Int - Short, UShort -> 2 * format[1] as Int - Int, UInt -> 4 * format[1] as Int - Long, ULong -> 8 * format[1] as Int - else -> throw IllegalArgumentException("Class [$formatType] not supported") - } - } - return ret - } - - @Throws(IllegalArgumentException::class) - fun pack(vararg args: Any?): ByteArray { - if (args.size != this.formats.size) { - throw IllegalArgumentException("argument size " + args.size + " doesn't match format size " + this.formats.size) - } - val bf = ByteBuffer.allocate(this.calcSize()) - bf.order(this.byteOrder) - for (i in args.indices) { - val arg = args[i] - val typeName = formats[i][0] - val multiple = formats[i][1] as Int - - if (typeName !in arrayOf(Random, Byte, String, UByte)) { - assert(1 == multiple) - } - - //x: padding: - if (Random == typeName) { - when (arg) { - null -> bf.appendPadding(0, multiple) - is Byte -> bf.appendPadding(arg, multiple) - is Int -> bf.appendPadding(arg.toByte(), multiple) - else -> throw IllegalArgumentException("Index[" + i + "] Unsupported arg [" + arg + "] with type [" + formats[i][0] + "]") - } - continue - } - - //c: character - if (Char == typeName) { - assert(arg is Char) { "[$arg](${arg!!::class.java}) is NOT Char" } - if ((arg as Char) !in '\u0000'..'\u00ff') { - throw IllegalArgumentException("arg[${arg.code}] exceeds 8-bit bound") - } - bf.put(arg.code.toByte()) - continue - } - - //b: byte array - if (Byte == typeName) { - when (arg) { - is IntArray -> bf.appendByteArray(arg, multiple) - is ByteArray -> bf.appendByteArray(arg, multiple) - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT ByteArray/IntArray") - } - continue - } - - //B: UByte array - if (UByte == typeName) { - when (arg) { - is ByteArray -> bf.appendByteArray(arg, multiple) - is UByteArray -> bf.appendUByteArray(arg, multiple) - is IntArray -> bf.appendUByteArray(arg, multiple) - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT ByteArray/IntArray") - } - continue - } - - //s: String - if (String == typeName) { - assert(arg != null) { "arg can not be NULL for String, formatString=$formatString, ${getFormatInfo(i)}" } - assert(arg is String) { "[$arg](${arg!!::class.java}) is NOT String, ${getFormatInfo(i)}" } - bf.appendByteArray((arg as String).toByteArray(), multiple) - continue - } - - //h: Short - if (Short == typeName) { - when (arg) { - is Int -> { - assert(arg in Short.MIN_VALUE..Short.MAX_VALUE) { "[$arg] is truncated as type Short.class" } - bf.putShort(arg.toShort()) - } - is Short -> bf.putShort(arg) //instance Short - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Short/Int") - } - continue - } - - //H: UShort - if (UShort == typeName) { - assert(arg is UShort || arg is UInt || arg is Int) { "[$arg](${arg!!::class.java}) is NOT UShort/UInt/Int" } - when (arg) { - is Int -> { - assert(arg >= UShort.MIN_VALUE.toInt() && arg <= UShort.MAX_VALUE.toInt()) { "[$arg] is truncated as type UShort" } - bf.putShort(arg.toShort()) - } - is UInt -> { - assert(arg >= UShort.MIN_VALUE && arg <= UShort.MAX_VALUE) { "[$arg] is truncated as type UShort" } - bf.putShort(arg.toShort()) - } - is UShort -> bf.putShort(arg.toShort()) - } - continue - } - - //i, l: Int - if (Int == typeName) { - assert(arg is Int) { "[$arg](${arg!!::class.java}) is NOT Int" } - bf.putInt(arg as Int) - continue - } - - //I, L: UInt - if (UInt == typeName) { - when (arg) { - is Int -> { - assert(arg >= 0) { "[$arg] is invalid as type UInt" } - bf.putInt(arg) - } - is UInt -> bf.putInt(arg.toInt()) - is Long -> { - assert(arg >= 0) { "[$arg] is invalid as type UInt" } - bf.putInt(arg.toInt()) - } - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT UInt/Int/Long") - } - continue - } - - //q: Long - if (Long == typeName) { - when (arg) { - is Long -> bf.putLong(arg) - is Int -> bf.putLong(arg.toLong()) - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Long/Int") - } - continue - } - - //Q: ULong - if (ULong == typeName) { - when (arg) { - is Int -> { - assert(arg >= 0) { "[$arg] is invalid as type ULong" } - bf.putLong(arg.toLong()) - } - is Long -> { - assert(arg >= 0) { "[$arg] is invalid as type ULong" } - bf.putLong(arg) - } - is ULong -> bf.putLong(arg.toLong()) - else -> throw IllegalArgumentException("[$arg](${arg!!::class.java}) is NOT Int/Long/ULong") - } - continue - } - - throw IllegalArgumentException("unrecognized format $typeName") - } - return bf.array() - } - - @Throws(IOException::class, IllegalArgumentException::class) - fun unpack(iS: InputStream): List<*> { - val ret = ArrayList() - for (format in this.formats) { - when (format[0]) { - Random -> ret.add(iS.getPadding(format[1] as Int)) //return padding byte - Byte -> ret.add(iS.getByteArray(format[1] as Int)) //b: byte array - UByte -> ret.add(iS.getUByteArray(format[1] as Int)) //B: ubyte array - Char -> ret.add(iS.getChar()) //char: 1 - String -> ret.add(iS.getCString(format[1] as Int)) //c string - Short -> ret.add(iS.getShort(this.byteOrder)) //h: short - UShort -> ret.add(iS.getUShort(this.byteOrder)) //H: UShort - Int -> ret.add(iS.getInt(this.byteOrder)) //i, l: Int - UInt -> ret.add(iS.getUInt(this.byteOrder)) //I, L: UInt - Long -> ret.add(iS.getLong(this.byteOrder)) //q: Long - ULong -> ret.add(iS.getULong(this.byteOrder)) //Q: ULong - else -> throw IllegalArgumentException("Class [" + format[0] + "] not supported") - }//end-of-when - }//end-of-for - return ret - } - - class ByteBufferExt { - companion object { - private val log = LoggerFactory.getLogger(ByteBufferExt::class.java) - - @Throws(IllegalArgumentException::class) - fun ByteBuffer.appendPadding(b: Byte, bufSize: Int) { - when { - bufSize == 0 -> { - log.debug("paddingSize is zero, perfect match") - return - } - bufSize < 0 -> { - throw IllegalArgumentException("illegal padding size: $bufSize") - } - else -> { - log.debug("paddingSize $bufSize") - } - } - val padding = ByteArray(bufSize) - Arrays.fill(padding, b) - this.put(padding) - } - - fun ByteBuffer.appendByteArray(inIntArray: IntArray, bufSize: Int) { - val arg2 = mutableListOf() - inIntArray.toMutableList().mapTo(arg2) { - if (it in Byte.MIN_VALUE..Byte.MAX_VALUE) { - it.toByte() - } else { - throw IllegalArgumentException("$it is not valid Byte") - } - } - appendByteArray(arg2.toByteArray(), bufSize) - } - - @Throws(IllegalArgumentException::class) - fun ByteBuffer.appendByteArray(inByteArray: ByteArray, bufSize: Int) { - val paddingSize = bufSize - inByteArray.size - if (paddingSize < 0) throw IllegalArgumentException("arg length [${inByteArray.size}] exceeds limit: $bufSize") - //data - this.put(inByteArray) - //padding - this.appendPadding(0.toByte(), paddingSize) - log.debug("paddingSize $paddingSize") - } - - fun ByteBuffer.appendUByteArray(inIntArray: IntArray, bufSize: Int) { - val arg2 = mutableListOf() - inIntArray.toMutableList().mapTo(arg2) { - if (it in UByte.MIN_VALUE.toInt()..UByte.MAX_VALUE.toInt()) - it.toUByte() - else { - throw IllegalArgumentException("$it is not valid Byte") - } - } - appendUByteArray(arg2.toUByteArray(), bufSize) - } - - fun ByteBuffer.appendUByteArray(inUByteArray: UByteArray, bufSize: Int) { - val bl = mutableListOf() - inUByteArray.toMutableList().mapTo(bl) { it.toByte() } - this.appendByteArray(bl.toByteArray(), bufSize) - } - } - } - - private class InputStreamExt { - companion object { - fun InputStream.getChar(): Char { - val data = ByteArray(Byte.SIZE_BYTES) - assert(Byte.SIZE_BYTES == this.read(data)) - return data[0].toInt().toChar() - } - - fun InputStream.getShort(inByteOrder: ByteOrder): Short { - val data = ByteArray(Short.SIZE_BYTES) - assert(Short.SIZE_BYTES == this.read(data)) - return data.toShort(inByteOrder) - } - - fun InputStream.getInt(inByteOrder: ByteOrder): Int { - val data = ByteArray(Int.SIZE_BYTES) - assert(Int.SIZE_BYTES == this.read(data)) - return data.toInt(inByteOrder) - } - - fun InputStream.getLong(inByteOrder: ByteOrder): Long { - val data = ByteArray(Long.SIZE_BYTES) - assert(Long.SIZE_BYTES == this.read(data)) - return data.toLong(inByteOrder) - } - - fun InputStream.getUShort(inByteOrder: ByteOrder): UShort { - val data = ByteArray(UShort.SIZE_BYTES) - assert(UShort.SIZE_BYTES == this.read(data)) - return data.toUShort(inByteOrder) - } - - fun InputStream.getUInt(inByteOrder: ByteOrder): UInt { - val data = ByteArray(UInt.SIZE_BYTES) - assert(UInt.SIZE_BYTES == this.read(data)) - return data.toUInt(inByteOrder) - } - - fun InputStream.getULong(inByteOrder: ByteOrder): ULong { - val data = ByteArray(ULong.SIZE_BYTES) - assert(ULong.SIZE_BYTES == this.read(data)) - return data.toULong(inByteOrder) - } - - fun InputStream.getByteArray(inSize: Int): ByteArray { - val data = ByteArray(inSize) - assert(inSize == this.read(data)) - return data - } - - fun InputStream.getUByteArray(inSize: Int): UByteArray { - val data = ByteArray(inSize) - assert(inSize == this.read(data)) - val innerData2 = mutableListOf() - data.toMutableList().mapTo(innerData2) { it.toUByte() } - return innerData2.toUByteArray() - } - - fun InputStream.getCString(inSize: Int): String { - val data = ByteArray(inSize) - assert(inSize == this.read(data)) - return data.toCString() - } - - fun InputStream.getPadding(inSize: Int): Byte { - val data = ByteArray(Byte.SIZE_BYTES) - assert(Byte.SIZE_BYTES == this.read(data)) //sample the 1st byte - val skipped = this.skip(inSize.toLong() - Byte.SIZE_BYTES)//skip remaining to save memory - assert(inSize.toLong() - Byte.SIZE_BYTES == skipped) - return data[0] - } - } - } - - class ByteArrayExt { - companion object { - fun ByteArray.toShort(inByteOrder: ByteOrder): Short { - val typeSize = Short.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "Short must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getShort() - } - } - - fun ByteArray.toInt(inByteOrder: ByteOrder): Int { - val typeSize = Int.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "Int must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getInt() - } - } - - fun ByteArray.toLong(inByteOrder: ByteOrder): Long { - val typeSize = Long.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "Long must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getLong() - } - } - - fun ByteArray.toUShort(inByteOrder: ByteOrder): UShort { - val typeSize = UShort.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "UShort must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getShort().toUShort() - } - } - - fun ByteArray.toUInt(inByteOrder: ByteOrder): UInt { - val typeSize = UInt.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "UInt must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getInt().toUInt() - } - } - - fun ByteArray.toULong(inByteOrder: ByteOrder): ULong { - val typeSize = ULong.SIZE_BYTES / Byte.SIZE_BYTES - assert(typeSize == this.size) { "ULong must have $typeSize bytes" } - return ByteBuffer.allocate(this.size).let { - it.order(inByteOrder) - it.put(this) - it.flip() - it.getLong().toULong() - } - } - - //similar to this.toString(StandardCharsets.UTF_8).replace("${Character.MIN_VALUE}", "") - // not Deprecated for now, "1.3.41 experimental api: ByteArray.decodeToString()") is a little different - fun ByteArray.toCString(): String { - return this.toString(StandardCharsets.UTF_8).let { str -> - str.indexOf(Character.MIN_VALUE).let { nullPos -> - if (nullPos >= 0) str.substring(0, nullPos) else str - } - } - } - }//end-of-Companion - }//end-of-ByteArrayExt -} diff --git a/helper/src/test/kotlin/cfig/io/Struct3RetireTest.kt b/helper/src/test/kotlin/cfig/io/Struct3RetireTest.kt deleted file mode 100644 index 30f9514..0000000 --- a/helper/src/test/kotlin/cfig/io/Struct3RetireTest.kt +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright 2021 yuyezhong@gmail.com -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cfig.io - -import cfig.helper.Helper -import cfig.io.Struct3Retire -import com.fasterxml.jackson.databind.ObjectMapper -import org.junit.Assert -import org.junit.Test -import java.io.ByteArrayInputStream - -@OptIn(kotlin.ExperimentalUnsignedTypes::class) -class Struct3RetireTest { - private fun getConvertedFormats(inStruct: Struct3Retire): ArrayList> { - val f = inStruct.javaClass.getDeclaredField("formats") - f.isAccessible = true - val formatDumps = arrayListOf>() - (f.get(inStruct) as ArrayList<*>).apply { - this.forEach { - @Suppress("UNCHECKED_CAST") - val format = it as Array - val k = if (format[0].toString().indexOf(" ") > 0) { - format[0].toString().split(" ")[1] - } else { - format[0].toString() - } - formatDumps.add(mapOf(k to (format[1] as Int))) - } - } - return formatDumps - } - - private fun constructorTestFun1(inFormatString: String) { - println(ObjectMapper().writeValueAsString(getConvertedFormats(Struct3Retire(inFormatString)))) - } - - @Test - fun constructorTest() { - constructorTestFun1("3s") - constructorTestFun1("5b") - constructorTestFun1("5x") - constructorTestFun1("2c") - } - - @Test - fun calcSizeTest() { - Assert.assertEquals(3, Struct3Retire("3s").calcSize()) - Assert.assertEquals(5, Struct3Retire("5b").calcSize()) - Assert.assertEquals(5, Struct3Retire("5x").calcSize()) - Assert.assertEquals(9, Struct3Retire("9c").calcSize()) - } - - @Test - fun toStringTest() { - println(Struct3Retire("!4s2L2QL11QL4x47sx80x")) - } - - //x - @Test - fun paddingTest() { - Assert.assertEquals("0000000000", Helper.toHexString(Struct3Retire("5x").pack(null))) - Assert.assertEquals("0000000000", Helper.toHexString(Struct3Retire("5x").pack(0))) - Assert.assertEquals("0101010101", Helper.toHexString(Struct3Retire("5x").pack(1))) - Assert.assertEquals("1212121212", Helper.toHexString(Struct3Retire("5x").pack(0x12))) - //Integer高位被截掉 - Assert.assertEquals("2323232323", Helper.toHexString(Struct3Retire("5x").pack(0x123))) - // minus 0001_0011 -> 补码 1110 1101,ie. 0xed - Assert.assertEquals("ededededed", Helper.toHexString(Struct3Retire("5x").pack(-0x13))) - //0xff - Assert.assertEquals("ffffffffff", Helper.toHexString(Struct3Retire("5x").pack(-1))) - - try { - Struct3Retire("5x").pack("bad") - Assert.assertTrue("should throw exception here", false) - } catch (e: IllegalArgumentException) { - } - - //unpack - Struct3Retire("3x").unpack(ByteArrayInputStream(Helper.fromHexString("000000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(0.toByte(), it[0]) - } - Struct3Retire("x2xx").unpack(ByteArrayInputStream(Helper.fromHexString("01121210"))).let { - Assert.assertEquals(3, it.size) - Assert.assertEquals(0x1.toByte(), it[0]) - Assert.assertEquals(0x12.toByte(), it[1]) - Assert.assertEquals(0x10.toByte(), it[2]) - } - } - - //c - @Test - fun characterTest() { - //constructor - Struct3Retire("c") - - //calcSize - Assert.assertEquals(3, Struct3Retire("3c").calcSize()) - - //pack illegal - try { - Struct3Retire("c").pack("a") - Assert.fail("should throw exception here") - } catch (e: Throwable) { - Assert.assertTrue(e is AssertionError || e is IllegalArgumentException) - } - - //pack legal - Assert.assertEquals( - "61", - Helper.toHexString(Struct3Retire("!c").pack('a')) - ) - Assert.assertEquals( - "61", - Helper.toHexString(Struct3Retire("c").pack('a')) - ) - Assert.assertEquals( - "616263", - Helper.toHexString(Struct3Retire("3c").pack('a', 'b', 'c')) - ) - - //unpack - Struct3Retire("3c").unpack(ByteArrayInputStream(Helper.fromHexString("616263"))).let { - Assert.assertEquals(3, it.size) - Assert.assertEquals('a', it[0]) - Assert.assertEquals('b', it[1]) - Assert.assertEquals('c', it[2]) - } - } - - //b - @Test - fun bytesTest() { - //constructor - Struct3Retire("b") - - //calcSize - Assert.assertEquals(3, Struct3Retire("3b").calcSize()) - - //pack - Assert.assertEquals( - "123456", Helper.toHexString( - Struct3Retire("3b").pack(byteArrayOf(0x12, 0x34, 0x56)) - ) - ) - Assert.assertEquals( - "123456", Helper.toHexString( - Struct3Retire("!3b").pack(byteArrayOf(0x12, 0x34, 0x56)) - ) - ) - Assert.assertEquals( - "123400", Helper.toHexString( - Struct3Retire("3b").pack(byteArrayOf(0x12, 0x34)) - ) - ) - - //unpack - Struct3Retire("3b").unpack(ByteArrayInputStream(Helper.fromHexString("123400"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals("123400", Helper.toHexString(it[0] as ByteArray)) - } - Struct3Retire("bbb").unpack(ByteArrayInputStream(Helper.fromHexString("123400"))).let { - Assert.assertEquals(3, it.size) - Assert.assertEquals("12", Helper.toHexString(it[0] as ByteArray)) - Assert.assertEquals("34", Helper.toHexString(it[1] as ByteArray)) - Assert.assertEquals("00", Helper.toHexString(it[2] as ByteArray)) - } - } - - //B: UByte array - @Test - fun uBytesTest() { - //constructor - Struct3Retire("B") - - //calcSize - Assert.assertEquals(3, Struct3Retire("3B").calcSize()) - - //pack - Assert.assertEquals( - "123456", Helper.toHexString( - Struct3Retire("3B").pack(byteArrayOf(0x12, 0x34, 0x56)) - ) - ) - Assert.assertEquals( - "123456", Helper.toHexString( - Struct3Retire("!3B").pack(byteArrayOf(0x12, 0x34, 0x56)) - ) - ) - Assert.assertEquals( - "123400", Helper.toHexString( - Struct3Retire("3B").pack(byteArrayOf(0x12, 0x34)) - ) - ) - - //unpack - Struct3Retire("3B").unpack(ByteArrayInputStream(Helper.fromHexString("123400"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals("123400", Helper.toHexString(it[0] as UByteArray)) - } - Struct3Retire("BBB").unpack(ByteArrayInputStream(Helper.fromHexString("123400"))).let { - Assert.assertEquals(3, it.size) - Assert.assertEquals("12", Helper.toHexString(it[0] as UByteArray)) - Assert.assertEquals("34", Helper.toHexString(it[1] as UByteArray)) - Assert.assertEquals("00", Helper.toHexString(it[2] as UByteArray)) - } - } - - //s - @Test - fun stringTest() { - //constructor - Struct3Retire("s") - - //calcSize - Assert.assertEquals(3, Struct3Retire("3s").calcSize()) - - //pack - Struct3Retire("3s").pack("a") - Struct3Retire("3s").pack("abc") - try { - Struct3Retire("3s").pack("abcd") - Assert.fail("should throw exception here") - } catch (e: Throwable) { - Assert.assertTrue(e.toString(), e is AssertionError || e is IllegalArgumentException) - } - - //unpack - Struct3Retire("3s").unpack(ByteArrayInputStream(Helper.fromHexString("616263"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals("abc", it[0]) - } - Struct3Retire("3s").unpack(ByteArrayInputStream(Helper.fromHexString("610000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals("a", it[0]) - } - } - - //h - @Test - fun shortTest() { - //constructor - Struct3Retire("h") - - //calcSize - Assert.assertEquals(6, Struct3Retire("3h").calcSize()) - - //pack - Assert.assertEquals("ff7f", Helper.toHexString(Struct3Retire("h").pack(0x7fff))) - Assert.assertEquals("0080", Helper.toHexString(Struct3Retire("h").pack(-0x8000))) - Assert.assertEquals("7fff0000", Helper.toHexString(Struct3Retire(">2h").pack(0x7fff, 0))) - - //unpack - Struct3Retire(">2h").unpack(ByteArrayInputStream(Helper.fromHexString("7fff0000"))).let { - Assert.assertEquals(2, it.size) - Assert.assertEquals(0x7fff.toShort(), it[0]) - Assert.assertEquals(0.toShort(), it[1]) - } - } - - //H - @Test - fun uShortTest() { - //constructor - Struct3Retire("H") - - //calcSize - Assert.assertEquals(6, Struct3Retire("3H").calcSize()) - - //pack - Assert.assertEquals("0100", Helper.toHexString(Struct3Retire("H").pack((1U).toUShort()))) - Assert.assertEquals("0100", Helper.toHexString(Struct3Retire("H").pack(1U))) - Assert.assertEquals("ffff", Helper.toHexString(Struct3Retire("H").pack(65535U))) - Assert.assertEquals("ffff", Helper.toHexString(Struct3Retire("H").pack(65535))) - try { - Struct3Retire("H").pack(-1) - Assert.fail("should throw exception here") - } catch (e: Throwable) { - Assert.assertTrue(e is AssertionError || e is IllegalArgumentException) - } - //unpack - Struct3Retire("H").unpack(ByteArrayInputStream(Helper.fromHexString("ffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(65535U.toUShort(), it[0]) - } - } - - //i, l - @Test - fun intTest() { - //constructor - Struct3Retire("i") - Struct3Retire("l") - - //calcSize - Assert.assertEquals(12, Struct3Retire("3i").calcSize()) - Assert.assertEquals(12, Struct3Retire("3l").calcSize()) - - //pack - Struct3Retire("i").pack(65535 + 1) - Struct3Retire("i").pack(-1) - //unpack - Struct3Retire("i").unpack(ByteArrayInputStream(Helper.fromHexString("00000100"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(65536, it[0]) - } - Struct3Retire("i").unpack(ByteArrayInputStream(Helper.fromHexString("ffffffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(-1, it[0]) - } - } - - //I, L - @Test - fun uIntTest() { - //constructor - Struct3Retire("I") - Struct3Retire("L") - - //calcSize - Assert.assertEquals(12, Struct3Retire("3I").calcSize()) - Assert.assertEquals(12, Struct3Retire("3L").calcSize()) - - //pack - Assert.assertEquals( - "01000000", Helper.toHexString( - Struct3Retire("I").pack(1U) - ) - ) - Assert.assertEquals( - "80000000", Helper.toHexString( - Struct3Retire(">I").pack(Int.MAX_VALUE.toUInt() + 1U) - ) - ) - //unpack - Struct3Retire("I").unpack(ByteArrayInputStream(Helper.fromHexString("01000000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(1U, it[0]) - } - Struct3Retire(">I").unpack(ByteArrayInputStream(Helper.fromHexString("80000000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(Int.MAX_VALUE.toUInt() + 1U, it[0]) - } - } - - //q: Long - @Test - fun longTest() { - //constructor - Struct3Retire("q") - - //calcSize - Assert.assertEquals(24, Struct3Retire("3q").calcSize()) - - //pack - Assert.assertEquals( - "8000000000000000", Helper.toHexString( - Struct3Retire(">q").pack(Long.MIN_VALUE) - ) - ) - Assert.assertEquals( - "7fffffffffffffff", Helper.toHexString( - Struct3Retire(">q").pack(Long.MAX_VALUE) - ) - ) - Assert.assertEquals( - "ffffffffffffffff", Helper.toHexString( - Struct3Retire(">q").pack(-1L) - ) - ) - //unpack - Struct3Retire(">q").unpack(ByteArrayInputStream(Helper.fromHexString("8000000000000000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(Long.MIN_VALUE, it[0]) - } - Struct3Retire(">q").unpack(ByteArrayInputStream(Helper.fromHexString("7fffffffffffffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(Long.MAX_VALUE, it[0]) - } - Struct3Retire(">q").unpack(ByteArrayInputStream(Helper.fromHexString("ffffffffffffffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(-1L, it[0]) - } - } - - //Q: ULong - @Test - fun uLongTest() { - //constructor - Struct3Retire("Q") - - //calcSize - Assert.assertEquals(24, Struct3Retire("3Q").calcSize()) - - //pack - Assert.assertEquals( - "7fffffffffffffff", Helper.toHexString( - Struct3Retire(">Q").pack(Long.MAX_VALUE) - ) - ) - Assert.assertEquals( - "0000000000000000", Helper.toHexString( - Struct3Retire(">Q").pack(ULong.MIN_VALUE) - ) - ) - Assert.assertEquals( - "ffffffffffffffff", Helper.toHexString( - Struct3Retire(">Q").pack(ULong.MAX_VALUE) - ) - ) - try { - Struct3Retire(">Q").pack(-1L) - } catch (e: Throwable) { - Assert.assertTrue(e is AssertionError || e is IllegalArgumentException) - } - //unpack - Struct3Retire(">Q").unpack(ByteArrayInputStream(Helper.fromHexString("7fffffffffffffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(Long.MAX_VALUE.toULong(), it[0]) - } - Struct3Retire(">Q").unpack(ByteArrayInputStream(Helper.fromHexString("0000000000000000"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(ULong.MIN_VALUE, it[0]) - } - Struct3Retire(">Q").unpack(ByteArrayInputStream(Helper.fromHexString("ffffffffffffffff"))).let { - Assert.assertEquals(1, it.size) - Assert.assertEquals(ULong.MAX_VALUE, it[0]) - } - } - - @Test - fun legacyTest() { - Assert.assertTrue( - Struct3Retire("<2i4b4b").pack( - 1, 7321, byteArrayOf(1, 2, 3, 4), byteArrayOf(200.toByte(), 201.toByte(), 202.toByte(), 203.toByte()) - ) - .contentEquals(Helper.fromHexString("01000000991c000001020304c8c9cacb")) - ) - Assert.assertTrue( - Struct3Retire("<2i4b4B").pack( - 1, 7321, byteArrayOf(1, 2, 3, 4), intArrayOf(200, 201, 202, 203) - ) - .contentEquals(Helper.fromHexString("01000000991c000001020304c8c9cacb")) - ) - - Assert.assertTrue(Struct3Retire("b2x").pack(byteArrayOf(0x13), null).contentEquals(Helper.fromHexString("130000"))) - Assert.assertTrue( - Struct3Retire("b2xi").pack(byteArrayOf(0x13), null, 55).contentEquals(Helper.fromHexString("13000037000000")) - ) - - Struct3Retire("5s").pack("Good").contentEquals(Helper.fromHexString("476f6f6400")) - Struct3Retire("5s1b").pack("Good", byteArrayOf(13)).contentEquals(Helper.fromHexString("476f6f64000d")) - } - - - @Test - fun legacyIntegerLE() { - //int (4B) - Assert.assertTrue(Struct3Retire("<2i").pack(1, 7321).contentEquals(Helper.fromHexString("01000000991c0000"))) - val ret = Struct3Retire("<2i").unpack(ByteArrayInputStream(Helper.fromHexString("01000000991c0000"))) - Assert.assertEquals(2, ret.size) - Assert.assertTrue(ret[0] is Int) - Assert.assertTrue(ret[1] is Int) - Assert.assertEquals(1, ret[0] as Int) - Assert.assertEquals(7321, ret[1] as Int) - - //unsigned int (4B) - Assert.assertTrue(Struct3Retire("2i").pack(1, 7321).contentEquals(Helper.fromHexString("0000000100001c99"))) - val ret = Struct3Retire(">2i").unpack(ByteArrayInputStream(Helper.fromHexString("0000000100001c99"))) - Assert.assertEquals(1, ret[0] as Int) - Assert.assertEquals(7321, ret[1] as Int) - } - - run { - Assert.assertTrue(Struct3Retire("!i").pack(-333).contentEquals(Helper.fromHexString("fffffeb3"))) - val ret2 = Struct3Retire("!i").unpack(ByteArrayInputStream(Helper.fromHexString("fffffeb3"))) - Assert.assertEquals(-333, ret2[0] as Int) - } - } -} diff --git a/helper/src/test/kotlin/cfig/io/Struct3Test.kt b/helper/src/test/kotlin/cfig/io/Struct3Test.kt index 9b180b8..3d528dd 100644 --- a/helper/src/test/kotlin/cfig/io/Struct3Test.kt +++ b/helper/src/test/kotlin/cfig/io/Struct3Test.kt @@ -1,4 +1,4 @@ -package cfig.io +package cc.cfig.io import cfig.helper.Helper import org.junit.Assert