Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/quickfix-j/quickfixj
Browse files Browse the repository at this point in the history
  • Loading branch information
david-gibbs-ig committed Dec 10, 2022
2 parents a04da12 + 5986864 commit e5391c9
Show file tree
Hide file tree
Showing 15 changed files with 297 additions and 201 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jdkLevel>1.8</jdkLevel>
<slf4j.version>2.0.3</slf4j.version>
<slf4j.version>2.0.5</slf4j.version>
<junit.version>4.13.2</junit.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
Expand Down
2 changes: 1 addition & 1 deletion quickfixj-codegenerator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
</plugin>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.4</version>
<version>3.7.0</version>
</plugin>
</plugins>
</build>
Expand Down
2 changes: 1 addition & 1 deletion quickfixj-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.5</version>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
2 changes: 1 addition & 1 deletion quickfixj-core/src/main/java/quickfix/FieldMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ public void setField(int key, Field<?> field) {

public void setField(StringField field) {
if (field.getValue() == null) {
throw new NullPointerException("Null field values are not allowed.");
throw new FieldException(SessionRejectReason.TAG_SPECIFIED_WITHOUT_A_VALUE, field.getField());
}
fields.put(field.getField(), field);
}
Expand Down
17 changes: 10 additions & 7 deletions quickfixj-core/src/main/java/quickfix/NumbersCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,21 @@ public final class NumbersCache {

static {
LITTLE_NUMBERS = new ArrayList<>(LITTLE_NUMBERS_LENGTH);
for (int i = 0; i < LITTLE_NUMBERS_LENGTH; i++)
for (int i = 0; i < LITTLE_NUMBERS_LENGTH; i++) {
LITTLE_NUMBERS.add(Integer.toString(i));
}
}

/**
* Get the String representing the given number
*
* @param i the long to convert
* @return the String representing the long
* @param i the int to convert
* @return the String representing the integer
*/
public static String get(int i) {
if (i < LITTLE_NUMBERS_LENGTH)
if (i < LITTLE_NUMBERS_LENGTH && i >= 0) {
return LITTLE_NUMBERS.get(i);
}
return String.valueOf(i);
}

Expand All @@ -56,10 +58,11 @@ public static String get(int i) {
* @return the String representing the double or null if the double is not an integer
*/
public static String get(double d) {
long l = (long)d;
if (d == (double)l)
long l = (long) d;
if (d == (double) l) {
return get(l);
}
return null;
}
}

}
15 changes: 5 additions & 10 deletions quickfixj-core/src/main/java/quickfix/SessionSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public SessionSettings(Properties variableValues) {
*
* @param filename the path to the file containing the session settings
* @param variableValues custom source of variable values in the settings
* @throws quickfix.ConfigError when file could not be loaded
* @throws ConfigError when file could not be loaded
*/
public SessionSettings(String filename, Properties variableValues) throws ConfigError {
this(variableValues);
Expand All @@ -122,7 +122,7 @@ public SessionSettings(String filename, Properties variableValues) throws Config
* Loads session settings from a file.
*
* @param filename the path to the file containing the session settings
* @throws quickfix.ConfigError when file could not be loaded
* @throws ConfigError when file could not be loaded
*/
public SessionSettings(String filename) throws ConfigError {
this();
Expand Down Expand Up @@ -365,12 +365,8 @@ public boolean getBool(String key) throws ConfigError, FieldConvertError {
* @throws ConfigError configuration error, probably a missing setting.
* @throws FieldConvertError error during field type conversion.
*/
public boolean getBool(SessionID sessionID, String key) throws ConfigError, FieldConvertError {
try {
return BooleanConverter.convert(getString(sessionID, key));
} catch (final FieldConvertError e) {
throw new ConfigError(e);
}
public boolean getBool(SessionID sessionID, String key) throws FieldConvertError, ConfigError {
return BooleanConverter.convert(getString(sessionID, key));
}

/**
Expand Down Expand Up @@ -472,8 +468,7 @@ private void load(InputStream inputStream) throws ConfigError {
}
storeSection(currentSectionId, currentSection);
} catch (final IOException e) {
final ConfigError configError = new ConfigError(e.getMessage());
throw configError;
throw new ConfigError(e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected static void assertLength(String value, String type, int... lengths) th
protected static void assertDigitSequence(String value, int i, int j, String type)
throws FieldConvertError {
for (int offset = i; offset < j; offset++) {
if (!Character.isDigit(value.charAt(offset))) {
if (!IntConverter.isDigit(value.charAt(offset))) {
throwFieldConvertError(value, type);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,24 @@
package quickfix.field.converter;

import quickfix.FieldConvertError;
import quickfix.NumbersCache;

/**
* Convert between an integer and a String
*/
public final class IntConverter {

private static final String INT_MAX_STRING = String.valueOf(Integer.MAX_VALUE);

/**
* Convert an integer to a String
*
* @param i the integer to convert
* @return the String representing the integer
* @see java.lang.Long#toString(long)
* @see NumbersCache#get(int)
*/
public static String convert(int i) {
return Long.toString(i);
return NumbersCache.get(i);
}

/**
Expand All @@ -43,22 +46,68 @@ public static String convert(int i) {
* @param value the String to convert
* @return the converted integer
* @throws FieldConvertError raised if the String does not represent a valid
* integer
* FIX integer, i.e. optional negative sign and rest are digits.
* @see java.lang.Integer#parseInt(String)
*/
public static int convert(String value) throws FieldConvertError {
try {
for (int i = 0; i < value.length(); i++) {
if (!Character.isDigit(value.charAt(i)) && !(i == 0 && value.charAt(i) == '-')) {
throw new FieldConvertError("invalid integral value: " + value);

if (!value.isEmpty()) {
final char firstChar = value.charAt(0);
boolean isNegative = (firstChar == '-');
if (!isDigit(firstChar) && !isNegative) {
throw new FieldConvertError("invalid integral value: " + value);
}
int minLength = (isNegative ? 2 : 1);
if (value.length() < minLength) {
throw new FieldConvertError("invalid integral value: " + value);
}

// Heuristic: since we have no range check in our parseInt() we only parse
// values which have at least one digit less than Integer.MAX_VALUE and
// leave longer Strings to Integer.parseInt().
// NB: we must not simply reject strings longer than MAX_VALUE since
// they could possibly include an arbitrary number of leading zeros.
int maxLength = (isNegative ? INT_MAX_STRING.length() : INT_MAX_STRING.length() - 1);
if (value.length() <= maxLength) {
return parseInt(value, isNegative);
} else {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new FieldConvertError("invalid integral value: " + value + ": " + e);
}
}
return Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new FieldConvertError("invalid integral value: " + value + ": " + e);
} else {
throw new FieldConvertError("invalid integral value: empty string");
}
}

/**
* Please note that input needs to be validated first, otherwise unexpected
* results may occur. Please also note that this method has no range or
* overflow check, so please only use it when you are sure that no overflow
* might occur (e.g. for parsing seconds or smaller integers).
*
* This method does however check if the contained characters are digits.
*
* @param value the String to convert
* @param isNegative if passed String is negative, first character will
* be skipped since it is assumed that it contains the negative sign
* @return the converted int
*/
private static int parseInt(String value, boolean isNegative) throws FieldConvertError {
int num = 0;
int firstIndex = (isNegative ? 1 : 0);
for (int i = firstIndex; i < value.length(); i++) {
if (isDigit(value.charAt(i))) {
num = (num * 10) + (value.charAt(i) - '0');
} else {
throw new FieldConvertError("invalid integral value: " + value);
}
}
return isNegative ? -num : num;
}

/**
* Please note that input needs to be validated first, otherwise unexpected
* results may occur. Please also note that this method has no range or overflow
Expand Down Expand Up @@ -106,4 +155,15 @@ static long parseLong(String value) {
}
return negative ? -num : num;
}

/**
* Check if a character is a digit, i.e. in the range between 0 and 9.
*
* @param character character to check
* @return true if character is a digit between 0 and 9
*/
static boolean isDigit(char character) {
return (character >= '0' && character <= '9');
}

}
24 changes: 24 additions & 0 deletions quickfixj-core/src/test/java/quickfix/FieldConvertersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public class FieldConvertersTest {
public void testIntegerConversion() throws Exception {
String intMaxValuePlus3 = "2147483650";
String intMinValueMinus3 = "-2147483651";
String intLargeValue = "999999999";
String intLargeValue2 = "2000000000";
assertEquals(String.valueOf(Integer.MAX_VALUE), IntConverter.convert(Integer.MAX_VALUE));
assertEquals(String.valueOf(Integer.MIN_VALUE), IntConverter.convert(Integer.MIN_VALUE));
assertEquals(999999999, IntConverter.convert(intLargeValue));
assertEquals(2000000000, IntConverter.convert(intLargeValue2));
assertEquals("123", IntConverter.convert(123));
assertEquals(123, IntConverter.convert("123"));
assertEquals(-1, IntConverter.convert("-1"));
Expand Down Expand Up @@ -91,6 +97,24 @@ public void testIntegerConversion() throws Exception {
} catch (FieldConvertError e) {
// expected
}
try {
IntConverter.convert("");
fail();
} catch (FieldConvertError e) {
// expected
}
try {
IntConverter.convert("-");
fail();
} catch (FieldConvertError e) {
// expected
}
try {
IntConverter.convert("+");
fail();
} catch (FieldConvertError e) {
// expected
}
}

@Test
Expand Down
40 changes: 24 additions & 16 deletions quickfixj-core/src/test/java/quickfix/FieldMapTest.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package quickfix;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import org.junit.Test;
import quickfix.field.EffectiveTime;
import quickfix.field.MDEntryTime;
import quickfix.field.converter.UtcTimeOnlyConverter;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.Iterator;
import java.util.Optional;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
* Tests the {@link FieldMap} class.
Expand Down Expand Up @@ -79,16 +80,16 @@ private void testOrdering(int[] vals, int[] order, int[] expected) {

@Test
public void testOrdering() {
testOrdering(new int[] { 1, 2, 3 }, null, new int[] { 1, 2, 3 });
testOrdering(new int[] { 3, 2, 1 }, null, new int[] { 1, 2, 3 });
testOrdering(new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 });
testOrdering(new int[] { 3, 2, 1 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 });
testOrdering(new int[] { 1, 2, 3 }, new int[] { 1, 3, 2 }, new int[] { 1, 3, 2 });
testOrdering(new int[] { 3, 2, 1 }, new int[] { 1, 3, 2 }, new int[] { 1, 3, 2 });
testOrdering(new int[] { 1, 2, 3 }, new int[] { 1, 3 }, new int[] { 1, 3, 2 });
testOrdering(new int[] { 3, 2, 1 }, new int[] { 1, 3 }, new int[] { 1, 3, 2 });
testOrdering(new int[] { 1, 2, 3 }, new int[] { 3, 1 }, new int[] { 3, 1, 2 });
testOrdering(new int[] { 3, 2, 1 }, new int[] { 3, 1 }, new int[] { 3, 1, 2 });
testOrdering(new int[]{1, 2, 3}, null, new int[]{1, 2, 3});
testOrdering(new int[]{3, 2, 1}, null, new int[]{1, 2, 3});
testOrdering(new int[]{1, 2, 3}, new int[]{1, 2, 3}, new int[]{1, 2, 3});
testOrdering(new int[]{3, 2, 1}, new int[]{1, 2, 3}, new int[]{1, 2, 3});
testOrdering(new int[]{1, 2, 3}, new int[]{1, 3, 2}, new int[]{1, 3, 2});
testOrdering(new int[]{3, 2, 1}, new int[]{1, 3, 2}, new int[]{1, 3, 2});
testOrdering(new int[]{1, 2, 3}, new int[]{1, 3}, new int[]{1, 3, 2});
testOrdering(new int[]{3, 2, 1}, new int[]{1, 3}, new int[]{1, 3, 2});
testOrdering(new int[]{1, 2, 3}, new int[]{3, 1}, new int[]{3, 1, 2});
testOrdering(new int[]{3, 2, 1}, new int[]{3, 1}, new int[]{3, 1, 2});
}

@Test
Expand All @@ -111,14 +112,21 @@ public void testOptionalDecimal() {
assertFalse(map.getOptionalDecimal(6).isPresent());
}

@Test
public void testNullFieldException() {
FieldMap map = new Message();
StringField field = new StringField(0, null);
assertThrows(FieldException.class, () -> map.setField(field));
}

private long epochMilliOfLocalDate(LocalDateTime localDateTime) {
return localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
}

@Test
public void testRemoveGroup() {
FieldMap map = new Message();
Group group = new Group(73,11);
Group group = new Group(73, 11);
map.addGroup(group);
assertTrue(map.hasGroup(73));
map.removeGroup(73);
Expand Down
Loading

0 comments on commit e5391c9

Please sign in to comment.