Skip to content

Commit 8f87ac8

Browse files
committed
Refactored and cleaned up encoder and decoder
1 parent dcc0ce0 commit 8f87ac8

File tree

2 files changed

+47
-60
lines changed

2 files changed

+47
-60
lines changed

quickfixj-core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java

+30-40
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
public class FIXMessageDecoder implements MessageDecoder {
4949

5050
private static final char SOH = '\001';
51-
private static final String FIELD_DELIMITER = String.valueOf(SOH);
5251

5352
private final Logger log = LoggerFactory.getLogger(getClass());
5453

@@ -78,11 +77,11 @@ private void resetState() {
7877
}
7978

8079
public FIXMessageDecoder() throws UnsupportedEncodingException {
81-
this(CharsetSupport.getCharset(), FIELD_DELIMITER);
80+
this(CharsetSupport.getCharset());
8281
}
8382

8483
public FIXMessageDecoder(String charset) throws UnsupportedEncodingException {
85-
this(charset, FIELD_DELIMITER);
84+
this(charset, String.valueOf(SOH));
8685
}
8786

8887
public FIXMessageDecoder(String charset, String delimiter) throws UnsupportedEncodingException {
@@ -93,12 +92,14 @@ public FIXMessageDecoder(String charset, String delimiter) throws UnsupportedEnc
9392
resetState();
9493
}
9594

95+
@Override
9696
public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
9797
boolean hasHeader = HEADER_PATTERN.find(in, in.position()) != -1L;
9898
return hasHeader ? MessageDecoderResult.OK :
9999
(in.remaining() > MAX_UNDECODED_DATA_LENGTH ? MessageDecoderResult.NOT_OK : MessageDecoderResult.NEED_DATA);
100100
}
101101

102+
@Override
102103
public MessageDecoderResult decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
103104
throws ProtocolCodecException {
104105
int messageCount = 0;
@@ -148,9 +149,9 @@ private boolean parseMessage(IoBuffer in, ProtocolDecoderOutput out)
148149

149150
if (state == PARSING_LENGTH) {
150151
byte ch = 0;
151-
while (hasRemaining(in)) {
152-
ch = get(in);
153-
if (!Character.isDigit((char) ch)) {
152+
while (position < in.limit()) { // while data remains
153+
ch = in.get(position++);
154+
if (ch < '0' || ch > '9') { // if not digit
154155
break;
155156
}
156157
bodyLength = bodyLength * 10 + (ch - '0');
@@ -161,7 +162,7 @@ private boolean parseMessage(IoBuffer in, ProtocolDecoderOutput out)
161162
log.debug("body length = " + bodyLength + ": " + getBufferDebugInfo(in));
162163
}
163164
} else {
164-
if (hasRemaining(in)) {
165+
if (position < in.limit()) { // if data remains
165166
String messageString = getMessageStringForError(in);
166167
handleError(in, in.position() + 1, "Length format error in message (last character:" + ch + "): " + messageString,
167168
false);
@@ -173,7 +174,7 @@ private boolean parseMessage(IoBuffer in, ProtocolDecoderOutput out)
173174
}
174175

175176
if (state == READING_BODY) {
176-
if (remaining(in) < bodyLength) {
177+
if (in.limit() - position < bodyLength) { // if remaining data is less than body
177178
break;
178179
}
179180
position += bodyLength;
@@ -223,9 +224,7 @@ private boolean parseMessage(IoBuffer in, ProtocolDecoderOutput out)
223224
}
224225
return messageFound;
225226
} catch (Throwable t) {
226-
state = SEEKING_HEADER;
227-
position = 0;
228-
bodyLength = 0;
227+
resetState();
229228
if (t instanceof ProtocolCodecException) {
230229
throw (ProtocolCodecException) t;
231230
} else {
@@ -234,23 +233,11 @@ private boolean parseMessage(IoBuffer in, ProtocolDecoderOutput out)
234233
}
235234
}
236235

237-
private int remaining(IoBuffer in) {
238-
return in.limit() - position;
239-
}
240-
241236
private String getBufferDebugInfo(IoBuffer in) {
242237
return "pos=" + in.position() + ",lim=" + in.limit() + ",rem=" + in.remaining()
243238
+ ",offset=" + position + ",state=" + state;
244239
}
245240

246-
private byte get(IoBuffer in) {
247-
return in.get(position++);
248-
}
249-
250-
private boolean hasRemaining(IoBuffer in) {
251-
return position < in.limit();
252-
}
253-
254241
private String getMessageString(IoBuffer buffer) throws UnsupportedEncodingException {
255242
byte[] data = new byte[position - buffer.position()];
256243
buffer.get(data);
@@ -282,7 +269,8 @@ private boolean isLogon(IoBuffer buffer) {
282269
return LOGON_PATTERN.find(buffer, buffer.position()) != -1L;
283270
}
284271

285-
public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1) throws Exception {
272+
@Override
273+
public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
286274
// empty
287275
}
288276

@@ -309,6 +297,7 @@ public interface MessageListener {
309297
public List<String> extractMessages(File file) throws IOException, ProtocolCodecException {
310298
final List<String> messages = new ArrayList<String>();
311299
extractMessages(file, new MessageListener() {
300+
@Override
312301
public void onMessage(String message) {
313302
messages.add(message);
314303
}
@@ -331,22 +320,23 @@ public void extractMessages(File file, final MessageListener listener) throws IO
331320
ProtocolCodecException {
332321
// Set up a read-only memory-mapped file
333322
RandomAccessFile fileIn = new RandomAccessFile(file, "r");
334-
FileChannel readOnlyChannel = fileIn.getChannel();
335-
MappedByteBuffer memoryMappedBuffer = readOnlyChannel.map(FileChannel.MapMode.READ_ONLY, 0,
336-
(int) readOnlyChannel.size());
337-
338-
decode(null, IoBuffer.wrap(memoryMappedBuffer), new ProtocolDecoderOutput() {
339-
340-
public void write(Object message) {
341-
listener.onMessage((String) message);
342-
}
343-
344-
public void flush(IoFilter.NextFilter nextFilter, IoSession ioSession) {
345-
// ignored
346-
}
347-
});
348-
readOnlyChannel.close();
349-
fileIn.close();
323+
try {
324+
FileChannel readOnlyChannel = fileIn.getChannel();
325+
MappedByteBuffer memoryMappedBuffer = readOnlyChannel.map(FileChannel.MapMode.READ_ONLY, 0,
326+
(int) readOnlyChannel.size());
327+
decode(null, IoBuffer.wrap(memoryMappedBuffer), new ProtocolDecoderOutput() {
328+
@Override
329+
public void write(Object message) {
330+
listener.onMessage((String) message);
331+
}
332+
@Override
333+
public void flush(IoFilter.NextFilter nextFilter, IoSession ioSession) {
334+
// ignored
335+
}
336+
});
337+
} finally {
338+
fileIn.close();
339+
}
350340
}
351341

352342
}

quickfixj-core/src/main/java/quickfix/mina/message/FIXMessageEncoder.java

+17-20
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
package quickfix.mina.message;
2121

2222
import java.io.UnsupportedEncodingException;
23-
import java.util.Collections;
23+
import java.util.Arrays;
2424
import java.util.HashSet;
2525
import java.util.Set;
2626

@@ -39,16 +39,10 @@
3939
*/
4040
public class FIXMessageEncoder implements MessageEncoder<Object> {
4141

42-
private static final Set<Class<?>> TYPES;
42+
private static final Set<Class<?>> TYPES =
43+
new HashSet<>(Arrays.<Class<?>>asList(Message.class, String.class));
4344
private final String charsetEncoding;
4445

45-
static {
46-
Set<Class<?>> types = new HashSet<Class<?>>();
47-
types.add(Message.class);
48-
types.add(String.class);
49-
TYPES = Collections.unmodifiableSet(types);
50-
}
51-
5246
public FIXMessageEncoder() {
5347
charsetEncoding = CharsetSupport.getCharset();
5448
}
@@ -57,25 +51,28 @@ public static Set<Class<?>> getMessageTypes() {
5751
return TYPES;
5852
}
5953

54+
private byte[] toBytes(String str) throws ProtocolCodecException {
55+
try {
56+
return str.getBytes(charsetEncoding);
57+
} catch (UnsupportedEncodingException e) {
58+
throw new ProtocolCodecException(e);
59+
}
60+
}
61+
62+
@Override
6063
public void encode(IoSession session, Object message, ProtocolEncoderOutput out)
6164
throws ProtocolCodecException {
62-
String fixMessageString;
65+
// get message bytes
66+
byte[] bytes;
6367
if (message instanceof String) {
64-
fixMessageString = (String) message;
68+
bytes = toBytes((String) message);
6569
} else if (message instanceof Message) {
66-
fixMessageString = message.toString();
70+
bytes = toBytes(message.toString());
6771
} else {
6872
throw new ProtocolCodecException("Invalid FIX message object type: "
6973
+ message.getClass());
7074
}
71-
72-
byte[] bytes;
73-
try {
74-
bytes = fixMessageString.getBytes(charsetEncoding);
75-
} catch (UnsupportedEncodingException e) {
76-
throw new ProtocolCodecException(e);
77-
}
78-
75+
// write bytes to buffer and output it
7976
IoBuffer buffer = IoBuffer.allocate(bytes.length);
8077
buffer.put(bytes);
8178
buffer.flip();

0 commit comments

Comments
 (0)