Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,7 @@ public static HDFDisplayConverter getDataDisplayConverter(final DataFormat dataO

dataFormatReference = dataObject;

Datatype dtype = dataObject.getDatatype();

// For VLEN(compound), use compound base type so CompoundDataDisplayConverter is created
if (dtype.isVLEN() && !dtype.isVarStr() && dtype.getDatatypeBase() != null &&
dtype.getDatatypeBase().isCompound()) {
dtype = dtype.getDatatypeBase();
}

HDFDisplayConverter converter = getDataDisplayConverter(dtype);
HDFDisplayConverter converter = getDataDisplayConverter(dataObject.getDatatype());

return converter;
}
Expand Down Expand Up @@ -237,7 +229,7 @@ private static class CompoundDataDisplayConverter extends HDFDisplayConverter {
CompoundDataFormat compoundFormat = (CompoundDataFormat)dataFormatReference;

List<Datatype> localSelectedTypes =
DataFactoryUtils.filterNonSelectedMembers(compoundFormat, dtype);
DataFactoryUtils.filterNonSelectedMembers(compoundFormat, dtype, false);

log.trace("setting up {} base HDFDisplayConverters", localSelectedTypes.size());

Expand Down Expand Up @@ -331,10 +323,15 @@ public Object canonicalToDisplayValue(Object value)
Object curObject = cmpdList.get(i);
if (curObject instanceof List)
buffer.append(memberTypeConverters[i].canonicalToDisplayValue(curObject));
else {
else if (curObject != null && curObject.getClass().isArray()) {
// Array-of-compound: the member is indexed by row.
Object dataArrayValue = Array.get(curObject, cellRowIdx);
buffer.append(memberTypeConverters[i].canonicalToDisplayValue(dataArrayValue));
}
else {
// A single compound element: the member is already the value.
buffer.append(memberTypeConverters[i].canonicalToDisplayValue(curObject));
}
}
buffer.append("}");
}
Expand Down Expand Up @@ -469,7 +466,9 @@ public Object canonicalToDisplayValue(Object value)
try {
Object obj;
Object convertedValue;
int arrLen = Array.getLength(value);

// An array's elements may arrive as a List, nested arrays included.
int arrLen = (value instanceof List) ? ((List<?>)value).size() : Array.getLength(value);

log.trace("canonicalToDisplayValue({}): array length={}", value, arrLen);

Expand All @@ -480,7 +479,7 @@ public Object canonicalToDisplayValue(Object value)
if (i > 0)
buffer.append(", ");

obj = Array.get(value, i);
obj = (value instanceof List) ? ((List<?>)value).get(i) : Array.get(value, i);

convertedValue = baseTypeConverter.canonicalToDisplayValue(obj);

Expand Down Expand Up @@ -610,7 +609,14 @@ public Object canonicalToDisplayValue(Object value)
try {
Object obj;
Object convertedValue;
int arrLen = Array.getLength(value);

// A scalar cell defers to the base converter.
if (!value.getClass().isArray() && !(value instanceof List)) {
buffer.append(baseTypeConverter.canonicalToDisplayValue(value));
return buffer;
}

int arrLen = (value instanceof List) ? ((List<?>)value).size() : Array.getLength(value);

log.trace("canonicalToDisplayValue({}): array length={}", value, arrLen);

Expand All @@ -621,7 +627,7 @@ public Object canonicalToDisplayValue(Object value)
if (i > 0)
buffer.append(", ");

obj = Array.get(value, i);
obj = (value instanceof List) ? ((List<?>)value).get(i) : Array.get(value, i);

convertedValue = baseTypeConverter.canonicalToDisplayValue(obj);

Expand Down
89 changes: 65 additions & 24 deletions hdfview/src/main/java/hdf/view/TableView/DataFactoryUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,36 @@ public class DataFactoryUtils {
/** the CMPD_START_IDX_MAP_INDEX value. */
public static final int CMPD_START_IDX_MAP_INDEX = 1;

/**
* Number of flat leaf names a Datatype contributes to the list produced by
* H5Datatype.extractCompoundInfo: a compound sums its children, an
* array-of-compound adds a header entry, anything else counts once.
*/
public static int countLeafNames(Datatype t)
{
if (t == null)
return 1;
if (t.isCompound()) {
int sum = 0;
List<Datatype> children = t.getCompoundMemberTypes();
if (children != null)
for (Datatype child : children)
sum += countLeafNames(child);
return sum;
}
if (t.isArray()) {
Datatype base = t.getDatatypeBase();
if (base != null && base.isCompound()) {
int sum = 1;
for (Datatype child : base.getCompoundMemberTypes())
sum += countLeafNames(child);
return sum;
}
return 1;
}
return 1;
}

/**
* Given a CompoundDataFormat, as well as a compound datatype, removes the
* non-selected datatypes from the List of datatypes inside the compound
Expand All @@ -62,34 +92,31 @@ public class DataFactoryUtils {
public static List<Datatype> filterNonSelectedMembers(CompoundDataFormat dataFormat,
final Datatype compoundType)
{
return filterNonSelectedMembers(dataFormat, compoundType, true);
}

/**
* As above, but an inner compound keeps every member: the dataset's selected-member
* list enumerates only top-level leaves, so filtering against it would drop them all.
*/
public static List<Datatype> filterNonSelectedMembers(CompoundDataFormat dataFormat,
final Datatype compoundType, boolean isTopLevel)
{
List<Datatype> selectedTypes = new ArrayList<>(compoundType.getCompoundMemberTypes());
if (!isTopLevel)
return selectedTypes;

List<Datatype> allSelectedTypes = Arrays.asList(dataFormat.getSelectedMemberTypes());
if (allSelectedTypes == null) {
log.debug("filterNonSelectedMembers(): selected compound member datatype list is null");
return null;
}

/*
* Make sure to make a copy of the compound datatype's member list, as we will
* make modifications to the list when members aren't selected.
*/
List<Datatype> selectedTypes = new ArrayList<>(compoundType.getCompoundMemberTypes());

/*
* Among the datatypes within this compound type, only keep the ones that are
* actually selected in the dataset.
*/
Iterator<Datatype> localIt = selectedTypes.iterator();
while (localIt.hasNext()) {
Datatype curType = localIt.next();

/*
* Since the passed in allSelectedMembers list is a flattened out datatype
* structure, we want to leave the nested compound Datatypes inside our local
* list of datatypes.
*/
if (curType.isCompound())
continue;

if (!allSelectedTypes.contains(curType))
localIt.remove();
}
Expand Down Expand Up @@ -191,24 +218,28 @@ else if (base.isArray()) {
}

if (nestedCompoundType != null) {
List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, nestedCompoundType);
List<Datatype> cmpdSelectedTypes =
filterNonSelectedMembers(dataFormat, nestedCompoundType, false);

/*
* For Array/Vlen of Compound types, we repeat the compound members n times,
* where n is the number of array elements of variable-length elements.
* Therefore, we repeat our mapping for these types n times.
* For Array of Compound types, repeat the compound members once per
* array element.
*/
for (int j = 0; j < arrSize; j++) {
buildColIdxToProviderMap(outMap, dataFormat, cmpdSelectedTypes, curMapIndex,
curProviderIndex, depth + 1);
}
}
else if (curType.isCompound()) {
List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, curType);
List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, curType, false);

buildColIdxToProviderMap(outMap, dataFormat, cmpdSelectedTypes, curMapIndex, curProviderIndex,
depth + 1);
}
else if (curType.isVLEN() && !curType.isVarStr()) {
// A vlen is one column: it holds the whole sequence.
outMap.put(curMapIndex[0]++, curProviderIndex[0]);
}
else
outMap.put(curMapIndex[0]++, curProviderIndex[0]);

Expand Down Expand Up @@ -299,7 +330,8 @@ else if (base.isArray()) {
}

if (nestedCompoundType != null) {
List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, nestedCompoundType);
List<Datatype> cmpdSelectedTypes =
filterNonSelectedMembers(dataFormat, nestedCompoundType, false);

/*
* For Array/Vlen of Compound types, we repeat the compound members n times,
Expand All @@ -318,11 +350,20 @@ else if (curType.isCompound()) {
if (depth == 0)
curStartIdx[0] = curMapIndex[0];

List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, curType);
List<Datatype> cmpdSelectedTypes = filterNonSelectedMembers(dataFormat, curType, false);

buildRelColIdxToStartIdxMap(outMap, dataFormat, cmpdSelectedTypes, curMapIndex, curStartIdx,
depth + 1);
}
else if (curType.isVLEN() && !curType.isVarStr()) {
// A vlen is one column: it holds the whole sequence.
if (depth == 0) {
outMap.put(curMapIndex[0], curMapIndex[0]);
curMapIndex[0]++;
}
else
outMap.put(curMapIndex[0]++, curStartIdx[0]);
}
else {
if (depth == 0) {
outMap.put(curMapIndex[0], curMapIndex[0]);
Expand Down
Loading
Loading