Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization #255

Open
wants to merge 105 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
de0938e
Added --read-write switch
GreyCat Mar 24, 2017
d24a36d
JavaMain: ensure that exceptions are really thrown, even on compile s…
GreyCat Mar 24, 2017
0b757b9
Started PoC seq writer support in JavaCompiler
GreyCat Mar 24, 2017
93b37a1
JavaCompiler: very basic bytes writing support
GreyCat Mar 24, 2017
75ec0c2
Allow simple serialization of FixedBytesType
GreyCat Mar 24, 2017
eed5d07
Translators: added strToBytes, implemented in Java translator
GreyCat Mar 24, 2017
5cf4edd
Added _i iteration number identifier
GreyCat Mar 24, 2017
4a3535f
JavaTranslator: added translation of `_i`
GreyCat Mar 24, 2017
568964d
ClassTypeProvider: use constants + added ITERATOR_I handling
GreyCat Mar 24, 2017
9e7bffa
Writing: added string handling, some repeat-expr handling, BytesEos h…
GreyCat Mar 24, 2017
8fd1002
Serialization: basic support for user types and BytesLimitType
GreyCat Mar 27, 2017
0d73de2
Merge branch 'master' into serialization
GreyCat Mar 27, 2017
ea06fec
Serialization: implemented unprocess and slightly better user type wr…
GreyCat Mar 27, 2017
9c1793e
AllocateIOLocalVar: Added allocation of fixed and growing IOs
GreyCat Mar 28, 2017
9f0e331
Serialization: implemented fixed-size preallocated IO buffers
GreyCat Mar 28, 2017
969401c
JavaCompiler: generate new Readable/Writable interface implements
GreyCat Mar 28, 2017
885469f
Serialization: more intricate process-on-top-of-user-type support
GreyCat Mar 28, 2017
0f3a2aa
JavaCompiler: implemented writing of repeat-eos
GreyCat Mar 29, 2017
e4a56f1
Serialization: implemented switch types support, reworked JavaCompile…
GreyCat Mar 29, 2017
44185e1
Added basic _check implementation, added checks for a proper number o…
GreyCat Mar 30, 2017
769dabc
Added String#to_b(encoding) and ByteArray#size methods + JavaTranslat…
GreyCat Mar 30, 2017
040b689
Added limited byte / string sizing checks
GreyCat Mar 30, 2017
28e8d06
Translators: added BytesType#first and #last, implemented for Java
GreyCat Mar 30, 2017
1b66897
GenericChecks: implemented tons of checks for BytesLimitType - bounda…
GreyCat Mar 30, 2017
7d2295f
Merge branch 'master' into serialization
GreyCat Apr 3, 2017
dd0880e
Merge branch 'master' into serialization
GreyCat Apr 4, 2017
d73ec6b
JavaCompiler: only use ReadOnly when _read is public, i.e. when debug…
GreyCat Apr 5, 2017
2081fb2
Merge branch 'master' into serialization
GreyCat Apr 7, 2017
7dee284
Merge branch 'master' into serialization
GreyCat Apr 27, 2017
75729f7
WIP
generalmimon Oct 27, 2019
6e6bdda
Merge branch 'master' into serialization
generalmimon Nov 3, 2019
9eb2ab5
Merge pull request #177 from generalmimon/serialization
GreyCat Nov 10, 2019
2e2e985
Stop generating empty constructor when autoRead
generalmimon Nov 16, 2019
e46cc95
Use common loop for all repetitions
generalmimon Nov 16, 2019
9d8f2d3
Merge pull request #182 from generalmimon/serialization-common-loop
GreyCat Dec 14, 2019
e4ad9aa
Revert "Stop generating empty constructor when autoRead"
generalmimon Dec 14, 2019
d8adcc5
Disable autoRead automatically in readWrite mode
generalmimon Feb 2, 2020
cfba0cc
Merge pull request #180 from generalmimon/serialization-autoread-empt…
GreyCat Feb 3, 2020
d26e37b
Extract changes from https://github.com/kaitai-io/kaitai_struct_compi…
generalmimon Sep 19, 2020
ead02a4
Merge tag '0.10' into serialization
generalmimon Aug 1, 2022
5c70d8f
Fix build errors after upgrading to the 0.10 codebase
generalmimon Aug 1, 2022
0867d51
Remove `FixedBytesType` as intended in the 0.9 `valid` design
generalmimon Aug 16, 2022
939cf98
Refactor EveryWriteIsExpression to use Ast.expr.InternalName
generalmimon Aug 28, 2022
83b1fa7
Delete unused attrFixedContentsParse (_io.ensure_fixed_contents())
generalmimon Sep 4, 2022
caea2b7
Fix writing of a field with `terminator` + `consume: false`
generalmimon Sep 4, 2022
c1d391a
Fix broken consistency check for repeated byte arrays
generalmimon Sep 5, 2022
43d044a
Java: fix bytesSubscript to give unsigned byte values (finally!)
generalmimon Sep 5, 2022
8404319
Drop `expr` argument of condIfFooter method
generalmimon Sep 8, 2022
2acf924
Java: include term if `include: true` && `terminator` == `pad-right`
generalmimon Sep 8, 2022
73b0347
Fix & add missing `terminator`/`pad-right` consistency checks
generalmimon Sep 10, 2022
d721d08
Reuse the byte array write method for strings
generalmimon Sep 11, 2022
50d6556
Add repeat-until last element check
generalmimon Sep 12, 2022
72ca925
Refactor access to the last array item in attrAssertUntilCond
generalmimon Sep 12, 2022
426a38d
Merge pull request #183 from generalmimon/serialization-repeat-until-…
generalmimon Sep 12, 2022
def6650
Extend repeat-until consistency check to all elements
generalmimon Sep 12, 2022
306bfb2
Add consistency check for *non-empty* `repeat: until` array
generalmimon Sep 12, 2022
849fc1c
Fix "Object cannot be converted to byte[]" errors in type switches
generalmimon Sep 13, 2022
74d553c
Fix locale-sensitive String#toUpperCase call in writeHeader
generalmimon Sep 14, 2022
604359d
Java: finally solve boxed numeric type casting issues consistently
generalmimon Sep 15, 2022
f8bb577
Add _invalidate*() for value and set*() for parse instances
generalmimon Sep 17, 2022
16374cc
Add _write*() and _check*() for parse instances
generalmimon Sep 17, 2022
070391c
Set write flags of parse instances at the beginning of `_write`
generalmimon Oct 28, 2022
9897818
_write(): use special loops for each repetition type again
generalmimon Oct 28, 2022
69e4a12
Java: make {_read,_write}{BE,LE}() `private` even if autoRead is off
generalmimon Oct 28, 2022
2710191
Fix instance write flags (previous attempt led to infinite recursion)
generalmimon Oct 28, 2022
7dce0c3
Rename _write{,LE,BE}() methods to _write_Seq{,LE,BE}()
generalmimon Oct 28, 2022
826b242
Rename {writeExprAsExpr=>itemExpr}(), move to EveryReadIsExpression
generalmimon Oct 29, 2022
ca012b6
Add _fetchInstances() method to recursively fetch parse instances
generalmimon Oct 29, 2022
3b08efe
Write substreams to parent only after all fields have been written
generalmimon Nov 26, 2022
544cad0
Add set{Inst}_ToWrite() setter to select what instances to write
generalmimon Nov 26, 2022
11da92f
Add support for writing substreams with `process` and/or `terminator`
generalmimon Dec 23, 2022
175c278
Fix handling `size-eos: true` with `terminator`/`pad-right`
generalmimon Dec 23, 2022
b5c2e92
Java: call writeBitsInt{Be,Le}(), disable calls to alignToByte()
generalmimon Dec 28, 2022
bda1842
Move consistency checks from _check() to _write() if needed
generalmimon Dec 31, 2022
a5dd1f9
Add a _write() check on EOF after a `size-eos: true` field
generalmimon Dec 31, 2022
ecb5757
Add a _write() check on EOF states of `repeat: eos`
generalmimon Dec 31, 2022
37f432b
Generate byte array checks for substreams in _write()
generalmimon Dec 31, 2022
4fdf21d
Add write support for `eos-error: false`
generalmimon Jan 1, 2023
a8e4c03
Convert Identifier to id in ConsistencyError using `humanReadable`
generalmimon Jan 1, 2023
08ac809
Remove unused `isRaw` parameter in `itemExpr` method
generalmimon Jan 1, 2023
cf26f3e
Generate checks for SwitchType as well
generalmimon Jan 1, 2023
37da6dd
Add checks for user `params`, set `io`/`io[]` params in _write()
generalmimon Jan 1, 2023
2accf38
Add checks for `_root` and `_parent` built-in parameters
generalmimon Jan 2, 2023
5afa962
Add `valid` checks as in _read() to _check()/_write()
generalmimon Jan 2, 2023
793f58b
Add necessary fixes after testing on https://github.com/kaitai-io/kai…
generalmimon Jan 3, 2023
533aaa8
Going forward, starting 0.11-SNAPSHOT
GreyCat Aug 1, 2022
52812f9
Fix superfluous footer in Lua, Perl, PHP, Python and Ruby
generalmimon Feb 14, 2023
203613b
Delete unused method attrWriteStreamToStream
generalmimon Feb 15, 2023
d1f16dd
Port serialization support to Python
generalmimon Feb 26, 2023
d986731
Fix Python 2 compatibility when creating a fixed stream
generalmimon Feb 26, 2023
fca43d9
Python: disable calls to alignToByte()
generalmimon Mar 6, 2023
e776c98
Python: use `self` as default `_root` only in top-level types
generalmimon Mar 7, 2023
00c831f
Add "implies --no-auto-read" to --read-write CLI option description
generalmimon Jul 27, 2023
f1dc857
Add "Java and Python only" to --read-write CLI option description
generalmimon Jul 27, 2023
952c89c
Merge branch 'master' into serialization
generalmimon Jul 31, 2023
9142a1b
Improve setting `zeroCopySubstream` to false in `readWrite` mode
generalmimon Aug 1, 2023
2eca3de
Bring back init of instance flags in non-`readWrite` mode (C++, C#)
generalmimon Aug 1, 2023
a477800
PythonCompiler: fix "{alignToByte => align_to_byte}()" in comment
generalmimon Aug 5, 2023
8b258e2
Remove alignToByte() insertion logic when writing
generalmimon Aug 5, 2023
cb0c1eb
Endianness.fromString(): revert incorrect `case {None => _}` change
generalmimon Aug 7, 2023
0179199
Stop using `_io` when throwing validation errors from _check()
generalmimon Sep 24, 2023
31f1359
Merge branch 'master' into serialization
generalmimon Oct 12, 2023
7d830fa
Fix Java 7 compat: add `final` in allocateIOFixed()
generalmimon Oct 13, 2023
dea74e1
Merge branch 'master' into serialization
generalmimon Oct 21, 2023
4066d1e
Merge branch 'master' into serialization
generalmimon Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion jvm/src/main/scala/io/kaitai/struct/JavaMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ object JavaMain {
}
}

opt[Unit]('w', "read-write") action { (x, c) =>
c.copy(runtime = c.runtime.copy(readWrite = true, autoRead = false))
} text("generate read-write support in classes (implies `--no-auto-read --zero-copy-substream false`, Java and Python only, default: read-only)")

opt[File]('d', "outdir") valueName("<directory>") action { (x, c) =>
c.copy(outDir = x)
} text("output directory (filenames will be auto-generated); on Unix-like shells, the short form `-d` requires arguments to be preceded by `--`")
Expand Down Expand Up @@ -172,7 +176,13 @@ object JavaMain {
version("version") text("output version information and exit")
}

parser.parse(args, CLIConfig())
parser.parse(args, CLIConfig()).map { c =>
if (c.runtime.readWrite) {
c.copy(runtime = c.runtime.copy(zeroCopySubstream = false))
} else {
c
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ class TranslatorSpec extends AnyFunSuite {
CppCompiler -> new CppTranslator(tp, new CppImportList(), new CppImportList(), RuntimeConfig()),
CSharpCompiler -> new CSharpTranslator(tp, new ImportList()),
GoCompiler -> new GoTranslator(goOutput, tp, new ImportList()),
JavaCompiler -> new JavaTranslator(tp, new ImportList()),
JavaCompiler -> new JavaTranslator(tp, new ImportList(), RuntimeConfig()),
JavaScriptCompiler -> new JavaScriptTranslator(tp),
LuaCompiler -> new LuaTranslator(tp, new ImportList()),
PerlCompiler -> new PerlTranslator(tp, new ImportList()),
Expand Down
131 changes: 123 additions & 8 deletions shared/src/main/scala/io/kaitai/struct/ClassCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ class ClassCompiler(
// Read method(s)
compileEagerRead(curClass.seq, curClass.meta.endian)

compileFetchInstancesProc(curClass.seq ++ curClass.instances.values.collect {
case inst: AttrLikeSpec => inst
})

if (config.readWrite) {
compileWrite(curClass.seq, curClass.instances, curClass.meta.endian)
compileCheck(curClass.seq)
}

// Destructor
compileDestructor(curClass)

Expand Down Expand Up @@ -132,6 +141,15 @@ class ClassCompiler(
)
compileInit(curClass)
curClass.instances.foreach { case (instName, _) => lang.instanceClear(instName) }
if (config.readWrite) {
curClass.instances.foreach { case (instName, instSpec) =>
instSpec match {
case _: ParseInstanceSpec =>
lang.instanceWriteFlagInit(instName)
case _: ValueInstanceSpec => // do nothing
}
}
}
if (lang.config.autoRead)
lang.runRead(curClass.name)
lang.classConstructorFooter
Expand Down Expand Up @@ -217,6 +235,9 @@ class ClassCompiler(
attr.isNullable
}
lang.attributeReader(attr.id, attr.dataTypeComposite, isNullable)
if (config.readWrite) {
lang.attributeSetter(attr.id, attr.dataTypeComposite, isNullable)
}
}
}

Expand All @@ -236,25 +257,45 @@ class ClassCompiler(
def compileEagerRead(seq: List[AttrSpec], endian: Option[Endianness]): Unit = {
endian match {
case None | Some(_: FixedEndian) =>
compileSeqProc(seq, None)
compileSeqReadProc(seq, None)
case Some(ce: CalcEndian) =>
lang.readHeader(None, false)
compileCalcEndian(ce)
lang.runReadCalc()
lang.readFooter()

compileSeqProc(seq, Some(LittleEndian))
compileSeqProc(seq, Some(BigEndian))
compileSeqReadProc(seq, Some(LittleEndian))
compileSeqReadProc(seq, Some(BigEndian))
case Some(InheritedEndian) =>
lang.readHeader(None, false)
lang.runReadCalc()
lang.readFooter()

compileSeqProc(seq, Some(LittleEndian))
compileSeqProc(seq, Some(BigEndian))
compileSeqReadProc(seq, Some(LittleEndian))
compileSeqReadProc(seq, Some(BigEndian))
}
}

def compileWrite(seq: List[AttrSpec], instances: Map[InstanceIdentifier, InstanceSpec], endian: Option[Endianness]): Unit = {
endian match {
case None | Some(_: FixedEndian) =>
compileSeqWriteProc(seq, instances, None)
case Some(CalcEndian(_, _)) | Some(InheritedEndian) =>
lang.writeHeader(None, false)
lang.runWriteCalc()
lang.writeFooter()

compileSeqWriteProc(seq, instances, Some(LittleEndian))
compileSeqWriteProc(seq, instances, Some(BigEndian))
}
}

def compileCheck(seq: List[AttrSpec]): Unit = {
lang.checkHeader()
compileSeqCheck(seq)
lang.checkFooter()
}

val IS_LE_ID = SpecialIdentifier("_is_le")

/**
Expand All @@ -276,18 +317,31 @@ class ClassCompiler(
* @param seq sequence of attributes
* @param defEndian default endianness
*/
def compileSeqProc(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
def compileSeqReadProc(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
lang.readHeader(defEndian, seq.isEmpty)
compileSeq(seq, defEndian)
compileSeqRead(seq, defEndian)
lang.readFooter()
}

def compileFetchInstancesProc(attrs: List[AttrLikeSpec]) = {
lang.fetchInstancesHeader()
compileFetchInstances(attrs)
lang.fetchInstancesFooter()
}

def compileSeqWriteProc(seq: List[AttrSpec], instances: Map[InstanceIdentifier, InstanceSpec], defEndian: Option[FixedEndian]) = {
lang.writeHeader(defEndian, !instances.values.exists(i => i.isInstanceOf[ParseInstanceSpec]) && seq.isEmpty)
compileSetInstanceWriteFlags(instances)
compileSeqWrite(seq, defEndian)
lang.writeFooter()
}

/**
* Compiles seq reading method body (only reading statements).
* @param seq sequence of attributes
* @param defEndian default endianness
*/
def compileSeq(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
def compileSeqRead(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
var wasUnaligned = false
seq.foreach { (attr) =>
val nowUnaligned = isUnalignedBits(attr.dataType)
Expand All @@ -298,6 +352,39 @@ class ClassCompiler(
}
}

def compileFetchInstances(attrs: List[AttrLikeSpec]): Unit = {
attrs.foreach { (attr) =>
lang.attrFetchInstances(attr, attr.id)
}
}

def compileSetInstanceWriteFlags(instances: Map[InstanceIdentifier, InstanceSpec]) = {
instances.foreach { case (instName, instSpec) =>
instSpec match {
case _: ParseInstanceSpec =>
lang.instanceSetWriteFlag(instName)
case _: ValueInstanceSpec => // do nothing
}
}
}

def compileSeqWrite(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
var wasUnaligned = false
seq.foreach { (attr) =>
val nowUnaligned = isUnalignedBits(attr.dataType)
if (wasUnaligned && !nowUnaligned)
lang.alignToByte(lang.normalIO)
lang.attrWrite(attr, attr.id, defEndian)
wasUnaligned = nowUnaligned
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to avoid using var and imperative. foldLeft seems to do the trick here, cleanly conveying the semantics and allowing e.g. advanced parallelization of such loops:

Suggested change
var wasUnaligned = false
seq.foreach { (attr) =>
val nowUnaligned = isUnalignedBits(attr.dataType)
if (wasUnaligned && !nowUnaligned)
lang.alignToByte(lang.normalIO)
lang.attrWrite(attr, attr.id, defEndian)
wasUnaligned = nowUnaligned
}
seq.foldLeft(false) { case (wasUnaligned, attr) =>
val nowUnaligned = isUnalignedBits(attr.dataType)
if (wasUnaligned && !nowUnaligned)
lang.alignToByte(lang.normalIO)
lang.attrWrite(attr, attr.id, defEndian)
nowUnaligned
}

Copy link
Member

@generalmimon generalmimon Aug 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, one of the major changes in Java and Python runtime libraries related to serialization was that all alignToByte insertion logic is handled in the runtime libraries themselves and the alignToByte() call generation is disabled in the compiler for both Java and Python:

// NOTE: the compiler does not need to output alignToByte() calls for Java anymore, since the byte
// alignment is handled by the runtime library since commit
// https://github.com/kaitai-io/kaitai_struct_java_runtime/commit/1bc75aa91199588a1cb12a5a1c672b80b66619ac
override def alignToByte(io: String): Unit = {}

// NOTE: the compiler does not need to output alignToByte() calls for Python anymore, since the byte
// alignment is handled by the runtime library since commit
// https://github.com/kaitai-io/kaitai_struct_python_runtime/commit/1cb84b84d358e1cdffe35845d1e6688bff923952
override def alignToByte(io: String): Unit = {}

(and now I see a small mistake in the comment in PythonCompiler - technically it should be "the compiler does not need to output alignToByte() align_to_byte()" per Python naming)


So I guess the piece of code you're reviewing can be simplified to just lang.attrWrite(attr, attr.id, defEndian).

}

def compileSeqCheck(seq: List[AttrSpec]) = {
seq.foreach { (attr) =>
lang.attrCheck(attr, attr.id)
}
}

/**
* Compiles all enums specifications for a given type.
* @param curClass current type to generate code for
Expand Down Expand Up @@ -329,6 +416,12 @@ class ClassCompiler(
lang.instanceHeader(className, instName, dataType, instSpec.isNullable)
if (lang.innerDocstrings)
compileInstanceDoc(instName, instSpec)
if (config.readWrite)
instSpec match {
case _: ParseInstanceSpec =>
lang.instanceCheckWriteFlagAndWrite(instName)
case _: ValueInstanceSpec => // do nothing
}
lang.instanceCheckCacheAndReturn(instName, dataType)

instSpec match {
Expand All @@ -343,6 +436,22 @@ class ClassCompiler(

lang.instanceReturn(instName, dataType)
lang.instanceFooter

if (config.readWrite)
instSpec match {
case pi: ParseInstanceSpec =>
lang.attributeSetter(instName, dataType, instSpec.isNullable)
lang.instanceToWriteSetter(instName)
lang.writeInstanceHeader(instName)
lang.attrWrite(pi, instName, endian)
lang.writeInstanceFooter

lang.checkInstanceHeader(instName)
lang.attrCheck(pi, instName)
lang.checkInstanceFooter
case _: ValueInstanceSpec =>
lang.instanceInvalidate(instName)
}
}

def compileInstanceDeclaration(instName: InstanceIdentifier, instSpec: InstanceSpec): Unit = {
Expand All @@ -355,6 +464,12 @@ class ClassCompiler(
instSpec.isNullable
}
lang.instanceDeclaration(instName, instSpec.dataTypeComposite, isNullable)
if (config.readWrite)
instSpec match {
case _: ParseInstanceSpec =>
lang.instanceWriteFlagDeclaration(instName)
case _: ValueInstanceSpec => // do nothing
}
}

def compileEnum(curClass: ClassSpec, enumColl: EnumSpec): Unit =
Expand Down
27 changes: 27 additions & 0 deletions shared/src/main/scala/io/kaitai/struct/ClassTypeProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,33 @@ class ClassTypeProvider(classSpecs: ClassSpecs, var topClass: ClassSpec) extends
case NamedIdentifier(name) => return determineType(inClass, name)
case InstanceIdentifier(name) => return determineType(inClass, name)
case SpecialIdentifier(name) => return determineType(inClass, name)
case RawIdentifier(innerId) => {
val innerType = determineType(innerId)
val (isArray, itemType: DataType) = innerType match {
case at: ArrayType => (true, at.elType)
case t => (false, t)
}
val singleType: DataType = itemType match {
case st: SwitchType => st.cases.collectFirst {
case (_, caseType)
if caseType.isInstanceOf[BytesType]
|| caseType.isInstanceOf[UserTypeFromBytes] => caseType
}.get
case t => t
}
/** see [[languages.components.ExtraAttrs$]] for possible types */
val bytesType = singleType match {
case bt: BytesType => bt
case utb: UserTypeFromBytes => utb.bytes
}
return if (isArray) ArrayTypeInStream(bytesType) else bytesType
}
case OuterSizeIdentifier(innerId) =>
val singleType = CalcIntType
return if (determineType(innerId).isInstanceOf[ArrayType]) ArrayTypeInStream(singleType) else singleType
case InnerSizeIdentifier(innerId) =>
val singleType = CalcIntType
return if (determineType(innerId).isInstanceOf[ArrayType]) ArrayTypeInStream(singleType) else singleType
case _ => // do nothing
}
throw new FieldNotFoundError(attrId.humanReadable, inClass)
Expand Down
4 changes: 2 additions & 2 deletions shared/src/main/scala/io/kaitai/struct/DocClassCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class DocClassCompiler(classSpecs: ClassSpecs, topClass: ClassSpec) ext
classHeader(curClass)

// Sequence
compileSeq(curClass)
compileSeqRead(curClass)

// Instances
curClass.instances.foreach { case (_, instSpec) =>
Expand All @@ -58,7 +58,7 @@ abstract class DocClassCompiler(classSpecs: ClassSpecs, topClass: ClassSpec) ext
classFooter(curClass)
}

def compileSeq(curClass: ClassSpec): Unit = {
def compileSeqRead(curClass: ClassSpec): Unit = {
seqHeader(curClass)

CalculateSeqSizes.forEachSeqAttr(curClass, (attr, seqPos, sizeElement, sizeContainer) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class GraphvizClassCompiler(classSpecs: ClassSpecs, topClass: ClassSpec) extends
out.puts

// Sequence
compileSeq(className, curClass)
compileSeqRead(className, curClass)

curClass.instances.foreach { case (instName, instSpec) =>
instSpec match {
Expand All @@ -84,7 +84,7 @@ class GraphvizClassCompiler(classSpecs: ClassSpecs, topClass: ClassSpec) extends
out.puts("}")
}

def compileSeq(className: List[String], curClass: ClassSpec): Unit = {
def compileSeqRead(className: List[String], curClass: ClassSpec): Unit = {
tableStart(className, "seq")

CalculateSeqSizes.forEachSeqAttr(curClass, (attr, seqPos, _, _) => {
Expand Down
15 changes: 7 additions & 8 deletions shared/src/main/scala/io/kaitai/struct/NimClassCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,25 @@ class NimClassCompiler(
override def compileEagerRead(seq: List[AttrSpec], endian: Option[Endianness]): Unit = {
endian match {
case None | Some(_: FixedEndian) =>
compileSeqProc(seq, None)
compileSeqReadProc(seq, None)
case Some(ce: CalcEndian) =>
compileSeqProc(seq, Some(LittleEndian))
compileSeqProc(seq, Some(BigEndian))
compileSeqReadProc(seq, Some(LittleEndian))
compileSeqReadProc(seq, Some(BigEndian))
lang.readHeader(None, false)
compileCalcEndian(ce)
lang.runReadCalc()
lang.readFooter()
case Some(InheritedEndian) =>
compileSeqProc(seq, Some(LittleEndian))
compileSeqProc(seq, Some(BigEndian))
compileSeqReadProc(seq, Some(LittleEndian))
compileSeqReadProc(seq, Some(BigEndian))
lang.readHeader(None, false)
lang.runReadCalc()
lang.readFooter()
}
}

// Must override just to add attribute docstrings
override def compileSeq(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
override def compileSeqRead(seq: List[AttrSpec], defEndian: Option[FixedEndian]) = {
var wasUnaligned = false
seq.foreach { (attr) =>
val nowUnaligned = isUnalignedBits(attr.dataType)
Expand Down Expand Up @@ -153,7 +153,7 @@ class NimClassCompiler(
def compileTypesRec(curClass: ClassSpec): Unit = {
curClass.types.foreach { case (_, subClass) => compileTypes(subClass) }
}

// def compileEnumConstants(curClass: ClassSpec): Unit = {
// provider.nowClass = curClass
// curClass.enums.foreach { case(_, enumColl) => {
Expand Down Expand Up @@ -203,4 +203,3 @@ class NimClassCompiler(
}

}

1 change: 1 addition & 0 deletions shared/src/main/scala/io/kaitai/struct/RuntimeConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ case class RuntimeConfig(
readStoresPos: Boolean = false,
opaqueTypes: Boolean = false,
zeroCopySubstream: Boolean = true,
readWrite: Boolean = false,
cppConfig: CppRuntimeConfig = CppRuntimeConfig(),
goPackage: String = "",
java: JavaRuntimeConfig = JavaRuntimeConfig(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class RustClassCompiler(

lang.readHeader(defEndian, false)

compileSeq(curClass.seq, defEndian)
compileSeqRead(curClass.seq, defEndian)
lang.classConstructorFooter
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ object Endianness {
def fromString(s: Option[String], defaultEndian: Option[Endianness], dt: String, path: List[String]): Option[FixedEndian] = s match {
case Some("le") => Some(LittleEndian)
case Some("be") => Some(BigEndian)
case None =>
case _ =>
generalmimon marked this conversation as resolved.
Show resolved Hide resolved
defaultEndian match {
case Some(e: FixedEndian) => Some(e)
case Some(_: CalcEndian) | Some(InheritedEndian) => None // to be overridden during compile
Expand Down
Loading