Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pfroud/class-of-null-value' wit…
Browse files Browse the repository at this point in the history
…h minor tweaks

Add some comments and improve some names
  • Loading branch information
Mingun committed Jun 7, 2022
2 parents 926dc20 + 8dd6d8a commit 664ad05
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/main/java/ru/mingun/kaitai/struct/tree/ChunkNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public abstract class ChunkNode extends ValueNode {
*
* @param name Name of field, under which this field arrives
* @param value Value of object
* @param valueClass Static class of the {@code value}. This is not necessary a runtime class of a
* value, but {@code value} is an instance of this class
* @param span Space that node is occupied in a stream
* @param isSequential If {@code true}, field declared in the {@code seq} section of the type,
* otherwise it is declared in the {@code instances} section
Expand All @@ -73,9 +75,9 @@ public abstract class ChunkNode extends ValueNode {
* @throws ReflectiveOperationException If {@code value} is {@link KaitaiStruct}
* and it was compiled without debug info (which includes position information)
*/
protected ChunkNode create(String name, Object value, Span span, boolean isSequential) throws ReflectiveOperationException {
protected ChunkNode create(String name, Object value, Class<?> valueClass, Span span, boolean isSequential) throws ReflectiveOperationException {
return value instanceof KaitaiStruct
? new StructNode(name, (KaitaiStruct)value, this, span, isSequential)
: new SimpleNode(name, value, this, span, isSequential);
: new SimpleNode(name, value, valueClass, this, span, isSequential);
}
}
8 changes: 6 additions & 2 deletions src/main/java/ru/mingun/kaitai/struct/tree/ListNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,25 @@
*/
public class ListNode extends ChunkNode {
private final List<?> value;
/** The type of elements of the {@code value}. */
private final Class<?> elementClass;

/** Lazy populated list of child nodes. */
private List<ChunkNode> children;
/** Start positions in root stream of each value object in {@link #value}. */
private final List<Integer> arrStart;
/** Endo positions in root stream of each value object in {@link #value} (exclusive). */
private final List<Integer> arrEnd;

ListNode(String name, List<?> value, StructNode parent,
ListNode(String name, List<?> value, Class<?> valueClass, StructNode parent,
Span span,
boolean isSequential,
List<Integer> arrStart,
List<Integer> arrEnd
) {
super(name, parent, span, isSequential);
this.value = value;
this.elementClass = valueClass;
this.arrStart = arrStart;
this.arrEnd = arrEnd;
}
Expand Down Expand Up @@ -100,7 +104,7 @@ private List<ChunkNode> init() {
final int s = arrStart.get(index);
final int e = arrEnd.get(index);
final Span span = new Span(s, e);
children.add(create("[" + index + ']', obj, span, isSequential));
children.add(create("[" + index + ']', obj, elementClass, span, isSequential));
++index;
} catch (ReflectiveOperationException ex) {
throw new UnsupportedOperationException("Can't get list value at index " + index, ex);
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/ru/mingun/kaitai/struct/tree/SimpleNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,21 @@ public class SimpleNode extends ChunkNode {
/** Parsed value of non-constructed type. */
private final Object value;

SimpleNode(String name, Object value, ChunkNode parent, Span span, boolean isSequential) {
/** Static type of {@code value}, to identify the type when value is null. */
private final Class<?> valueClass;

SimpleNode(String name, Object value, Class<?> valueClass, ChunkNode parent, Span span, boolean isSequential) {
super(name, parent, span, isSequential);
this.value = value;
this.valueClass = valueClass;
}

@Override
public Object getValue() { return value; }

/** Static type of {@code value}, to identify the type when value is {@code null}. */
public Class<?> getValueClass() { return valueClass; }

//<editor-fold defaultstate="collapsed" desc="TreeNode">
@Override
public ChunkNode getChildAt(int childIndex) {
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/ru/mingun/kaitai/struct/tree/StructNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import io.kaitai.struct.KaitaiStruct;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import static java.util.Collections.enumeration;
Expand Down Expand Up @@ -170,9 +172,15 @@ private ChunkNode create(Method getter, boolean isSequential) throws ReflectiveO
if (isPresent && List.class.isAssignableFrom(getter.getReturnType())) {
final List<Integer> sa = arrStart.get(name);
final List<Integer> ea = arrEnd.get(name);
return new ListNode(name, (List<?>)field, this, span, isSequential, sa, ea);

// We are sure that return type is a generic with one Class parameter, because KaitaiStruct
// java generator generates fields/methods with an ArrayList<XXX> static type
final ParameterizedType returnType = (ParameterizedType) getter.getGenericReturnType();
final Type elementType = returnType.getActualTypeArguments()[0];

return new ListNode(name, (List<?>) field, (Class<?>) elementType, this, span, isSequential, sa, ea);
}
return create(name, field, span, isSequential);
return create(name, field, getter.getReturnType(), span, isSequential);
}

private ArrayList<ChunkNode> init() {
Expand Down

0 comments on commit 664ad05

Please sign in to comment.