Skip to content

Commit

Permalink
Allow setting custom FIX tags in encoders (WIP) real-logic#462
Browse files Browse the repository at this point in the history
  • Loading branch information
pcdv committed Jul 6, 2022
1 parent b1f439d commit eef6555
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 2 deletions.
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Helps IDEA users apply some of the formatting rules enforced by checkstyle

root = true

[*]

[*.java]
indent_size = 4
ij_java_method_brace_style = next_line
ij_java_block_brace_style = next_line
ij_java_class_brace_style = next_line
ij_java_space_after_type_cast = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package uk.co.real_logic.artio.builder;

import uk.co.real_logic.artio.util.MutableAsciiBuffer;

/**
* Class provides common implementation methods used by encoders.
*/
public class CommonEncoderImpl
{
// TODO resizable buffer or way to set a size
protected MutableAsciiBuffer customTagsBuffer = new MutableAsciiBuffer(new byte[64]);

protected int customTagsLength = 0;

private int putTagHeader(final int tag)
{
int pos = customTagsLength;
pos += customTagsBuffer.putIntAscii(pos, tag);
customTagsBuffer.putByte(pos++, (byte)'=');
return pos;
}

public CommonEncoderImpl customTag(final int tag, final int value)
{
int pos = putTagHeader(tag);
pos += customTagsBuffer.putIntAscii(pos, value);
customTagsBuffer.putSeparator(pos++);
customTagsLength = pos;
return this;
}

public CommonEncoderImpl customTagAscii(final int tag, final CharSequence value)
{
int pos = putTagHeader(tag);
pos += customTagsBuffer.putStringWithoutLengthAscii(pos, value);
customTagsBuffer.putSeparator(pos++);
customTagsLength = pos;
return this;
}

public void resetCustomTags()
{
customTagsLength = 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.agrona.MutableDirectBuffer;
import org.agrona.concurrent.UnsafeBuffer;
import org.agrona.generation.OutputManager;
import uk.co.real_logic.artio.builder.CommonEncoderImpl;
import uk.co.real_logic.artio.builder.Encoder;
import uk.co.real_logic.artio.builder.SessionHeaderEncoder;
import uk.co.real_logic.artio.dictionary.Generated;
Expand Down Expand Up @@ -207,7 +208,8 @@ protected void generateAggregateFile(final Aggregate aggregate, final AggregateT
DirectBuffer.class,
MutableDirectBuffer.class,
UnsafeBuffer.class,
AsciiSequenceView.class);
AsciiSequenceView.class,
CommonEncoderImpl.class);
generateAggregateClass(aggregate, aggregateType, className, out);
});
}
Expand Down Expand Up @@ -339,7 +341,7 @@ private String classDeclaration(
}
else
{
extendsClause = "";
extendsClause = " extends CommonEncoderImpl";
}
return String.format(
"\n" +
Expand All @@ -365,6 +367,9 @@ private String completeResetMethod(
case HEADER:
additionalReset = " beginStringAsCopy(DEFAULT_BEGIN_STRING, 0, DEFAULT_BEGIN_STRING.length);\n";
break;
case MESSAGE:
additionalReset = " resetCustomTags();\n";
break;
default:
additionalReset = "";
}
Expand Down Expand Up @@ -968,6 +973,13 @@ private String encodeMethod(final List<Entry> entries, final AggregateType aggre
if (aggregateType == AggregateType.MESSAGE)
{
suffix =
"\n" +
" if (customTagsLength > 0)\n" +
" {\n" +
" buffer.putBytes(position, customTagsBuffer, 0, customTagsLength);\n" +
" position += customTagsLength;\n" +
" }\n" +
"\n" +
" position += trailer.startTrailer(buffer, position);\n" +
"\n" +
" final int messageStart = header.finishHeader(buffer, bodyStart, position - bodyStart);\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,13 @@ public final class ExampleDictionary
"8=FIX.4.4\0019=91\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" +
"\001124=2\001130=2\001131=1\001404=10\001131=2\001404=20\00110=176\001";

public static final String WITH_CUSTOM_TAGS =
"8=FIX.4.4\0019=110\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" +
"\001124=2\001130=2\001131=1\001404=10\001131=2\001404=20" +
"\00110100=42" +
"\00110101=foo" +
"\00110=227\001";

public static final String NESTED_COMPONENT_MESSAGE =
"8=FIX.4.4\0019=120\00135=0\001115=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" +
"\001124=2\001130=2\001131=1\001404=10\001131=2\001404=20\001141=180\001142=2\001143=99\001143=100\001" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import uk.co.real_logic.artio.EncodingException;
import uk.co.real_logic.artio.builder.CommonEncoderImpl;
import uk.co.real_logic.artio.builder.Encoder;
import uk.co.real_logic.artio.fields.DecimalFloat;
import uk.co.real_logic.artio.fields.UtcTimestampEncoder;
Expand Down Expand Up @@ -698,6 +699,19 @@ public void shouldValidateMissingRequiredFloatFields() throws Exception
encoder.encode(buffer, 1);
}

@Test
public void shouldSetCustomTags() throws Exception
{
final Encoder encoder = newHeartbeat();
setRequiredFields(encoder);
setupComponent(encoder);

((CommonEncoderImpl)encoder).customTag(10100, 42);
((CommonEncoderImpl)encoder).customTagAscii(10101, "foo");

assertEncodesTo(encoder, WITH_CUSTOM_TAGS);
}

@Test(expected = EncodingException.class)
public void shouldValidateMissingRequiredIntFields() throws Exception
{
Expand Down

0 comments on commit eef6555

Please sign in to comment.