Skip to content

Commit

Permalink
Add tests for sizeof calculator
Browse files Browse the repository at this point in the history
Fow now only very basic tests is implemented - only size of built-in types is tested
  • Loading branch information
Mingun committed Sep 12, 2023
1 parent ff55012 commit 67ad00a
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 2 deletions.
159 changes: 159 additions & 0 deletions jvm/src/test/scala/io/kaitai/struct/CalculateSeqSizes$Test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package io.kaitai.struct

import io.kaitai.struct.datatype.{BigEndian, BigBitEndian}
import io.kaitai.struct.datatype.DataType
import io.kaitai.struct.datatype.DataType._
import io.kaitai.struct.exprlang.Ast
import io.kaitai.struct.format.{DynamicSized, FixedSized, MetaSpec, Sized, YamlAttrArgs}
import io.kaitai.struct.precompile.CalculateSeqSizes

import org.scalatest.FunSpec
import org.scalatest.Matchers._

class CalculateSeqSizes$Test extends FunSpec {
private def parse(
typeName: Option[String],
size: Option[Int],
terminator: Option[Int],
contents: Option[Array[Byte]],
): DataType = {
DataType.fromYaml(
typeName,
List(),
MetaSpec(
List(), // path
false, // isOpaque
None, // id
Some(BigEndian), // endian
Some(BigBitEndian), // bitEndian
Some("utf-8"), // encoding
false, // forceDebug
None, // opaqueTypes
List() // imports
),
YamlAttrArgs(
size.map(s => Ast.expr.IntNum(s)),
false,// sizeEos
None, // encoding
terminator,
false,// include
false,// consume
false,// eosError
None, // padRight
contents,
None, // enumRef
None, // parent
None, // process
)
)
}
private def sizeof(
typeName: Option[String],
size: Option[Int],
terminator: Option[Int],
contents: Option[Array[Byte]],
): Sized = {
CalculateSeqSizes.dataTypeBitsSize(parse(typeName, size, terminator, contents))
}
/** Helper for testing built-in types */
private def sizeof(typeName: String): Sized = {
sizeof(Some(typeName), None, None, None)
}
/** Helper for testing unsized built-in types which requires explicit size boundary. */
private def sizeof(typeName: String, terminator: Int): Sized = {
sizeof(Some(typeName), None, Some(terminator), None)
}
/** Helper for testing the unnamed "bytes" built-in type defined implicitly via `size` key. */
private def sizeof(size: Int): Sized = {
sizeof(None, Some(size), None, None)
}
/** Helper for testing the `contents` size. */
private def sizeof(contents: Array[Byte]): Sized = {
sizeof(None, None, None, Some(contents))
}

describe("CalculateSeqSizes") {
it("built-in types has correct size") {
sizeof("s1") should be (FixedSized( 8))
sizeof("s2") should be (FixedSized(16))
sizeof("s4") should be (FixedSized(32))
sizeof("s8") should be (FixedSized(64))

sizeof("s2be") should be (FixedSized(16))
sizeof("s4be") should be (FixedSized(32))
sizeof("s8be") should be (FixedSized(64))

sizeof("s2le") should be (FixedSized(16))
sizeof("s4le") should be (FixedSized(32))
sizeof("s8le") should be (FixedSized(64))

//-----------------------------------------------------------------------

sizeof("u1") should be (FixedSized( 8))
sizeof("u2") should be (FixedSized(16))
sizeof("u4") should be (FixedSized(32))
sizeof("u8") should be (FixedSized(64))

sizeof("u2be") should be (FixedSized(16))
sizeof("u4be") should be (FixedSized(32))
sizeof("u8be") should be (FixedSized(64))

sizeof("u2le") should be (FixedSized(16))
sizeof("u4le") should be (FixedSized(32))
sizeof("u8le") should be (FixedSized(64))

//-----------------------------------------------------------------------

sizeof("f4") should be (FixedSized(32))
sizeof("f8") should be (FixedSized(64))

sizeof("f4be") should be (FixedSized(32))
sizeof("f8be") should be (FixedSized(64))

sizeof("f4le") should be (FixedSized(32))
sizeof("f8le") should be (FixedSized(64))

//-----------------------------------------------------------------------

sizeof("b1") should be (FixedSized(1))
sizeof("b2") should be (FixedSized(2))
sizeof("b3") should be (FixedSized(3))
sizeof("b4") should be (FixedSized(4))
sizeof("b5") should be (FixedSized(5))
sizeof("b6") should be (FixedSized(6))
sizeof("b7") should be (FixedSized(7))
sizeof("b8") should be (FixedSized(8))
sizeof("b9") should be (FixedSized(9))

sizeof("b2be") should be (FixedSized(2))
sizeof("b3be") should be (FixedSized(3))
sizeof("b4be") should be (FixedSized(4))
sizeof("b5be") should be (FixedSized(5))
sizeof("b6be") should be (FixedSized(6))
sizeof("b7be") should be (FixedSized(7))
sizeof("b8be") should be (FixedSized(8))
sizeof("b9be") should be (FixedSized(9))

sizeof("b2le") should be (FixedSized(2))
sizeof("b3le") should be (FixedSized(3))
sizeof("b4le") should be (FixedSized(4))
sizeof("b5le") should be (FixedSized(5))
sizeof("b6le") should be (FixedSized(6))
sizeof("b7le") should be (FixedSized(7))
sizeof("b8le") should be (FixedSized(8))
sizeof("b9le") should be (FixedSized(9))

//-----------------------------------------------------------------------

sizeof("str", 0) should be (DynamicSized)
sizeof("strz" ) should be (DynamicSized)

//TODO: Uncomment when https://github.com/kaitai-io/kaitai_struct/issues/799
// will be implemented
// sizeof("bytes") should be (DynamicSized)
sizeof(10) should be (FixedSized(10*8))// size: 10

sizeof("abcdef".getBytes()) should be (FixedSized(6*8))// content: 'abcdef'
}
}
}
11 changes: 9 additions & 2 deletions shared/src/main/scala/io/kaitai/struct/datatype/DataType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -483,19 +483,26 @@ object DataType {
private val ReFloatType = """f(4|8)(le|be)?""".r
private val ReBitType = """b(\d+)(le|be)?""".r

/**
* @param dto Content of the `type` key or the case variant in case of `switch-on` type
* @param path YAML path to the type definition, for use in errors
* @param metaDef Default properties of the attribute from `meta` section of type definition
* @param arg Other properties of the attribute in the KSY definition, such as `size`,
`content`, `terminator`, etc.
*/
def fromYaml(
dto: Option[String],
path: List[String],
metaDef: MetaSpec,
arg: YamlAttrArgs
): DataType = {
val r = dto match {
case None =>
case None => // `type:` key is missing in the KSY definition
arg.contents match {
case Some(c) => BytesLimitType(Ast.expr.IntNum(c.length), None, false, None, arg.process)
case _ => arg.getByteArrayType(path)
}
case Some(dt) => dt match {
case Some(dt) => dt match {// type: dt
case "u1" => Int1Type(false)
case "s1" => Int1Type(true)
case ReIntType(signStr, widthStr, endianStr) =>
Expand Down
19 changes: 19 additions & 0 deletions shared/src/main/scala/io/kaitai/struct/format/ClassSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,29 @@ case object GenericStructClassSpec extends ClassSpecLike {
override def toDataType: DataType = CalcKaitaiStructType()
}

/**
* Type that represent result of the `_sizeof` special property and `sizeof<>`
* meta-function.
*/
sealed trait Sized
/**
* The size of type have no constant value. The examples is built-in unsized
* types: `str`, `strz`, and `bytes`. Those types has no natural size in contrary
* to the sized types, such as `u1` or `f4be`.
*/
case object DynamicSized extends Sized
/**
* A marker object that indicates that size of the type has not been yet calculated
* and calculation should be performed when size will be requested.
*/
case object NotCalculatedSized extends Sized
/**
* A marker object that indicates that calculation of the size of the type in the
* progress. If that object will be seen during calculation process it is mean that
* type is defined recursively.
*/
case object StartedCalculationSized extends Sized
/** The size of type is `n` bytes. */
case class FixedSized(n: Int) extends Sized

case class ClassSpec(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ object CalculateSeqSizes {
}
}

/**
* Calculates size of the specified class instance for use in the `_sizeof`
* special property and `sizeof<>` meta-function.
*
* @param curClass
*/
def getSeqSize(curClass: ClassSpec): Sized = {
curClass.seqSize match {
case DynamicSized | _: FixedSized =>
Expand Down

0 comments on commit 67ad00a

Please sign in to comment.