Skip to content

Commit

Permalink
Add support for complex types - basic implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
byrnHDF committed Dec 18, 2024
1 parent c685959 commit d515ab4
Show file tree
Hide file tree
Showing 11 changed files with 432 additions and 42 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ of HDF5 and HDF4. Previous releases of HDFView that were based on HDF5 1.8,
| 3.3.0 | 1.14.0 | 4.2.16 | HDF5 1.12 (new-style) references, Single-Writer/Multiple-Readers (SWMR) reads, bug fixes |
| 3.3.1 | 1.14.2 | 4.2.16-2 | Fixes a critical HDF4 + HDFView bug |
| 3.3.2 | 1.14.4 | 4.3.0 | Float16 support |
| 3.3.3 | 1.16.0 | 4.4.0 | Complex number support |
| 3.4.0 | 2.0.0 | 4.4.0 | Complex number support |


PREVIOUS RELEASES AND SOURCE CODE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ else if (dtype.isOpaque() || dtype.isBitField())
converter = new BitfieldDataDisplayConverter(dtype);
else if (dtype.isRef())
converter = new RefDataDisplayConverter(dtype);
else if (dtype.isComplex())
converter = new ComplexDataDisplayConverter(dtype);
}
catch (Exception ex) {
log.debug(
Expand Down Expand Up @@ -963,4 +965,137 @@ public Object canonicalToDisplayValue(Object value)
return buffer;
}
}

private static class ComplexDataDisplayConverter extends HDFDisplayConverter {
private static final Logger log = LoggerFactory.getLogger(ComplexDataDisplayConverter.class);

private final HDFDisplayConverter baseTypeConverter;
private final StringBuilder buffer;

ComplexDataDisplayConverter(final Datatype dtype) throws Exception {
super(dtype);

if (!dtype.isComplex()) {
log.debug("exit: datatype is not a complex type");
throw new Exception("ComplexDataDisplayConverter: datatype is not a complex type");
}

Datatype baseType = dtype.getDatatypeBase();

if (baseType == null) {
log.debug("exit: base datatype is null");
throw new Exception("ComplexDataDisplayConverter: base datatype is null");
}

try {
baseTypeConverter = getDataDisplayConverter(baseType);

/*
* Make base datatype converter inherit the data conversion settings.
*/
baseTypeConverter.setShowAsHex(this.showAsHex);
baseTypeConverter.setShowAsBin(this.showAsBin);
baseTypeConverter.setNumberFormat(this.numberFormat);
baseTypeConverter.setConvertEnum(this.isEnumConverted);
}
catch (Exception ex) {
log.debug("exit: couldn't get DataDisplayConverter for base datatype: ", ex);
throw new Exception("ComplexDataDisplayConverter: couldn't get DataDisplayConverter for base datatype: "
+ ex.getMessage());
}

buffer = new StringBuilder();
}

@Override
public Object canonicalToDisplayValue(ILayerCell cell, IConfigRegistry configRegistry, Object value)
{
cellRowIdx = cell.getRowIndex();
cellColIdx = cell.getColumnIndex();
return canonicalToDisplayValue(value);
}

@Override
public Object canonicalToDisplayValue(Object value)
{
log.trace("canonicalToDisplayValue({}): start", value);

if (value instanceof String)
return value;

if (value == null) {
log.debug("canonicalToDisplayValue({}): value is null", value);
return DataFactoryUtils.nullStr;
}

buffer.setLength(0); // clear the old string

/*
* Pass the cell's row and column index down in case there is a CompoundDataDisplayConverter at the bottom
* of the chain.
*/
baseTypeConverter.cellRowIdx = cellRowIdx;
baseTypeConverter.cellColIdx = cellColIdx;

try {
Object obj;
Object convertedValue;
int arrLen = Array.getLength(value);

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

for (int i = 0; i < arrLen; i++) {
if (i > 0)
buffer.append("+");

obj = Array.get(value, i);

convertedValue = baseTypeConverter.canonicalToDisplayValue(obj);

buffer.append(convertedValue);
}

buffer.append("i");
}
catch (Exception ex) {
log.debug("canonicalToDisplayValue({}): failure: ", value, ex);
buffer.setLength(0);
buffer.append(DataFactoryUtils.errStr);
}

return buffer;
}

@Override
public void setNumberFormat(NumberFormat format)
{
super.setNumberFormat(format);

baseTypeConverter.setNumberFormat(format);
}

@Override
public void setShowAsHex(boolean asHex)
{
super.setShowAsHex(asHex);

baseTypeConverter.setShowAsHex(asHex);
}

@Override
public void setShowAsBin(boolean asBin)
{
super.setShowAsBin(asBin);

baseTypeConverter.setShowAsBin(asBin);
}

@Override
public void setConvertEnum(boolean convert)
{
super.setConvertEnum(convert);

baseTypeConverter.setConvertEnum(convert);
}
}
}
116 changes: 116 additions & 0 deletions src/org.hdfgroup.hdfview/hdf/view/TableView/DataProviderFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ else if (dtype.isOpaque() || dtype.isBitField())
dataProvider = new BitfieldDataProvider(dtype, dataBuf, dataTransposed);
else if (dtype.isRef())
dataProvider = new RefDataProvider(dtype, dataBuf, dataTransposed);
else if (dtype.isComplex())
dataProvider = new ComplexDataProvider(dtype, dataBuf, dataTransposed);
}
catch (Exception ex) {
log.debug("getDataProvider(): error occurred in retrieving a DataProvider: ", ex);
Expand Down Expand Up @@ -1438,6 +1440,7 @@ private void updateArrayOfArrayElements(Object newValue, Object curBuf, int colu
case Datatype.CLASS_ARRAY:
case Datatype.CLASS_COMPOUND:
case Datatype.CLASS_VLEN:
case Datatype.CLASS_COMPLEX:
default:
buffer = new Object[newcnt];
break;
Expand Down Expand Up @@ -1480,6 +1483,7 @@ private void updateArrayOfAtomicElements(Object newValue, Object curBuf, int row
case Datatype.CLASS_ARRAY:
case Datatype.CLASS_COMPOUND:
case Datatype.CLASS_VLEN:
case Datatype.CLASS_COMPLEX:
default:
buffer = new Object[newcnt];
break;
Expand Down Expand Up @@ -1949,4 +1953,116 @@ private String populateReferenceObject(Object byteBuf, int startIndex)
return objectStr;
}
}

private static class ComplexDataProvider extends HDFDataProvider {
private static final Logger log = LoggerFactory.getLogger(ComplexDataProvider.class);

private final HDFDataProvider baseTypeDataProvider;

private final StringBuilder buffer;

private final long typeSize;

ComplexDataProvider(final Datatype dtype, final Object dataBuf, final boolean dataTransposed) throws Exception {
super(dtype, dataBuf, dataTransposed);

Datatype baseType = dtype.getDatatypeBase();

baseTypeDataProvider = getDataProvider(baseType, dataBuf, dataTransposed);

typeSize = baseType.getDatatypeSize();

buffer = new StringBuilder();
}

@Override
public Object getDataValue(int columnIndex, int rowIndex)
{
buffer.setLength(0);

log.trace("getDataValue(rowIndex={}, columnIndex={}): start", rowIndex, columnIndex);

try {
int bufIndex = physicalLocationToBufIndex(rowIndex, columnIndex);
theValue = retrieveArrayOfAtomicElements(dataBuf, bufIndex * 2);
log.trace("getDataValue(bufIndex={}, dataBuf={})=({})", bufIndex, dataBuf, theValue);
}
catch (Exception ex) {
log.debug("getDataValue(rowIndex={}, columnIndex={}): failure: ", rowIndex, columnIndex, ex);
theValue = DataFactoryUtils.errStr;
}

log.trace("getDataValue(rowIndex={}, columnIndex={})=({}): finish", rowIndex, columnIndex, theValue);

return theValue;
}

private Object[] retrieveArrayOfAtomicElements(Object objBuf, int rowStartIdx)
{
log.debug("retrieveArrayOfAtomicElements(): objBuf={}", objBuf);
Object[] tempArray = new Object[(int) 2];
Object realElement = Array.get(objBuf, rowStartIdx);
Object imgElement = Array.get(objBuf, rowStartIdx + 1);
log.debug("retrieveArrayOfAtomicElements(): realElement={} imgElement={}", realElement, imgElement);

tempArray[0] = baseTypeDataProvider.getDataValue(objBuf, rowStartIdx);
tempArray[1] = baseTypeDataProvider.getDataValue(objBuf, rowStartIdx + 1);

log.debug("retrieveArrayOfAtomicElements(): tempArray={}", tempArray);
return tempArray;
}

@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue)
{
try {
int bufIndex = physicalLocationToBufIndex(rowIndex, columnIndex);

updateArrayElements(dataBuf, newValue, columnIndex, rowIndex);
}
catch (Exception ex) {
log.debug("setDataValue(rowIndex={}, columnIndex={}, {}): cell value update failure: ", rowIndex,
columnIndex, newValue, ex);
}
log.trace("setDataValue(rowIndex={}, columnIndex={})=({}): finish", rowIndex, columnIndex, newValue);
}

@Override
public void setDataValue(int columnIndex, int rowIndex, Object bufObject, Object newValue)
{
try {
updateArrayElements(bufObject, newValue, columnIndex, rowIndex);
}
catch (Exception ex) {
log.debug("setDataValue(rowIndex={}, columnIndex={}, bufObject={}, {}): cell value update failure: ",
rowIndex, columnIndex, bufObject, newValue, ex);
}
log.trace("setDataValue(rowIndex={}, columnIndex={}, bufObject={})=({}): finish", rowIndex, columnIndex,
bufObject, newValue);
}

private void updateArrayElements(Object curBuf, Object newValue, int columnIndex, int rowStartIndex)
{
updateArrayOfAtomicElements(newValue, curBuf, rowStartIndex);
}

private void updateArrayOfAtomicElements(Object newValue, Object curBuf, int rowStartIdx)
{
ArrayList vlElements = ((ArrayList[]) curBuf)[rowStartIdx];

StringTokenizer st = new StringTokenizer((String) newValue, "+i");
int newcnt = st.countTokens();
Object[] buffer = new Double[newcnt];
for (int i = 0; i < newcnt; i++) {
baseTypeDataProvider.setDataValue(i, buffer, st.nextToken().trim());
isValueChanged = isValueChanged || baseTypeDataProvider.getIsValueChanged();
}
String bname = buffer.getClass().getName();
String cname = curBuf.getClass().getName();
log.trace("updateArrayOfAtomicElements(): buffer cname={} of data cname={}", bname, cname);
vlElements = new ArrayList<>(Arrays.asList(buffer));
log.debug("updateArrayOfAtomicElements(): new vlSize={}", vlElements.size());
((ArrayList[]) curBuf)[rowStartIdx] = vlElements;
}
}
}
20 changes: 18 additions & 2 deletions src/org.hdfgroup.hdfview/hdf/view/dialog/UserOptionsHDFPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public class UserOptionsHDFPage extends UserOptionsDefaultPage {
private Button checkNativeOrder, checkDecOrder, checkIncOrder;
private Button checkIndexName, checkIndexCreateOrder;
private Button earlyLibVersion, early18LibVersion, early110LibVersion, early112LibVersion,
early114LibVersion, earlyLateLibVersion;
early114LibVersion, early200LibVersion, earlyLateLibVersion;
private Button lateLibVersion, late18LibVersion, late110LibVersion, late112LibVersion, late114LibVersion,
lateLateLibVersion;
late200LibVersion, lateLateLibVersion;
private Button pluginDirButton;

/** Default early libversion for files */
Expand Down Expand Up @@ -130,6 +130,8 @@ else if (early112LibVersion.getSelection())
ViewProperties.setEarlyLib("v112");
else if (early114LibVersion.getSelection())
ViewProperties.setEarlyLib("v114");
else if (early200LibVersion.getSelection())
ViewProperties.setEarlyLib("v200");
else if (earlyLateLibVersion.getSelection())
ViewProperties.setEarlyLib("Latest");
else
Expand All @@ -148,6 +150,8 @@ else if (late112LibVersion.getSelection())
ViewProperties.setLateLib("v112");
else if (late114LibVersion.getSelection())
ViewProperties.setLateLib("v114");
else if (late200LibVersion.getSelection())
ViewProperties.setLateLib("v200");
else if (lateLateLibVersion.getSelection())
ViewProperties.setLateLib("Latest");
else
Expand Down Expand Up @@ -211,6 +215,7 @@ protected void load()
early110LibVersion.setSelection(earlyLibVers.compareTo("v110") == 0);
early112LibVersion.setSelection(earlyLibVers.compareTo("v112") == 0);
early114LibVersion.setSelection(earlyLibVers.compareTo("v114") == 0);
early200LibVersion.setSelection(earlyLibVers.compareTo("v200") == 0);
earlyLateLibVersion.setSelection(earlyLibVers.compareTo("Latest") == 0);

lateLibVers = ViewProperties.getLateLib();
Expand All @@ -220,6 +225,7 @@ protected void load()
late110LibVersion.setSelection(lateLibVers.compareTo("v110") == 0);
late112LibVersion.setSelection(lateLibVers.compareTo("v112") == 0);
late114LibVersion.setSelection(lateLibVers.compareTo("v114") == 0);
late200LibVersion.setSelection(lateLibVers.compareTo("v200") == 0);
lateLateLibVersion.setSelection(lateLibVers.compareTo("Latest") == 0);

checkConvertEnum.setSelection(ViewProperties.isConvertEnum());
Expand Down Expand Up @@ -311,6 +317,11 @@ protected Control createContents(Composite parent)
early114LibVersion.setText("v114");
early114LibVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

early200LibVersion = new Button(earlyLibVersionGroup, SWT.RADIO);
early200LibVersion.setFont(curFont);
early200LibVersion.setText("v200");
early200LibVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

earlyLateLibVersion = new Button(earlyLibVersionGroup, SWT.RADIO);
earlyLateLibVersion.setFont(curFont);
earlyLateLibVersion.setText("Latest");
Expand Down Expand Up @@ -348,6 +359,11 @@ protected Control createContents(Composite parent)
late114LibVersion.setText("v114");
late114LibVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

late200LibVersion = new Button(lateLibVersionGroup, SWT.RADIO);
late200LibVersion.setFont(curFont);
late200LibVersion.setText("v200");
late200LibVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

lateLateLibVersion = new Button(lateLibVersionGroup, SWT.RADIO);
lateLateLibVersion.setFont(curFont);
lateLateLibVersion.setText("Latest");
Expand Down
1 change: 1 addition & 0 deletions src/org.hdfgroup.object/hdf/object/CompoundDS.java
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ else if (dtype.isArray()) {
case Datatype.CLASS_ENUM:
case Datatype.CLASS_VLEN:
case Datatype.CLASS_TIME:
case Datatype.CLASS_COMPLEX:
theObj = convertByteMember(baseType, byteData);
break;

Expand Down
Loading

0 comments on commit d515ab4

Please sign in to comment.