/* * RomRaider Open-Source Tuning, Logging and Reflashing * Copyright (C) 2006-2015 RomRaider.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.romraider.logger.ecu.definition; import static com.romraider.logger.ecu.definition.xml.ConverterMaxMinDefaults.getDefault; import static com.romraider.util.ByteUtil.asUnsignedInt; import static com.romraider.util.JEPUtil.evaluate; import static com.romraider.util.ParamChecker.checkNotNull; import static com.romraider.util.ParamChecker.checkNotNullOrEmpty; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.text.DecimalFormat; import java.util.HashMap; import java.util.Map; import com.romraider.Settings; import com.romraider.logger.ecu.ui.handler.dash.GaugeMinMax; public final class EcuParameterConvertorImpl implements EcuDataConvertor { private static final String FLOAT = "float"; private static final String UINT = "uint"; private final String units; private final String expression; private final DecimalFormat format; private final int bit; private final String dataType; private final int endian; private final Map<String, String> replaceMap; private final GaugeMinMax gaugeMinMax; public EcuParameterConvertorImpl() { this("Raw data", "x", "0", -1, "uint", Settings.ENDIAN_BIG, new HashMap<String, String>(), getDefault()); } public EcuParameterConvertorImpl(String units, String expression, String format, int bit, String dataType, int endian, Map<String, String> replaceMap, GaugeMinMax gaugeMinMax) { checkNotNullOrEmpty(units, "units"); checkNotNullOrEmpty(expression, "expression"); checkNotNullOrEmpty(format, "format"); checkNotNull(replaceMap, "replaceMap"); this.units = units; this.expression = expression; this.format = new DecimalFormat(format); this.bit = bit; this.dataType = (dataType == null ? "uint8" : dataType); this.endian = endian; this.replaceMap = replaceMap; this.gaugeMinMax = gaugeMinMax; } public double convert(byte[] bytes) { final ByteBuffer bb = ByteBuffer.wrap(bytes); if (endian == Settings.ENDIAN_LITTLE) { bb.order(ByteOrder.LITTLE_ENDIAN); } double result = 0; if (bit >= 0 && bit <= 31) { return (asUnsignedInt(bytes) & (1 << bit)) != 0 ? 1 : 0; } else if (dataType.equalsIgnoreCase(FLOAT)) { result = evaluate(expression, bb.getFloat()); } else { long value = 0; switch (bb.capacity()) { case 1: value = bb.get(); break; case 2: value = bb.getShort(); break; case 4: value = bb.getInt(); break; } if (dataType.toLowerCase().startsWith(UINT)) { switch (bb.capacity()) { case 1: value = value & 0xff; break; case 2: value = value & 0xffff; break; case 4: value = value & 0xffffffffL; break; } } result = evaluate(expression, value); } return Double.isNaN(result) || Double.isInfinite(result) ? 0.0 : result; } public String getUnits() { return units; } public GaugeMinMax getGaugeMinMax() { return gaugeMinMax; } public String getFormat() { return format.toPattern(); } public String format(double value) { String formattedValue = format.format(value); if (replaceMap.containsKey(formattedValue)) { return replaceMap.get(formattedValue); } else { return formattedValue; } } public String toString() { return getUnits(); } public String getExpression() { return expression; } @Override public String getDataType() { return dataType; } }