From b0c2a5d7abab39924e2bf0035c76d7ed4096eace Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 18 Mar 2024 20:28:07 +0500 Subject: [PATCH] C++: implement doByteArrayNonLiteral - create array from expression of `bytes` type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expressions of this type are created using: - omitting the `type:` field in attributes and parse instances - declaring parameters with `type: bytes` - using `.as` cast Ghostly fixes test ``` [info] - cpp_stl:[0 + 1, 5].as *** 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 --- .../kaitai/struct/translators/TranslatorSpec.scala | 2 +- .../io/kaitai/struct/translators/CppTranslator.scala | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jvm/src/test/scala/io/kaitai/struct/translators/TranslatorSpec.scala b/jvm/src/test/scala/io/kaitai/struct/translators/TranslatorSpec.scala index 094ea3e23..ce95ae209 100644 --- a/jvm/src/test/scala/io/kaitai/struct/translators/TranslatorSpec.scala +++ b/jvm/src/test/scala/io/kaitai/struct/translators/TranslatorSpec.scala @@ -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", CalcIntType, CalcBytesType, ResultMap( - CppCompiler -> "???", + CppCompiler -> "std::string({static_cast(0 + 1), static_cast(5)})", CSharpCompiler -> "new byte[] { 0 + 1, 5 }", GoCompiler -> "[]uint8{0 + 1, 5}", JavaCompiler -> "new byte[] { 0 + 1, 5 }", diff --git a/shared/src/main/scala/io/kaitai/struct/translators/CppTranslator.scala b/shared/src/main/scala/io/kaitai/struct/translators/CppTranslator.scala index b5686af2a..fb6fcd95d 100644 --- a/shared/src/main/scala/io/kaitai/struct/translators/CppTranslator.scala +++ b/shared/src/main/scala/io/kaitai/struct/translators/CppTranslator.scala @@ -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(${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 byte 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 {