diff --git a/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala b/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala index 931286b6e..f7e690ad0 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/components/CommonReads.scala @@ -1,6 +1,7 @@ package io.kaitai.struct.languages.components import io.kaitai.struct.datatype._ +import io.kaitai.struct.datatype.DataType.{ArrayTypeInStream, BytesType} import io.kaitai.struct.exprlang.Ast import io.kaitai.struct.format._ @@ -104,4 +105,38 @@ trait CommonReads extends LanguageCompiler { */ def attrValidateAll(attr: AttrLikeSpec) = attr.valid.foreach(valid => attrValidate(attr.id, attr, valid)) + + /** + * Creates a substream by reading bytes that will comprise the stream first into a buffer in + * memory, and then wrapping that buffer as a new stream. + * @param id identifier of a member that this stream is for + * @param byteType underlying bytes type + * @param io parent stream to derive substream from + * @param rep repeat specification for underlying bytes type + * @param defEndian default endianness specification + * @return string reference to a freshly created substream + */ + def createSubstreamBuffered( + id: Identifier, + byteType: BytesType, + io: String, + rep: RepeatSpec, + defEndian: Option[FixedEndian] + ): String = { + val rawId = RawIdentifier(id) + + attrParse2(rawId, byteType, io, rep, true, defEndian) + + val extraType = rep match { + case NoRepeat => byteType + case _ => ArrayTypeInStream(byteType) + } + + this match { + case thisStore: AllocateAndStoreIO => + thisStore.allocateIO(rawId, rep) + case thisLocal: AllocateIOLocalVar => + thisLocal.allocateIO(rawId, rep) + } + } } diff --git a/shared/src/main/scala/io/kaitai/struct/languages/components/EveryReadIsExpression.scala b/shared/src/main/scala/io/kaitai/struct/languages/components/EveryReadIsExpression.scala index a350c52c3..2778be82f 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/components/EveryReadIsExpression.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/components/EveryReadIsExpression.scala @@ -105,7 +105,10 @@ trait EveryReadIsExpression case knownSizeType: UserTypeFromBytes => // we have a fixed buffer, thus we shall create separate IO for it createSubstream(id, knownSizeType.bytes, io, rep, defEndian) - case _: UserTypeInstream => + case knownSizeType: CalcUserTypeFromBytes => + // we have a fixed buffer, thus we shall create separate IO for it + createSubstream(id, knownSizeType.bytes, io, rep, defEndian) + case _: UserTypeInstream | _: CalcUserType => // no fixed buffer, just use regular IO io } @@ -171,33 +174,6 @@ trait EveryReadIsExpression def createSubstreamFixedSize(id: Identifier, blt: BytesLimitType, io: String, rep: RepeatSpec, defEndian: Option[FixedEndian]): String = createSubstreamBuffered(id, blt, io, rep, defEndian) - /** - * Creates a substream by reading bytes that will comprise the stream first into a buffer in - * memory, and then wrapping that buffer as a new stream. - * @param id identifier of a member that this stream is for - * @param byteType underlying bytes type - * @param io parent stream to derive substream from - * @param rep repeat specification for underlying bytes type - * @param defEndian default endianness specification - * @return string reference to a freshly created substream - */ - def createSubstreamBuffered(id: Identifier, byteType: BytesType, io: String, rep: RepeatSpec, defEndian: Option[FixedEndian]): String = { - val rawId = RawIdentifier(id) - - attrParse2(rawId, byteType, io, rep, true, defEndian) - - val extraType = rep match { - case NoRepeat => byteType - case _ => ArrayTypeInStream(byteType) - } - - this match { - case thisStore: AllocateAndStoreIO => - thisStore.allocateIO(rawId, rep) - case thisLocal: AllocateIOLocalVar => - thisLocal.allocateIO(rawId, rep) - } - } def attrSwitchTypeParse( id: Identifier, diff --git a/shared/src/main/scala/io/kaitai/struct/languages/components/GoReads.scala b/shared/src/main/scala/io/kaitai/struct/languages/components/GoReads.scala index 600d0cb28..af8246809 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/components/GoReads.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/components/GoReads.scala @@ -112,24 +112,10 @@ trait GoReads extends CommonReads with ObjectOrientedLanguage with GoSwitchOps { def attrUserTypeParse(id: Identifier, dataType: UserType, io: String, rep: RepeatSpec, defEndian: Option[FixedEndian]): Unit = { val newIO = dataType match { case knownSizeType: UserTypeFromBytes => - // we have a fixed buffer, thus we shall create separate IO for it - val rawId = RawIdentifier(id) - val byteType = knownSizeType.bytes - - attrParse2(rawId, byteType, io, rep, true, defEndian) - - val extraType = rep match { - case NoRepeat => byteType - case _ => ArrayTypeInStream(byteType) - } - - this match { - case thisStore: AllocateAndStoreIO => - thisStore.allocateIO(rawId, rep) - case thisLocal: AllocateIOLocalVar => - thisLocal.allocateIO(rawId, rep) - } - case _: UserTypeInstream => + createSubstreamBuffered(id, knownSizeType.bytes, io, rep, defEndian) + case knownSizeType: CalcUserTypeFromBytes => + createSubstreamBuffered(id, knownSizeType.bytes, io, rep, defEndian) + case _: UserTypeInstream | _: CalcUserType => // no fixed buffer, just use regular IO io }