diff --git a/core/pv-pva/src/main/java/org/phoebus/pv/pva/PVAStructureHelper.java b/core/pv-pva/src/main/java/org/phoebus/pv/pva/PVAStructureHelper.java index 3d5f8d4d74..279e7ed288 100644 --- a/core/pv-pva/src/main/java/org/phoebus/pv/pva/PVAStructureHelper.java +++ b/core/pv-pva/src/main/java/org/phoebus/pv/pva/PVAStructureHelper.java @@ -7,16 +7,6 @@ ******************************************************************************/ package org.phoebus.pv.pva; -import static java.util.stream.Collectors.toList; -import static java.util.stream.IntStream.range; -import static org.phoebus.pv.pva.Decoders.decodeAlarm; -import static org.phoebus.pv.pva.Decoders.decodeTime; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - import org.epics.pva.data.PVAArray; import org.epics.pva.data.PVABool; import org.epics.pva.data.PVABoolArray; @@ -56,23 +46,33 @@ import org.epics.vtype.VTable; import org.epics.vtype.VType; -/** Helper for handling 'structure' type PVA data */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.IntStream.range; +import static org.phoebus.pv.pva.Decoders.decodeAlarm; +import static org.phoebus.pv.pva.Decoders.decodeTime; + +/** + * Helper for handling 'structure' type PVA data + */ @SuppressWarnings("nls") -public class PVAStructureHelper -{ - /** @param struct Structure - * @param name_helper {@link PVNameHelper} - * @return Decoded VType - * @throws Exception on error +public class PVAStructureHelper { + /** + * @param struct Structure + * @param name_helper {@link PVNameHelper} + * @return Decoded VType + * @throws Exception on error */ - public static VType getVType(final PVAStructure struct, final PVNameHelper name_helper) throws Exception - { + public static VType getVType(final PVAStructure struct, final PVNameHelper name_helper) throws Exception { PVAStructure actual = struct; final Optional elementIndex = name_helper.getElementIndex(); - if (! name_helper.getField().equals("value")) - { // Fetch data from a sub-(sub-sub-)field + if (!name_helper.getField().equals("value")) { // Fetch data from a sub-(sub-sub-)field final PVAData field = struct.locate(name_helper.getField()); if (field instanceof PVAStructure) actual = (PVAStructure) field; @@ -80,25 +80,17 @@ else if (field instanceof PVANumber) return Decoders.decodeNumber(struct, (PVANumber) field); else if (field instanceof PVABool) return Decoders.decodeBool(struct, (PVABool) field); - else if (field instanceof PVAStructureArray) - { - if (elementIndex.isPresent()) - { + else if (field instanceof PVAStructureArray) { + if (elementIndex.isPresent()) { actual = ((PVAStructureArray) field).get()[elementIndex.get()]; } - } - else if (field instanceof PVAArray) - { - if (elementIndex.isPresent()) - { + } else if (field instanceof PVAArray) { + if (elementIndex.isPresent()) { return decodeNTArray(struct, elementIndex.get()); - } - else - { + } else { return Decoders.decodeArray(struct, (PVAArray) field); } - } - else if (field instanceof PVAString) + } else if (field instanceof PVAString) return Decoders.decodeString(struct, (PVAString) field); } @@ -110,8 +102,13 @@ else if (field instanceof PVAString) return decodeScalar(actual); if (type.equals("NTEnum:1.0")) return Decoders.decodeEnum(actual); - if (type.equals("NTScalarArray:1.0")) - return decodeNTArray(actual); + if (type.equals("NTScalarArray:1.0")) { + if (elementIndex.isPresent()) { + return decodeNTArray(actual, elementIndex.get()); + } else { + return decodeNTArray(actual); + } + } if (type.equals("NTNDArray:1.0")) return ImageDecoder.decode(actual); if (type.equals("NTTable:1.0")) @@ -119,22 +116,19 @@ else if (field instanceof PVAString) // Handle data that contains a "value", even though not marked as NT* final PVAData field = actual.get("value"); - if (field instanceof PVANumber || - field instanceof PVAString) + if (field instanceof PVANumber || + field instanceof PVAString) return decodeScalar(actual); else if (field instanceof PVAArray) return decodeNTArray(actual); - else if (field instanceof PVAUnion) - { // Decode the currently selected variant of the union + else if (field instanceof PVAUnion) { // Decode the currently selected variant of the union final PVAData union_field = ((PVAUnion) field).get(); - if (union_field instanceof PVANumber || - union_field instanceof PVAString) + if (union_field instanceof PVANumber || + union_field instanceof PVAString) return decodeScalarField(struct, union_field); else if (union_field instanceof PVAArray) return decodeNTArrayField(struct, union_field); - } - else if (field instanceof PVABool) - { + } else if (field instanceof PVABool) { final PVABool bool = (PVABool) field; return VBoolean.of(bool.get(), Alarm.none(), Time.now()); } @@ -142,25 +136,25 @@ else if (field instanceof PVABool) // Create string that indicates name of unknown type return VString.of(actual.format(), - Alarm.of(AlarmSeverity.UNDEFINED, AlarmStatus.CLIENT, "Unknown type"), - Time.now()); + Alarm.of(AlarmSeverity.UNDEFINED, AlarmStatus.CLIENT, "Unknown type"), + Time.now()); } - /** Attempt to decode a scalar {@link VType} - * @param struct PVA data for a scalar - * @return Value - * @throws Exception on error decoding the scalar + /** + * Attempt to decode a scalar {@link VType} + * + * @param struct PVA data for a scalar + * @return Value + * @throws Exception on error decoding the scalar */ - private static VType decodeScalar(final PVAStructure struct) throws Exception - { + private static VType decodeScalar(final PVAStructure struct) throws Exception { final VType result = decodeScalarField(struct, struct.get("value")); if (result != null) return result; throw new Exception("Expected struct with scalar 'value', got " + struct); } - private static VType decodeScalarField(final PVAStructure struct, final PVAData field) throws Exception - { + private static VType decodeScalarField(final PVAStructure struct, final PVAData field) throws Exception { if (field instanceof PVANumber) return Decoders.decodeNumber(struct, (PVANumber) field); if (field instanceof PVABool) @@ -170,104 +164,87 @@ private static VType decodeScalarField(final PVAStructure struct, final PVAData return null; } - /** Decode table from NTTable - * @param struct - * @return - * @throws Exception + /** + * Decode table from NTTable + * + * @param struct + * @return + * @throws Exception */ - private static VType decodeNTTable(final PVAStructure struct) throws Exception - { + private static VType decodeNTTable(final PVAStructure struct) throws Exception { final PVAStringArray labels_array = struct.get("labels"); - final List names = new ArrayList<>(Arrays.asList(labels_array.get())); + final List names = new ArrayList<>(Arrays.asList(labels_array.get())); final List> types = new ArrayList<>(names.size()); final List values = new ArrayList<>(names.size()); final PVAStructure value_struct = struct.get("value"); - for (PVAData column : value_struct.get()) - { - if (column instanceof PVADoubleArray) - { - final PVADoubleArray typed = (PVADoubleArray)column; + for (PVAData column : value_struct.get()) { + if (column instanceof PVADoubleArray) { + final PVADoubleArray typed = (PVADoubleArray) column; types.add(Double.TYPE); values.add(ArrayDouble.of(typed.get())); - } - else if (column instanceof PVAFloatArray) - { - final PVAFloatArray typed = (PVAFloatArray)column; + } else if (column instanceof PVAFloatArray) { + final PVAFloatArray typed = (PVAFloatArray) column; types.add(Float.TYPE); values.add(ArrayFloat.of(typed.get())); - } - else if (column instanceof PVAIntArray) - { - final PVAIntArray typed = (PVAIntArray)column; + } else if (column instanceof PVAIntArray) { + final PVAIntArray typed = (PVAIntArray) column; types.add(Integer.TYPE); if (typed.isUnsigned()) values.add(ArrayUInteger.of(typed.get())); else values.add(ArrayInteger.of(typed.get())); - } - else if (column instanceof PVAStringArray) - { - final PVAStringArray typed = (PVAStringArray)column; + } else if (column instanceof PVAStringArray) { + final PVAStringArray typed = (PVAStringArray) column; types.add(String.class); values.add(Arrays.asList(typed.get())); - } - else if (column instanceof PVAShortArray) - { - final PVAShortArray typed = (PVAShortArray)column; + } else if (column instanceof PVAShortArray) { + final PVAShortArray typed = (PVAShortArray) column; types.add(Short.TYPE); if (typed.isUnsigned()) values.add(ArrayUShort.of(typed.get())); else values.add(ArrayShort.of(typed.get())); - } - else if (column instanceof PVALongArray) - { - final PVALongArray typed = (PVALongArray)column; + } else if (column instanceof PVALongArray) { + final PVALongArray typed = (PVALongArray) column; types.add(Long.TYPE); if (typed.isUnsigned()) values.add(ArrayULong.of(typed.get())); else values.add(ArrayLong.of(typed.get())); - } - else if (column instanceof PVAByteArray) - { - final PVAByteArray typed = (PVAByteArray)column; + } else if (column instanceof PVAByteArray) { + final PVAByteArray typed = (PVAByteArray) column; types.add(Byte.TYPE); if (typed.isUnsigned()) values.add(ArrayUByte.of(typed.get())); else values.add(ArrayByte.of(typed.get())); - } - else if (column instanceof PVABoolArray) - { - final PVABoolArray typed = (PVABoolArray)column; + } else if (column instanceof PVABoolArray) { + final PVABoolArray typed = (PVABoolArray) column; types.add(Boolean.TYPE); boolean[] data = typed.get(); // Convert to boxed Integer to add to List values.add(range(0, data.length).mapToObj(i -> data[i]).collect(toList())); - } - else - { - throw new IllegalArgumentException("Could not decode table column of type: " + column.getClass()); + } else { + throw new IllegalArgumentException("Could not decode table column of type: " + column.getClass()); } } return VTable.of(types, names, values); } - /** Decode 'value', 'timeStamp', 'alarm' of NTArray - * @param struct - * @return - * @throws Exception + /** + * Decode 'value', 'timeStamp', 'alarm' of NTArray + * + * @param struct + * @return + * @throws Exception */ - private static VType decodeNTArray(final PVAStructure struct) throws Exception - { + private static VType decodeNTArray(final PVAStructure struct) throws Exception { return decodeNTArrayField(struct, struct.get("value")); } - private static VType decodeNTArrayField(final PVAStructure struct, final PVAData field) throws Exception - { + private static VType decodeNTArrayField(final PVAStructure struct, final PVAData field) throws Exception { if (field instanceof PVADoubleArray) return Decoders.decodeDoubleArray(struct, (PVADoubleArray) field); if (field instanceof PVAFloatArray) @@ -283,70 +260,55 @@ private static VType decodeNTArrayField(final PVAStructure struct, final PVAData if (field instanceof PVAStringArray) return Decoders.decodeStringArray(struct, (PVAStringArray) field); return VString.of(struct.format(), - Alarm.of(AlarmSeverity.UNDEFINED, AlarmStatus.CLIENT, "Unknown array type"), - Time.now()); + Alarm.of(AlarmSeverity.UNDEFINED, AlarmStatus.CLIENT, "Unknown array type"), + Time.now()); } /** * Decode 'value', 'timeStamp', 'alarm' of NTArray and extract the value at index + * * @param struct * @param index * @return {@link VType} * @throws Exception */ - private static VType decodeNTArray(PVAStructure struct, Integer index) throws Exception - { + private static VType decodeNTArray(PVAStructure struct, Integer index) throws Exception { final PVAData field = struct.get("value"); - if (field instanceof PVADoubleArray) - { + if (field instanceof PVADoubleArray) { return VNumber.of(((VNumberArray) Decoders.decodeDoubleArray(struct, (PVADoubleArray) field)).getData().getDouble(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVAFloatArray) - { + } else if (field instanceof PVAFloatArray) { return VNumber.of(((VNumberArray) Decoders.decodeFloatArray(struct, (PVAFloatArray) field)).getData().getFloat(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVALongArray) - { + } else if (field instanceof PVALongArray) { return VNumber.of(((VNumberArray) Decoders.decodeLongArray(struct, (PVALongArray) field)).getData().getLong(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVAIntArray) - { + } else if (field instanceof PVAIntArray) { return VNumber.of(((VNumberArray) Decoders.decodeIntArray(struct, (PVAIntArray) field)).getData().getInt(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVAShortArray) - { + } else if (field instanceof PVAShortArray) { return VNumber.of(((VNumberArray) Decoders.decodeShortArray(struct, (PVAShortArray) field)).getData().getShort(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVAByteArray) - { + } else if (field instanceof PVAByteArray) { return VNumber.of(((VNumberArray) Decoders.decodeByteArray(struct, (PVAByteArray) field)).getData().getByte(index), decodeAlarm(struct), decodeTime(struct), Display.none()); - } - else if (field instanceof PVAStringArray) - { + } else if (field instanceof PVAStringArray) { return VString.of(((VStringArray) Decoders.decodeStringArray(struct, (PVAStringArray) field)).getData().get(index), decodeAlarm(struct), decodeTime(struct)); - } - else - { + } else { return VString.of(struct.format(), Alarm.of(AlarmSeverity.UNDEFINED, AlarmStatus.CLIENT, "Unknown array type"), Time.now());