Skip to content

Commit c68b540

Browse files
[Java] Use the associated length field to determine how much to copy from a data/xmldata buffer when encoding a message
1 parent 4cf9658 commit c68b540

File tree

4 files changed

+56
-18
lines changed

4 files changed

+56
-18
lines changed

artio-codecs/src/main/java/uk/co/real_logic/artio/dictionary/generation/EncoderGenerator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,15 +1127,16 @@ else if (mustCheckLength)
11271127
case XMLDATA:
11281128
return String.format(
11291129
"%1$s" +
1130-
"%4$s buffer.putBytes(position, %2$s);\n" +
1131-
"%4$s position += %2$s.length;\n" +
1130+
"%4$s buffer.putBytes(position, %2$s, 0, %5$s);\n" +
1131+
"%4$s position += %5$s;\n" +
11321132
"%4$s buffer.putSeparator(position);\n" +
11331133
"%4$s position++;\n" +
11341134
"%3$s",
11351135
tag,
11361136
fieldName,
11371137
enablingSuffix,
1138-
indent);
1138+
indent,
1139+
formatPropertyName(field.associatedLengthField().name()));
11391140

11401141
default:
11411142
throw new UnsupportedOperationException("Unknown type: " + type);

artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/ExampleDictionary.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public final class ExampleDictionary
8787
public static final String FLOAT_FIELD = "floatField";
8888
public static final String BOOLEAN_FIELD = "booleanField";
8989
public static final String DATA_FIELD = "dataField";
90+
public static final String DATA_FIELD_LENGTH = "dataFieldLength";
9091
public static final String TEST_REQ_ID_LENGTH = "testReqIDLength";
9192
public static final String TEST_REQ_ID_OFFSET = "testReqIDOffset";
9293
public static final String ON_BEHALF_OF_COMP_ID_LENGTH = "onBehalfOfCompIDLength";
@@ -221,12 +222,16 @@ public final class ExampleDictionary
221222
"\001118=Y\001200=3\001119=123\001127=19700101-00:00:00.001\00110=199\001";
222223

223224
public static final String ENCODED_MESSAGE_FIXT11 =
224-
"8=FIXT.1.1\0019=75\00135=0\001115=abc\001112=abc\001116=2\001117=1.1" +
225-
"\001118=Y\001119=123\001127=19700101-00:00:00.001\00110=021\001";
225+
"8=FIXT.1.1\0019=81\00135=0\001115=abc\001112=abc\001116=2\001117=1.1" +
226+
"\001118=Y\001200=3\001119=123\001127=19700101-00:00:00.001\00110=021\001";
227+
228+
public static final String ENCODED_MESSAGE_LONG_DATA =
229+
"8=FIXT.1.1\0019=84\00135=0\001115=abc\001112=abc\001116=2\001117=1.1" +
230+
"\001118=Y\001200=6\001119=123456\001127=19700101-00:00:00.001\00110=186\001";
226231

227232
public static final String ENCODED_MESSAGE_WITH_SIGNATURE =
228-
"8=FIX.4.4\0019=96\00135=0\001115=abc\001112=abc\001116=2\001117=1.1" +
229-
"\001118=Y\001119=123\001127=19700101-00:00:00.001\00193=11\00189=Good to go!\00110=040\001";
233+
"8=FIX.4.4\0019=102\00135=0\001115=abc\001112=abc\001116=2\001117=1.1" +
234+
"\001118=Y\001200=3\001119=123\001127=19700101-00:00:00.001\00193=11\00189=Good to go!\00110=079\001";
230235

231236
public static final String ONLY_TESTREQ_ENCODED_MESSAGE =
232237
"8=FIX.4.4\0019=61\00135=0\001115=abc\001112=abc\001116=2\001117=1.1\001127=19700101-00:00:00.001" +
@@ -529,7 +534,6 @@ public final class ExampleDictionary
529534

530535
private static final String ENUM_TEST_MESSAGE = "EnumTestMessage";
531536
private static final String ENUM_TEST_MESSAGE_TYPE = "ET";
532-
static final String DATA_FIELD_LENGTH = "DataFieldLength";
533537

534538
static
535539
{

artio-codecs/src/test/java/uk/co/real_logic/artio/dictionary/generation/EncoderGeneratorTest.java

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,8 @@ public void encodesValues() throws Exception
391391
setRequiredFields(encoder);
392392
setupHeader(encoder);
393393
setupTrailer(encoder);
394-
395394
setOptionalFields(encoder);
396-
setDataFieldLength(encoder);
395+
397396
assertEncodesTo(encoder, ENCODED_MESSAGE);
398397
}
399398

@@ -438,6 +437,34 @@ public void encodesValuesWithBeginString() throws Exception
438437
assertEncodesTo(encoder, ENCODED_MESSAGE_FIXT11);
439438
}
440439

440+
@Test
441+
public void encodesDataWithoutOverflowFromPreviousMessage() throws Exception
442+
{
443+
final Encoder encoder = newHeartbeat();
444+
445+
setRequiredFields(encoder);
446+
setupHeader(encoder, "FIXT.1.1");
447+
setupTrailer(encoder);
448+
setTestReqIdTo(encoder, ABC);
449+
setBoolean(encoder, BOOLEAN_FIELD, true);
450+
setByteArrayAsCopy(encoder, DATA_FIELD, new byte[]{ '1', '2', '3', '4', '5', '6' }, 0, 6);
451+
setInt(encoder, DATA_FIELD_LENGTH, 6);
452+
453+
assertEncodesTo(encoder, ENCODED_MESSAGE_LONG_DATA);
454+
455+
encoder.reset();
456+
457+
setRequiredFields(encoder);
458+
setupHeader(encoder, "FIXT.1.1");
459+
setupTrailer(encoder);
460+
setTestReqIdTo(encoder, ABC);
461+
setBoolean(encoder, BOOLEAN_FIELD, true);
462+
setByteArrayAsCopy(encoder, DATA_FIELD, new byte[]{ '1', '2', '3' }, 0, 3);
463+
setInt(encoder, DATA_FIELD_LENGTH, 3);
464+
465+
assertEncodesTo(encoder, ENCODED_MESSAGE_FIXT11);
466+
}
467+
441468
@Test
442469
public void encodeDecimalFloatUsingRawValueAndScale() throws Exception
443470
{
@@ -447,9 +474,7 @@ public void encodeDecimalFloatUsingRawValueAndScale() throws Exception
447474
setFloatFieldRawValues(encoder);
448475
setupHeader(encoder);
449476
setupTrailer(encoder);
450-
451477
setOptionalFields(encoder);
452-
setDataFieldLength(encoder);
453478

454479
assertEncodesTo(encoder, ENCODED_MESSAGE);
455480
}
@@ -510,7 +535,6 @@ public void shouldIncludeOptionalFieldsInToString() throws Exception
510535

511536
setRequiredFields(encoder);
512537
setOptionalFields(encoder);
513-
setDataFieldLength(encoder);
514538

515539
assertThat(encoder.toString(), containsString(STRING_ENCODED_MESSAGE_SUFFIX));
516540
}
@@ -1162,6 +1186,7 @@ private void setOptionalFields(final Encoder encoder) throws Exception
11621186
setTestReqIdTo(encoder, ABC);
11631187
setBoolean(encoder, BOOLEAN_FIELD, true);
11641188
setByteArray(encoder, DATA_FIELD, new byte[]{ '1', '2', '3' });
1189+
setInt(encoder, DATA_FIELD_LENGTH, 3);
11651190
}
11661191

11671192
private FieldBagEncoder getAnyFieldsEncoder(final Encoder encoder, final String name) throws Exception
@@ -1288,9 +1313,4 @@ private void setTestReqIdBuffer(
12881313
.getMethod(TEST_REQ_ID, DirectBuffer.class, int.class, int.class)
12891314
.invoke(encoder, new UnsafeBuffer(PREFIXED_VALUE_IN_BYTES), 1, 3);
12901315
}
1291-
1292-
private void setDataFieldLength(final Encoder encoder) throws Exception
1293-
{
1294-
setInt(encoder, "dataFieldLength", 3);
1295-
}
12961316
}

artio-codecs/src/test/java/uk/co/real_logic/artio/util/Reflection.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ public static void setByteArray(final Object object, final String setter, final
9090
set(object, setter, byte[].class, value);
9191
}
9292

93+
public static void setByteArrayAsCopy(final Object object, final String setter, final byte[] value, final int offset, final int length)
94+
throws Exception
95+
{
96+
try
97+
{
98+
object.getClass().getMethod(setter + "AsCopy", byte[].class, int.class, int.class).invoke(object, value, offset, length);
99+
}
100+
catch (final InvocationTargetException e)
101+
{
102+
LangUtil.rethrowUnchecked(e.getCause());
103+
}
104+
}
105+
93106
private static void set(
94107
final Object object,
95108
final String setterName,

0 commit comments

Comments
 (0)