package org.yamcs.xtceproc; import java.util.List; import org.yamcs.ErrorInCommand; import org.yamcs.parameter.Value; import org.yamcs.protobuf.Yamcs.Value.Type; import org.yamcs.utils.StringConverter; import org.yamcs.utils.ValueUtility; import org.yamcs.xtce.ArgumentType; import org.yamcs.xtce.BinaryArgumentType; import org.yamcs.xtce.BooleanArgumentType; import org.yamcs.xtce.DataEncoding; import org.yamcs.xtce.EnumeratedArgumentType; import org.yamcs.xtce.FloatArgumentType; import org.yamcs.xtce.FloatDataEncoding; import org.yamcs.xtce.FloatValidRange; import org.yamcs.xtce.IntegerArgumentType; import org.yamcs.xtce.IntegerRange; import org.yamcs.xtce.IntegerValidRange; import org.yamcs.xtce.StringArgumentType; import org.yamcs.xtce.ValueEnumeration; import com.google.common.primitives.UnsignedLongs; public class ArgumentTypeProcessor { ProcessorData pdata; public ArgumentTypeProcessor(ProcessorData pdata) { if(pdata==null) { throw new NullPointerException(); } this.pdata = pdata; } public Value decalibrate(ArgumentType atype, Value v) { if (atype instanceof EnumeratedArgumentType) { return decalibrateEnumerated((EnumeratedArgumentType) atype, v); } else if (atype instanceof IntegerArgumentType) { return decalibrateInteger((IntegerArgumentType) atype, v); } else if (atype instanceof FloatArgumentType) { return decalibrateFloat((FloatArgumentType) atype, v); } else if (atype instanceof StringArgumentType) { return decalibrateString((StringArgumentType) atype, v); } else if (atype instanceof BinaryArgumentType) { return decalibrateBinary((BinaryArgumentType) atype, v); } else if (atype instanceof BooleanArgumentType) { return decalibrateBoolean((BooleanArgumentType) atype, v); } else { throw new IllegalArgumentException("decalibration for "+atype+" not implemented"); } } private Value decalibrateEnumerated(EnumeratedArgumentType atype, Value v) { if(v.getType()!=Type.STRING) { throw new IllegalArgumentException("Enumerated decalibrations only available for strings"); } return ValueUtility.getSint64Value(atype.decalibrate(v.getStringValue())); } private Value decalibrateInteger(IntegerArgumentType ipt, Value v) { if (v.getType() == Type.UINT32) { return doIntegerDecalibration(ipt, v.getUint32Value()&0xFFFFFFFFL); } else if (v.getType() == Type.UINT64) { return doIntegerDecalibration(ipt, v.getUint64Value()); } else if (v.getType() == Type.SINT32) { return doIntegerDecalibration(ipt, v.getSint32Value()); } else if (v.getType() == Type.SINT64) { return doIntegerDecalibration(ipt, v.getSint64Value()); } else if (v.getType() == Type.STRING) { return doIntegerDecalibration(ipt, Long.valueOf(v.getStringValue())); } else { throw new IllegalStateException("Unsupported raw value type '"+v.getType()+"' cannot be converted to integer"); } } private Value doIntegerDecalibration(IntegerArgumentType ipt, long v) { DataEncoding de = ipt.getEncoding(); if(de instanceof FloatDataEncoding) { return doFloatDecalibration(ipt.getEncoding(), ipt.getSizeInBits(), v); } CalibratorProc calibrator = pdata.getDecalibrator(ipt.getEncoding()); Value raw; long longDecalValue = (calibrator == null) ? v : (long)calibrator.calibrate(v); if (ipt.getSizeInBits() <= 32) { if (ipt.isSigned()) { raw = ValueUtility.getSint32Value((int) longDecalValue); } else { raw = ValueUtility.getUint32Value((int) longDecalValue); } } else { if (ipt.isSigned()) { raw = ValueUtility.getSint64Value(longDecalValue); } else { raw = ValueUtility.getUint64Value(longDecalValue); } } return raw; } private Value decalibrateBoolean(BooleanArgumentType ipt, Value v) { if (v.getType() != Type.BOOLEAN) { throw new IllegalStateException("Unsupported raw value type '"+v.getType()+"' cannot be converted to boolean"); } return v; } private Value decalibrateFloat(FloatArgumentType fat, Value v) { if(v.getType() == Type.FLOAT) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getFloatValue()); } else if(v.getType() == Type.DOUBLE) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getDoubleValue()); } else if(v.getType() == Type.STRING) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), Double.valueOf(v.getStringValue())); } else if(v.getType() == Type.UINT32) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getUint32Value()); } else if(v.getType() == Type.UINT64) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getUint64Value()); } else if(v.getType() == Type.SINT32) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getSint32Value()); } else if(v.getType() == Type.SINT64) { return doFloatDecalibration(fat.getEncoding(), fat.getSizeInBits(), v.getSint64Value()); } else { throw new IllegalArgumentException("Unsupported value type '"+v.getType()+"' cannot be converted to float"); } } private Value doFloatDecalibration(DataEncoding de, int sizeInBits, double doubleValue) { CalibratorProc calibrator = pdata.getDecalibrator(de); double doubleCalValue = (calibrator == null) ? doubleValue:calibrator.calibrate(doubleValue); Value raw; if(sizeInBits == 32) { raw = ValueUtility.getFloatValue((float)doubleCalValue); } else { raw = ValueUtility.getDoubleValue(doubleCalValue); } return raw; } private static Value decalibrateString(StringArgumentType sat, Value v) { Value raw; if(v.getType() == Type.STRING) { raw = v; } else { throw new IllegalStateException("Unsupported value type '"+v.getType()+"' cannot be converted to string"); } return raw; } private static Value decalibrateBinary(BinaryArgumentType bat, Value v) { Value raw; if(v.getType() == Type.BINARY) { raw = v; } else { throw new IllegalStateException("Unsupported value type '"+v.getType()+"' cannot be converted to binary"); } return raw; } public static Value getInitialValue(ArgumentType type) { if (type instanceof IntegerArgumentType) { if(((IntegerArgumentType) type).getInitialValue() == null) return null; return ValueUtility.getStringValue(((IntegerArgumentType) type).getInitialValue()); } else if (type instanceof FloatArgumentType) { if(((FloatArgumentType) type).getInitialValue() == null) return null; return ValueUtility.getDoubleValue(((FloatArgumentType) type).getInitialValue()); } else if (type instanceof StringArgumentType) { if(((StringArgumentType) type).getInitialValue() == null) return null; return ValueUtility.getStringValue(((StringArgumentType) type).getInitialValue()); } else if (type instanceof BinaryArgumentType) { if(((BinaryArgumentType) type).getInitialValue() == null) return null; return ValueUtility.getBinaryValue(((BinaryArgumentType) type).getInitialValue()); } else if (type instanceof EnumeratedArgumentType) { if(((EnumeratedArgumentType) type).getInitialValue() == null) return null; return ValueUtility.getStringValue(((EnumeratedArgumentType) type).getInitialValue()); } return null; } public static Value parseAndCheckRange(ArgumentType type, String argumentValue) throws ErrorInCommand { Value v; if(type instanceof IntegerArgumentType) { IntegerArgumentType intType = (IntegerArgumentType) type; if(intType.isSigned()) { long l = Long.decode(argumentValue); IntegerValidRange vr = ((IntegerArgumentType)type).getValidRange(); if(vr!=null) { if(!ValidRangeChecker.checkIntegerRange(vr, l)) { throw new ErrorInCommand("Value "+l+" is not in the range required for the type "+type); } } v = ValueUtility.getSint64Value(l); } else { long l = UnsignedLongs.decode(argumentValue); IntegerValidRange vr = ((IntegerArgumentType)type).getValidRange(); if(vr!=null) { if(!ValidRangeChecker.checkUnsignedIntegerRange(vr, l)) { throw new ErrorInCommand("Value "+l+" is not in the range required for the type "+type); } } v = ValueUtility.getUint64Value(l); } } else if(type instanceof FloatArgumentType) { double d = Double.parseDouble(argumentValue); FloatValidRange vr = ((FloatArgumentType)type).getValidRange(); if(vr!=null) { if(!ValidRangeChecker.checkFloatRange(vr, d)) { throw new ErrorInCommand("Value "+d+" is not in the range required for the type "+type); } } v = ValueUtility.getDoubleValue(d); } else if(type instanceof StringArgumentType) { v = ValueUtility.getStringValue(argumentValue); IntegerRange r = ((StringArgumentType)type).getSizeRangeInCharacters(); if(r!=null) { int length = argumentValue.length(); if (length<r.getMinInclusive()) { throw new ErrorInCommand("Value "+argumentValue+" supplied for parameter fo type "+type+" does not satisfy minimum length of "+r.getMinInclusive()); } if(length>r.getMaxInclusive()) { throw new ErrorInCommand("Value "+argumentValue+" supplied for parameter fo type "+type+" does not satisfy maximum length of "+r.getMaxInclusive()); } } } else if (type instanceof BinaryArgumentType) { byte[] b = StringConverter.hexStringToArray(argumentValue); v = ValueUtility.getBinaryValue(b); } else if (type instanceof EnumeratedArgumentType) { EnumeratedArgumentType enumType = (EnumeratedArgumentType)type; List<ValueEnumeration> vlist = enumType.getValueEnumerationList(); boolean found =false; for(ValueEnumeration ve:vlist) { if(ve.getLabel().equals(argumentValue)) { found = true; } } if(!found) { throw new ErrorInCommand("Value '"+argumentValue+"' supplied for enumeration argument cannot be found in enumeration list "+vlist); } v = ValueUtility.getStringValue(argumentValue); } else if (type instanceof BooleanArgumentType) { boolean b = Boolean.parseBoolean(argumentValue); v = ValueUtility.getBooleanValue(b); } else { throw new IllegalArgumentException("Cannot parse values of type "+type); } return v; } }