/******************************************************************************* * Copyright (c) 2011 Oak Ridge National Laboratory. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package org.csstudio.data.values; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; /** Helper for decoding the data in a {@link IValue}, * mostly for display purposes. * @author Kay Kasemir */ public class ValueUtil { /** @return Array length of the value. <code>1</code> for scalars. */ public static int getSize(final IValue value) { if (value instanceof IDoubleValue) return ((IDoubleValue) value).getValues().length; else if (value instanceof ILongValue) return ((ILongValue) value).getValues().length; else if (value instanceof IEnumeratedValue) return ((IEnumeratedValue) value).getValues().length; return 1; } /** Try to get a double number from the Value. * <p> * Some applications only deal with numeric data, * so they want to interprete integer, enum and double values * all the same. * @param value The value to decode. * @return A double, or <code>Double.NaN</code> in case the value type * does not decode into a number, or * <code>Double.NEGATIVE_INFINITY</code> if the value's severity * indicates that there happens to be no useful value. */ public static double getDouble(final IValue value) { return getDouble(value, 0); } /** Try to get a double-typed array element from the Value. * @param value The value to decode. * @param index The array index, 0 ... getSize()-1. * @see #getSize(Value) * @see #getDouble(Value) * @return A double, or <code>Double.NaN</code> in case the value type * does not decode into a number, or * <code>Double.NEGATIVE_INFINITY</code> if the value's severity * indicates that there happens to be no useful value. */ public static double getDouble(final IValue value, final int index) { if (value.getSeverity().hasValue()) { if (value instanceof IDoubleValue) return ((IDoubleValue) value).getValues()[index]; else if (value instanceof ILongValue) return ((ILongValue) value).getValues()[index]; else if (value instanceof IEnumeratedValue) return ((IEnumeratedValue) value).getValues()[index]; // else: // Cannot decode that sample type as a number. return Double.NaN; } // else: Sample carries no value other than stat/sevr return Double.NEGATIVE_INFINITY; } /** Try to get a double-typed array from the Value. * @param value The value to decode. * @see #getSize(Value) * @see #getDouble(Value) * @return A double array, or an empty double array in case the value type * does not decode into a number, or if the value's severity * indicates that there happens to be no useful value. */ public static double[] getDoubleArray(final IValue value) { if (! value.getSeverity().hasValue()) // Sample carries no value other than stat/sevr return new double[0]; if (value instanceof IDoubleValue) return ((IDoubleValue) value).getValues(); else if (value instanceof ILongValue) { final long ilv[] = ((ILongValue) value).getValues(); final double result[] = new double[ilv.length]; for (int i = ilv.length-1; i>=0; --i) result[i] = ilv[i]; return result; } else if (value instanceof IEnumeratedValue) { final int iev[] = ((IEnumeratedValue) value).getValues(); final double result[] = new double[iev.length]; for (int i = iev.length-1; i>=0; --i) result[i] = iev[i]; return result; } // else: // Cannot decode that sample type as a number. return new double[0]; } /** Try to get an info string from the Value. * <p> * For numeric values, which is probably the vast majority of * all values, this is the severity and status information. * <p> * For 'enum' type values, <code>getDouble()</code> will return * the numeric value, and <code>getInfo()</code> returns the associated * enumeration string, appended to a possible severity/status text. * <p> * For string type values, this is the string value and * a possible severity/status text, * while <code>getDouble()</code> will return <code>NaN</code>. * * @param value The value to decode. * @return The info string, never <code>null</code>. * * @deprecated Remove. Only used in old Data Browser?? */ @Deprecated public static String getInfo(final IValue value) { String info = null; String val_txt = null; final String sevr = value.getSeverity().toString(); final String stat = value.getStatus(); if (sevr.length() > 0 || stat.length() > 0) info = sevr + Messages.SevrStatSeparator + stat; if (value instanceof IEnumeratedValue) val_txt = ((IEnumeratedValue) value).format(); else if (value instanceof IStringValue) val_txt = ((IStringValue) value).getValue(); if (val_txt != null) // return info appended to value { if (info == null) return val_txt; return val_txt + Messages.SevrStatSeparator + info; } if (info == null) return ""; //$NON-NLS-1$ return info; } /** @return Non-<code>null</code> String for the value and its * severity/status. Does not include the time stamp. * @see Value#format() * @see #getInfo(Value) */ public static String formatValueAndSeverity(final IValue value) { if (value == null) return ""; //$NON-NLS-1$ String v = value.format(); if (value.getSeverity().isOK()) return v; return v + Messages.ValueSevrStatSeparator + value.getSeverity().toString() + Messages.SevrStatSeparator + value.getStatus() + Messages.SevrStatEnd; } /** * Converts the given value into a string representation. For string values, * returns the value. For numeric (double and long) values, returns a * non-localized string representation. Double values use a point as the * decimal separator. For other types of values, the value's * {@link IValue#format()} method is called and its result returned. * * @param value * the value. * @return a string representation of the value. */ @SuppressWarnings("nls") public static String getString(final IValue value) { if (value instanceof IStringValue) return ((IStringValue) value).getValue(); else if (value instanceof IDoubleValue) { final IDoubleValue idv = (IDoubleValue) value; final double dv = idv.getValue(); if (Double.isNaN(dv)) return "NaN"; if (Double.isInfinite(dv)) return "Inf"; final int precision = ((INumericMetaData) idv.getMetaData()).getPrecision(); final DecimalFormatSymbols dcf = new DecimalFormatSymbols(Locale.US); dcf.setDecimalSeparator('.'); final DecimalFormat format = new DecimalFormat("0.#", dcf); format.setMinimumFractionDigits(precision); format.setMaximumFractionDigits(precision); return format.format(dv); } else if (value instanceof ILongValue) { final ILongValue lv = (ILongValue) value; return Long.toString(lv.getValue()); } else return (value == null) ? "" : value.format(); } }