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

com.ddfplus.util.ParserHelper Maven / Gradle / Ivy

There is a newer version: 1.1.7
Show newest version
/**
 * Copyright (C) 2004 - 2015 by Barchart.com, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Barchart.com, Inc.
 * Use is subject to license terms.
 */
package com.ddfplus.util;

import java.awt.event.KeyEvent;
import java.text.NumberFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ddfplus.db.SymbolInfo;

/**
 * The MessageParser class is the central class in the ddf api parsing system.
 * This class contains one key static method: ParseMesasge. This in turn returns
 * a fully parsed Message (subclass) from a given input ddfplus text message.
 */
public final class ParserHelper {

	private static final Logger LOG = LoggerFactory.getLogger(ParserHelper.class);

	/**
	 * Default Value when there is no data. This is not the same as zero (0),
	 * since zero can be a valid value. This constant is an unlikely
	 * number to appear, and therefore occurs if no value exists.
	 */
	public static final int DDFAPI_NOVALUE = 0;

	/**
	 * Specifies Decimal notation.
	 * 
	 * @see #float2string
	 */
	public static final int DECIMAL = 0;

	public static final int PURE_DECIMAL = 3;

	/**
	 * Specifies Dash notation.
	 * 
	 * @see #float2string
	 */
	public static final int DASH = 1;

	/**
	 * Specifies Integer notation.
	 * 
	 * @see #float2string
	 */
	public static final int INTEGER = 2;

	private static final int[] units_f1 = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
	private static final int[] units_f2 = { 8, 16, 32, 64, 128, 256, 512 };
	private static final int[] units_f3 = { 8, 16, 32, 64, 128, 256, 512 };
	private static final int[] units_f4 = { 10, 100, 100, 100, 1000, 1000, 1000 };

	/**
	 * Converts a floating point value into the same String format that the JERQ
	 * servers use to transmit data. The nuance difference is in the INTEGER
	 * value of certain items, such as the 10-Year note, which is transmitted in
	 * 64ths, even though it is displayed in 32nds and halves.
	 */
	public static int float2int(int basecode, float value) {

		float c = value;
		float rf = (float) 0.25;

		if (c < 0)
			rf = (float) -0.25;

		byte tmp = (byte) basecode;

		// The nice thing about futures units > 0 is that
		// they are all decimal, and you don't have to do
		// much with them.
		if (tmp >= 0) {
			float d = c * units_f1[tmp] + rf;
			return (int) d;
		}

		// Now the pain in the ass stuff
		int i = 0 - basecode - 1;
		int ii = units_f3[i];
		int jj = units_f4[i];

		float dd = ((float) 1.0 / units_f2[i]);
		float t = roundFloat(c, dd);
		int n = (int) t;
		int j = (int) ((t - n) * ii + rf);
		if (j >= ii)
			j = jj;

		return (n * jj + j);
	}

	/**
	 * Converts a floating point value into a String that's suitable for client
	 * display.
	 * 

* * @param f * Floating point value * @param basecode * Base Code (a.k.a. unit code) * @param target * The Target Format *

* Target is one of the following constants:
*

    *
  • #DECIMAL - Decimal Notation *
  • #DASH - Dash Notation *
  • #INTEGER - Integer (like dash but no dashes) notation *
*/ public static final String float2string(float f, char basecode, int target) { return float2string(f, basecode, target, true); } private final static NumberFormat NF = NumberFormat.getInstance(); /* * Convert a float to a DDF string. * * TODO Possible optimizations here. */ public synchronized static final String float2string(float value, final char basecode, final int target, final boolean special64) { final int unit = SymbolInfo.ddfuc2bb(basecode); if (unit >= 0) { if (target == PURE_DECIMAL) NF.setGroupingUsed(false); else NF.setGroupingUsed(true); NF.setMinimumFractionDigits(unit); NF.setMaximumFractionDigits(unit); String s = NF.format(value); if (target == INTEGER) { char ca[] = s.toCharArray(); int st = 0; s = ""; for (int i = 0; i < ca.length; i++) { if ((i == 0) && (ca[i] == '+') || (ca[i] == '-')) // A // leading // sign st++; else if ((ca[i] == '0') || (ca[i] == '.')) // Strip all // zeros from // the left st++; else if (Character.isDigit(ca[i])) break; } for (int i = st; i < ca.length; i++) { if (Character.isDigit(ca[i])) s = s + ca[i]; } if ((value == 0.0f) && (s.length() < 1)) s = "0"; if (value < 0) s = "-" + s; return s; } else return s; } if ((target == DECIMAL) || (target == PURE_DECIMAL)) { if (target == PURE_DECIMAL) NF.setGroupingUsed(false); else NF.setGroupingUsed(true); switch (unit) { case -1: NF.setMinimumFractionDigits(3); NF.setMaximumFractionDigits(3); break; case -2: NF.setMinimumFractionDigits(4); NF.setMaximumFractionDigits(4); break; case -3: NF.setMinimumFractionDigits(5); NF.setMaximumFractionDigits(5); break; case -4: NF.setMinimumFractionDigits(6); NF.setMaximumFractionDigits(6); break; case -5: NF.setMinimumFractionDigits(7); NF.setMaximumFractionDigits(7); break; case -6: NF.setMinimumFractionDigits(8); NF.setMaximumFractionDigits(8); break; } return (NF.format(value)); } int sign = 1; if (value < 0.0f) sign = -1; value = Math.abs(value); int iWhole = (int) value; String sw = "" + iWhole; if (sign == -1) sw = "-" + sw; String sf = ""; float div = value - (int) value; int digits = 0; if (unit == -1) { div = div * 8; digits = 1; } else if (unit == -2) { div = div * 16; digits = 2; } else if (unit == -3) { div = div * 32; digits = 2; } else if (unit == -4) { if (special64) { // 64ths --> 32nds and halves div = div * 320; digits = 3; } else { div = div * 64; digits = 2; } } else if (unit == -5) { if (special64) { div = div * 320; digits = 3; } else { div = div * 128; digits = 3; } } else if (unit == -6) { div = div * 256; digits = 3; } else { div = 0; digits = 1; } sf = "00000000" + (int) div; sf = sf.substring(sf.length() - digits, sf.length()); if (target == INTEGER) { if (iWhole != 0) return (sw + sf); else { char c = sw.charAt(0); if (c == '-') return c + sf; else return sf; } } else return sw + "-" + sf; } /** * Specialized method used to round a float to specified number of digits. * Uses casts to eliminate floating point irregularities. */ public static float roundFloat(float r, float rinc) { float t = rinc; if (r < 0) t = -rinc; t = (r + t / (float) 2.0) / rinc; int i = (int) t; float d = rinc * i; return d; } /** * Converts a string representation of the data to a floating point value, * based on the unitcode. */ public static float string2float(String value, char unitcode) throws NumberFormatException { return string2float(value, SymbolInfo.ddfuc2bb(unitcode)); } /** * Converts a string representation of the data to a floating point value, * based on the unitcode. */ public static float string2float(String value, int basecode) throws NumberFormatException { if (value.length() == 0) return DDFAPI_NOVALUE; if (value.equals("-")) return 0; int ival = Integer.parseInt(value); float f = 0; if (basecode >= 0) { f = (ival / (float) Math.pow(10, basecode)); } else { switch (basecode) { case -1: f = (ival / 10) + ((float) (ival % 10) / 8); break; case -2: f = (ival / 100) + ((float) (ival % 100) / 16); break; case -3: f = (ival / 100) + ((float) (ival % 100) / 32); break; case -4: f = (ival / 100) + ((float) (ival % 100) / 64); break; case -5: f = (ival / 1000) + ((float) (ival % 1000) / 128); break; case -6: f = (ival / 1000) + ((float) (ival % 1000) / 256); break; } } return f; } /** * A unified way of converting string values to integer values. */ public static int string2int(String value) { int i = DDFAPI_NOVALUE; if (value.length() == 0) return DDFAPI_NOVALUE; try { i = Integer.parseInt(value); } catch (Exception e) { ; } return i; } public static boolean isPrintableChar(final char c) { final Character.UnicodeBlock block = Character.UnicodeBlock.of(c); return (!Character.isISOControl(c)) && c != KeyEvent.CHAR_UNDEFINED && block != null && block != Character.UnicodeBlock.SPECIALS; } public final static char filterNullChar(final char in) { if (in == ASCII.NUL) { return '?'; } else { return in; } } public final static String toAsciiString(final byte bytes[]) { int size = bytes.length; char[] charArray = new char[size]; for (int k = 0; k < size; k++) { char c = (char) bytes[k]; if (isPrintableChar(c)) { charArray[k] = c; } else { charArray[k] = ASCII.SPACE; } } return new String(charArray); } public final static String toAsciiString2(final byte bytes[]) { int size = bytes.length; char[] charArray = new char[size * 2]; int m = 0; for (int k = 0; k < size; k++) { char c = (char) bytes[k]; charArray[m++] = ASCII.SPACE; if (isPrintableChar(c)) { charArray[m++] = c; } else { charArray[m++] = ASCII.SPACE; } } return new String(charArray); } public final static String toHexString(final byte bytes[]) { if (bytes == null) { return null; } StringBuffer sb = new StringBuffer(); int size = bytes.length; for (int k = 0; k < size; k++) { byte high = (byte) ((bytes[k] & 0xf0) >> 4); byte low = (byte) (bytes[k] & 0x0f); sb.append(nibble2char(high)); sb.append(nibble2char(low)); } return sb.toString(); } private final static char nibble2char(final byte b) { byte nibble = (byte) (b & 0x0f); if (nibble < 10) { return (char) ('0' + nibble); } return (char) ('a' + nibble - 10); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy