Skip to content

Commit

Permalink
C++: implement doByteArrayNonLiteral - create array from expression o…
Browse files Browse the repository at this point in the history
…f `bytes` type

Expressions of this type are created using:
- omitting the `type:` field in attributes and parse instances
- declaring parameters with `type: bytes`
- using `.as<bytes>` cast

Ghostly fixes test
```
[info]     - cpp_stl:[0 + 1, 5].as<bytes> *** FAILED ***
[info]       scala.NotImplementedError: an implementation is missing
[info]       at scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
[info]       at io.kaitai.struct.translators.BaseTranslator.doByteArrayNonLiteral(BaseTranslator.scala:179)
[info]       at io.kaitai.struct.translators.BaseTranslator.doByteArrayNonLiteral(BaseTranslator.scala:28)
[info]       at io.kaitai.struct.translators.CommonArraysAndCast.doByteArray(CommonArraysAndCast.scala:85)
[info]       at io.kaitai.struct.translators.CommonArraysAndCast.doCastOrArray(CommonArraysAndCast.scala:62)
[info]       at io.kaitai.struct.translators.CommonArraysAndCast.doCastOrArray$(CommonArraysAndCast.scala:53)
[info]       at io.kaitai.struct.translators.BaseTranslator.doCastOrArray(BaseTranslator.scala:28)
[info]       at io.kaitai.struct.translators.BaseTranslator.translate(BaseTranslator.scala:147)
[info]       at io.kaitai.struct.translators.AbstractTranslator.translate(AbstractTranslator.scala:25)
[info]       at io.kaitai.struct.translators.AbstractTranslator.translate$(AbstractTranslator.scala:25)
[info]       ...
```
(actually, test is failing because option `useListInitializers` in C++ backend is not set in tests
and code generation without it is not unimplemented right now)

Co-authored-by: Petr Pučil <[email protected]>
  • Loading branch information
Mingun and generalmimon committed Mar 30, 2024
1 parent a4cd503 commit 3f574b5
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ class TranslatorSpec extends AnyFunSpec {
describe("to do type enforcement") {
// type enforcement: casting to non-literal byte array
full("[0 + 1, 5].as<bytes>", CalcIntType, CalcBytesType, ResultMap(
CppCompiler -> "???",
CppCompiler -> "std::string({static_cast<char>(0 + 1), static_cast<char>(5)})",
CSharpCompiler -> "new byte[] { 0 + 1, 5 }",
GoCompiler -> "[]uint8{0 + 1, 5}",
JavaCompiler -> "new byte[] { 0 + 1, 5 }",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,22 @@ class CppTranslator(provider: TypeProvider, importListSrc: CppImportList, import
// TODO: C++14
}
} else {
throw new RuntimeException("C++ literal arrays are not implemented yet")
throw new RuntimeException("literal arrays are not implemented yet in C++98")
}
}

override def doByteArrayLiteral(arr: Seq[Byte]): String =
"std::string(\"" + Utils.hexEscapeByteArray(arr) + "\", " + arr.length + ")"
override def doByteArrayNonLiteral(values: Seq[Ast.expr]): String = {
// It is assumed that every expression produces integer in the range [0; 255]
if (config.cppConfig.useListInitializers) {
"std::string({" + values.map(value => s"static_cast<char>(${translate(value)})").mkString(", ") + "})"
} else {
// TODO: We need to produce an expression, but this is possible only with initializer lists
// or variadic templates (if use a helper function) which both available only since C++11
throw new RuntimeException("literal arrays are not implemented yet in C++98")
}
}

override def genericBinOp(left: Ast.expr, op: Ast.operator, right: Ast.expr, extPrec: Int) = {
(detectType(left), detectType(right), op) match {
Expand Down

0 comments on commit 3f574b5

Please sign in to comment.