/******************************************************************************* * Copyright (c) quickfixengine.org All rights reserved. * * This file is part of the QuickFIX FIX Engine * * This file may be distributed under the terms of the quickfixengine.org * license as defined by quickfixengine.org and appearing in the file * LICENSE included in the packaging of this file. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. * * See http://www.quickfixengine.org/LICENSE for licensing information. * * Contact ask@quickfixengine.org if any conditions of this licensing * are not clear to you. ******************************************************************************/ package quickfix.field.converter; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import quickfix.FieldConvertError; import quickfix.RuntimeError; /** * Converts between a double and a String. */ public class DoubleConverter { private static final Pattern decimalPattern = Pattern.compile("-?\\d*(\\.\\d*)?"); private static ThreadLocal<DecimalFormat[]> threadDecimalFormats = new ThreadLocal<DecimalFormat[]>(); /** * Converts a double to a string with no padding. * @param d the double to convert * @return the formatted String representing the double. * @see #convert(double, int) */ public static String convert(double d) { return convert(d, 0); } static DecimalFormat getDecimalFormat(int padding) { if (padding > 14) { // FieldConvertError not supported in setDouble methods on Message throw new RuntimeError("maximum padding of 14 zeroes is supported: " + padding); } DecimalFormat[] decimalFormats = threadDecimalFormats.get(); if (decimalFormats == null) { decimalFormats = new DecimalFormat[14]; threadDecimalFormats.set(decimalFormats); } DecimalFormat f = decimalFormats[padding]; if (f == null) { StringBuffer buffer = new StringBuffer("0."); for (int i = 0; i < padding; i++) { buffer.append('0'); } for (int i = padding; i < 14; i++) { buffer.append('#'); } f = new DecimalFormat(buffer.toString()); f.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); decimalFormats[padding] = f; } return f; } /** * Converts a double to a string with padding. * @param d the double to convert * @param padding the number of zeros to add to end of the formatted double * @return the formatted String representing the double. */ public static String convert(double d, int padding) { return getDecimalFormat(padding).format(d); } /** * Convert a String value to a double. * @param value the String value to convert * @return the parsed double * @throws FieldConvertError if the String is not a valid double pattern. */ public static double convert(String value) throws FieldConvertError { try { Matcher matcher = decimalPattern.matcher(value); if (!matcher.matches()) { throw new NumberFormatException(); } return Double.parseDouble(value); } catch (NumberFormatException e) { throw new FieldConvertError("invalid double value: " + value); } } }