Skip to content

Commit

Permalink
650 - filestore message length fix
Browse files Browse the repository at this point in the history
  • Loading branch information
the-thing committed Dec 7, 2023
1 parent 8cf71f9 commit 8bae003
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public static void setCharset(String charset) throws UnsupportedEncodingExceptio
CharsetSupport.isStringEquivalent = isStringEquivalent(charsetInstance);
}

public static void setDefaultCharset() throws UnsupportedEncodingException {
setCharset(getDefaultCharset());
}

public static String getCharset() {
return charset;
}
Expand Down
8 changes: 4 additions & 4 deletions quickfixj-core/src/main/java/quickfix/FileStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public class FileStore implements MessageStore, Closeable {
private final String sessionFileName;
private final boolean syncWrites;
private final int maxCachedMsgs;
private final String charsetEncoding = CharsetSupport.getCharset();
private RandomAccessFile messageFileReader;
private RandomAccessFile messageFileWriter;
private DataOutputStream headerDataOutputStream;
Expand Down Expand Up @@ -350,7 +349,7 @@ private String getMessage(long offset, int size, int i) throws IOException {
final byte[] data = new byte[size];
messageFileReader.seek(offset);
messageFileReader.readFully(data);
return new String(data, charsetEncoding);
return new String(data, CharsetSupport.getCharset());
} catch (EOFException eofe) { // can't read fully
throw new IOException("Truncated input while reading message: messageIndex=" + i
+ ", offset=" + offset + ", expected size=" + size, eofe);
Expand All @@ -363,7 +362,8 @@ private String getMessage(long offset, int size, int i) throws IOException {
@Override
public boolean set(int sequence, String message) throws IOException {
final long offset = messageFileWriter.getFilePointer();
final int size = message.length();
byte[] messageBytes = message.getBytes(CharsetSupport.getCharset());
final int size = messageBytes.length;
if (messageIndex != null) {
updateMessageIndex(sequence, offset, size);
}
Expand All @@ -374,7 +374,7 @@ public boolean set(int sequence, String message) throws IOException {
if (syncWrites) {
headerFileOutputStream.getFD().sync();
}
messageFileWriter.write(message.getBytes(CharsetSupport.getCharset()));
messageFileWriter.write(messageBytes);
return true;
}

Expand Down
179 changes: 179 additions & 0 deletions quickfixj-core/src/test/java/quickfix/FieldTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,185 @@ public void testMessageSetGetString() {
assertEquals(side1, side2);
}

private void testFieldCalcuations(String value, int checksum, int length) {
Field<String> field = new Field<>(12, value);
field.setObject(value);
assertEquals("12=" + value, field.toString());
assertEquals(checksum, field.getChecksum());
assertEquals(length, field.getLength());

value = value.substring(0, value.length() - 1) + (char)(value.charAt(value.length() - 1) + 1);
checksum = (checksum + 1) & 0xFF;
field.setObject(value);
assertEquals("12=" + value, field.toString());
assertEquals(checksum, field.getChecksum());
assertEquals(length, field.getLength());

field.setTag(13);
checksum = (checksum + 1) & 0xFF;
assertEquals("13=" + value, field.toString());
assertEquals(checksum, field.getChecksum());
assertEquals(length, field.getLength());
}

@Test
public void testFieldCalculationsWithDefaultCharset() {
testFieldCalcuations("VALUE", 30, 9);
}

@Test
public void testFieldCalculationsWithUTF8Charset() throws UnsupportedEncodingException {
CharsetSupport.setCharset("UTF-8");
try {
testFieldCalcuations("\u6D4B\u9A8C\u6570\u636E", 50, 16);
} finally {
CharsetSupport.setDefaultCharset();
}
}

@Test
public void testDateField() {
DateField field = new DateField(11);
Date date = new Date();
field.setValue(date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
field = new DateField(11, date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
}

@Test
public void testUtcDateOnlyField() {
UtcDateOnlyField field = new UtcDateOnlyField(11);
LocalDate date = LocalDate.now();
field.setValue(date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
field = new UtcDateOnlyField(11, date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
}

@Test
public void testUtcTimeOnlyField() {
UtcTimeOnlyField field = new UtcTimeOnlyField(11);
LocalTime date = LocalTime.now();
field.setValue(date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
field = new UtcTimeOnlyField(11, date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
}

@Test
public void testUtcTimeStampField() {
UtcTimeStampField field = new UtcTimeStampField(11);
LocalDateTime date = LocalDateTime.now();
field.setValue(date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
field = new UtcTimeStampField(11, date);
assertEquals(11, field.getTag());
assertEquals(date, field.getValue());
}

@Test
public void testBooleanField() {
BooleanField field = new BooleanField(11);
field.setValue(true);
assertEquals(11, field.getTag());
assertTrue(field.getValue());
field.setValue(Boolean.FALSE);
assertEquals(11, field.getTag());
assertFalse(field.getValue());
field = new BooleanField(22, true);
assertEquals(22, field.getTag());
assertTrue(field.getValue());
field = new BooleanField(33, Boolean.TRUE);
assertEquals(33, field.getTag());
assertTrue(field.getValue());
}

@Test
public void testDoubleField() {
DoubleField field = new DoubleField(11);
field.setValue(12.3);
assertEquals(11, field.getTag());
assertEquals(12.3, field.getValue(), 0);
field.setValue(new Double(23.4));
assertEquals(11, field.getTag());
assertEquals(23.4, field.getValue(), 0);
field = new DoubleField(22, 34.5);
assertEquals(22, field.getTag());
assertEquals(34.5, field.getValue(), 0);
field = new DoubleField(33, new Double(45.6));
assertEquals(33, field.getTag());
assertEquals(45.6, field.getValue(), 0);
}

@Test(expected = NumberFormatException.class)
public void testDoubleFieldException() {
DoubleField field = new DoubleField(11, Double.NaN);
}

@Test
public void testDecimalField() {
DecimalField field = new DecimalField(11);
field.setValue(12.3);
assertEquals(11, field.getTag());
assertEquals(BigDecimal.valueOf(12.3), field.getValue());
field.setValue(23.4);
assertEquals(11, field.getTag());
assertEquals(BigDecimal.valueOf(23.4), field.getValue());
field = new DecimalField(22, 34.5);
assertEquals(22, field.getTag());
assertEquals(BigDecimal.valueOf(34.5), field.getValue());
field = new DecimalField(33, 45.6);
assertEquals(33, field.getTag());
assertEquals(BigDecimal.valueOf(45.6), field.getValue());
}

@Test(expected = NumberFormatException.class)
public void testDecimalFieldException() {
DecimalField field = new DecimalField(11, Double.POSITIVE_INFINITY);
}

@Test
public void testCharField() {
CharField field = new CharField(11);
field.setValue('x');
assertEquals(11, field.getTag());
assertEquals('x', field.getValue());
field.setValue(Character.valueOf('X'));
assertEquals(11, field.getTag());
assertEquals('X', field.getValue());
field = new CharField(22, 'a');
assertEquals(22, field.getTag());
assertEquals('a', field.getValue());
field = new CharField(33, Character.valueOf('A'));
assertEquals(33, field.getTag());
assertEquals('A', field.getValue());
}

@Test
public void testIntField() {
IntField field = new IntField(11);
field.setValue(12);
assertEquals(11, field.getTag());
assertEquals(12, field.getValue());
field.setValue(Integer.valueOf(23));
assertEquals(11, field.getTag());
assertEquals(23, field.getValue());
field = new IntField(22, 23);
assertEquals(22, field.getTag());
assertEquals(23, field.getValue());
field = new IntField(33, Integer.valueOf(44));
assertEquals(33, field.getTag());
assertEquals(44, field.getValue());
}

@Test
public void testBytesField() {
byte[] data = "rawdata".getBytes();
Expand Down
31 changes: 30 additions & 1 deletion quickfixj-core/src/test/java/quickfix/FileStoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@

package quickfix;

import org.quickfixj.CharsetSupport;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class FileStoreTest extends AbstractMessageStoreTest {

protected void tearDown() throws Exception {
public void tearDown() throws Exception {
super.tearDown();
CharsetSupport.setDefaultCharset();
FileStore fileStore = (FileStore) getStore();
try {
fileStore.closeAndDeleteFiles();
Expand All @@ -36,6 +39,7 @@ protected void tearDown() throws Exception {
}
}

@Override
protected MessageStoreFactory getMessageStoreFactory() throws ConfigError, FieldConvertError {
SessionSettings settings = new SessionSettings(getConfigurationFileName());
// Initialize the session settings from the defaults
Expand All @@ -44,6 +48,7 @@ protected MessageStoreFactory getMessageStoreFactory() throws ConfigError, Field
return new FileStoreFactory(settings);
}

@Override
protected Class<?> getMessageStoreClass() {
return FileStore.class;
}
Expand Down Expand Up @@ -118,4 +123,28 @@ public void testResetShouldNeverFail() throws Exception {
thread.interrupt();
thread.join();
}

public void testSetAndGetMessageWithAsciiCharacters() throws IOException {
MessageStore underTest = getStore();
underTest.set(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789");

List<String> messages = new ArrayList<>();
underTest.get(1, 1, messages);

assertEquals(1, messages.size());
assertEquals("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789", messages.get(0));
}

public void testSetAndGetMessageWithUnicodeCharacters() throws IOException {
CharsetSupport.setCharset("UTF-8");

MessageStore underTest = getStore();
underTest.set(1, "a \u00A9 \u2603 \uD834\uDF06");

List<String> messages = new ArrayList<>();
underTest.get(1, 1, messages);

assertEquals(1, messages.size());
assertEquals("a \u00A9 \u2603 \uD834\uDF06", messages.get(0));
}
}
2 changes: 1 addition & 1 deletion quickfixj-core/src/test/java/quickfix/MessageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ private void doTestMessageWithEncodedField(String charset, String text) throws E
final Message msg = new Message(order.toString(), DataDictionaryTest.getDictionary());
assertEquals(charset + " encoded field", text, msg.getString(EncodedText.FIELD));
} finally {
CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
CharsetSupport.setDefaultCharset();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,21 @@ public class FIXMessageDecoderTest {

@Before
public void setUp() throws Exception {
CharsetSupport.setDefaultCharset();
decoder = new FIXMessageDecoder();
buffer = IoBuffer.allocate(8192);
decoderOutput = new ProtocolDecoderOutputForTest();
}

@After
public void tearDown() throws Exception {
CharsetSupport.setDefaultCharset();
buffer.clear();
}

@Test
@Test(expected = UnsupportedEncodingException.class)
public void testInvalidStringCharset() throws Exception {
try {
decoder = new FIXMessageDecoder("BOGUS");
fail("no exception thrown");
} catch (UnsupportedEncodingException e) {
// expected
}
decoder = new FIXMessageDecoder("BOGUS");
}

@Test
Expand Down Expand Up @@ -104,8 +101,6 @@ public void testWesternEuropeanDecoding() throws Exception {
doWesternEuropeanDecodingTest();
} catch (InvalidMessage e) {
// expected
} finally {
CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
}
}

Expand Down
Loading

0 comments on commit 8bae003

Please sign in to comment.