diff --git a/quickfixj-core/src/main/java/quickfix/CachedFileStore.java b/quickfixj-core/src/main/java/quickfix/CachedFileStore.java index 6ea5d0170..494b3cef1 100644 --- a/quickfixj-core/src/main/java/quickfix/CachedFileStore.java +++ b/quickfixj-core/src/main/java/quickfix/CachedFileStore.java @@ -28,6 +28,7 @@ import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -86,8 +87,6 @@ public class CachedFileStore implements MessageStore { private FileOutputStream headerFileOutputStream; - private final String charsetEncoding = CharsetSupport.getCharset(); - CachedFileStore(String path, SessionID sessionID, boolean syncWrites) throws IOException { this.syncWrites = syncWrites; @@ -308,16 +307,15 @@ public boolean get(int sequence, String message) { throw new UnsupportedOperationException("not supported"); } - private String read(long offset, long size) throws IOException { - final byte[] data = new byte[(int) size]; - - messageFileReader.seek(offset); - if (messageFileReader.read(data) != size) { - throw new IOException("Truncated input while reading message: " - + new String(data, charsetEncoding)); + private String read(long offset, int size) throws IOException { + try { + final byte[] data = new byte[size]; + messageFileReader.seek(offset); + messageFileReader.readFully(data); + return new String(data, CharsetSupport.getCharset()); + } catch (EOFException eofe) { // can't read fully + throw new IOException("Truncated input while reading message: offset=" + offset + ", expected size=" + size, eofe); } - - return new String(data, charsetEncoding); } private Collection getMessage(long startSequence, long endSequence) throws IOException { @@ -326,7 +324,7 @@ private Collection getMessage(long startSequence, long endSequence) thro final List offsetAndSizes = messageIndex.get(startSequence, endSequence); for (final long[] offsetAndSize : offsetAndSizes) { if (offsetAndSize != null) { - final String message = read(offsetAndSize[0], offsetAndSize[1]); + final String message = read(offsetAndSize[0], (int) offsetAndSize[1]); messages.add(message); } } @@ -341,7 +339,8 @@ private Collection getMessage(long startSequence, long endSequence) thro */ public boolean set(int sequence, String message) throws IOException { final long offset = messageFileWriter.getFilePointer(); - final int size = message.length(); + final byte[] messageBytes = message.getBytes(CharsetSupport.getCharset()); + final int size = messageBytes.length; messageIndex.put((long) sequence, new long[] { offset, size }); headerDataOutputStream.writeInt(sequence); headerDataOutputStream.writeLong(offset); @@ -350,7 +349,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; } diff --git a/quickfixj-core/src/main/java/quickfix/FileStore.java b/quickfixj-core/src/main/java/quickfix/FileStore.java index bbee97f01..0b4cf6b6e 100644 --- a/quickfixj-core/src/main/java/quickfix/FileStore.java +++ b/quickfixj-core/src/main/java/quickfix/FileStore.java @@ -362,7 +362,7 @@ 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(); - byte[] messageBytes = message.getBytes(CharsetSupport.getCharset()); + final byte[] messageBytes = message.getBytes(CharsetSupport.getCharset()); final int size = messageBytes.length; if (messageIndex != null) { updateMessageIndex(sequence, offset, size); diff --git a/quickfixj-core/src/test/java/quickfix/AbstractMessageStoreTest.java b/quickfixj-core/src/test/java/quickfix/AbstractMessageStoreTest.java index 06d93ba4d..40632bc47 100644 --- a/quickfixj-core/src/test/java/quickfix/AbstractMessageStoreTest.java +++ b/quickfixj-core/src/test/java/quickfix/AbstractMessageStoreTest.java @@ -20,11 +20,14 @@ package quickfix; import junit.framework.TestCase; +import org.quickfixj.CharsetSupport; import java.io.IOException; import java.util.ArrayList; +import java.util.List; public abstract class AbstractMessageStoreTest extends TestCase { + private SessionID sessionID; private MessageStore store; @@ -167,6 +170,44 @@ public void testRefreshMessageStore() throws Exception { } } + public void testSetAndGetMessageWithAsciiCharacters() throws IOException { + MessageStore underTest = getStore(); + + if (underTest instanceof SleepycatStore) { + return; + } + + underTest.set(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789"); + + List messages = new ArrayList<>(); + underTest.get(1, 1, messages); + + assertEquals(1, messages.size()); + assertEquals("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789", messages.get(0)); + } + + public void testSetAndGetMessageWithUnicodeCharacters() throws IOException { + MessageStore underTest = getStore(); + + if (underTest instanceof SleepycatStore) { + return; + } + + CharsetSupport.setCharset("UTF-8"); + + try { + underTest.set(1, "a \u00A9 \u2603 \uD834\uDF06"); + + List messages = new ArrayList<>(); + underTest.get(1, 1, messages); + + assertEquals(1, messages.size()); + assertEquals("a \u00A9 \u2603 \uD834\uDF06", messages.get(0)); + } finally { + CharsetSupport.setDefaultCharset(); + } + } + protected void closeMessageStore(MessageStore store) throws IOException { // does nothing, by default } diff --git a/quickfixj-core/src/test/java/quickfix/FileStoreTest.java b/quickfixj-core/src/test/java/quickfix/FileStoreTest.java index c54cedee3..08b09c25d 100644 --- a/quickfixj-core/src/test/java/quickfix/FileStoreTest.java +++ b/quickfixj-core/src/test/java/quickfix/FileStoreTest.java @@ -123,28 +123,4 @@ public void testResetShouldNeverFail() throws Exception { thread.interrupt(); thread.join(); } - - public void testSetAndGetMessageWithAsciiCharacters() throws IOException { - MessageStore underTest = getStore(); - underTest.set(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789"); - - List 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 messages = new ArrayList<>(); - underTest.get(1, 1, messages); - - assertEquals(1, messages.size()); - assertEquals("a \u00A9 \u2603 \uD834\uDF06", messages.get(0)); - } } diff --git a/quickfixj-core/src/test/java/quickfix/SleepycatStoreTest.java b/quickfixj-core/src/test/java/quickfix/SleepycatStoreTest.java index ec84e6a9b..fd3bf2380 100644 --- a/quickfixj-core/src/test/java/quickfix/SleepycatStoreTest.java +++ b/quickfixj-core/src/test/java/quickfix/SleepycatStoreTest.java @@ -23,7 +23,8 @@ import java.io.IOException; public class SleepycatStoreTest extends AbstractMessageStoreTest { - protected MessageStoreFactory getMessageStoreFactory() throws ConfigError, FieldConvertError { + + protected MessageStoreFactory getMessageStoreFactory() throws ConfigError { SessionSettings settings = new SessionSettings(getConfigurationFileName()); File tmpfile; try { @@ -62,5 +63,4 @@ public void testCloseAndOpen() throws Exception { assertEquals(123, store.getNextSenderMsgSeqNum()); assertEquals(321, store.getNextTargetMsgSeqNum()); } - }