All Downloads are FREE. Search and download functionalities are using the official Maven repository.

quickfix.field.converter.DoubleConverter Maven / Gradle / Ivy

There is a newer version: 2.3.1
Show newest version
/*******************************************************************************
 * 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 [email protected] if any conditions of this licensing
 * are not clear to you.
 ******************************************************************************/

package quickfix.field.converter;

import quickfix.FieldConvertError;
import quickfix.RuntimeError;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

/**
 * Converts between a double and a String.
 */
public class DoubleConverter {
    private static final ThreadLocal THREAD_DECIMAL_FORMATS = new ThreadLocal<>();

    /**
     * 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 = THREAD_DECIMAL_FORMATS.get();
        if (decimalFormats == null) {
            decimalFormats = new DecimalFormat[14];
            THREAD_DECIMAL_FORMATS.set(decimalFormats);
        }
        DecimalFormat f = decimalFormats[padding];
        if (f == null) {
            StringBuilder buffer = new StringBuilder("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 {
            return parseDouble(value);
        } catch (NumberFormatException e) {
            throw new FieldConvertError("invalid double value: " + value);
        }
    }

    private static double parseDouble(String value) {
        if(value.length() == 0) throw new NumberFormatException(value);
        boolean dot = false; int i = 0;
        char c = value.charAt(i);
        switch (c) {
            case '-': i++; break;
            case '+': throw new NumberFormatException(value);
        }
        for (; i < value.length(); i++) {
            c = value.charAt(i);
            if (!dot && c == '.') dot = true;
            else if (c < '0' || c > '9') throw new NumberFormatException(value);
        }
        return Double.parseDouble(value);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy