Skip to content

Commit 84fcc8f

Browse files
Merge pull request #113 from deutschebank/db-contrib/constant-seq-length
Constant sequence length fix
2 parents 10f9275 + 02e749f commit 84fcc8f

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

src/mfast/ext_ref.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,12 @@ class ext_mref<sequence_mref, LengthExtRef, ElementExtRef> {
310310
cref_type get() const { return base_; }
311311
is_optional_type optional() const { return is_optional_type(); }
312312
length_type set_length(value_storage &storage) const {
313+
auto* length_inst = base_.instruction()->length_instruction();
313314
field_mref_base length_mref(nullptr, &storage,
314-
base_.instruction()->length_instruction());
315+
length_inst);
316+
// a temporary storage is used for sequence length field
317+
// and we must initialize it properly to support constant operators
318+
length_inst->construct_value(storage, nullptr);
315319
return length_type(length_mref);
316320
}
317321

tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ FASTTYPEGEN_TARGET(simple_types6 simple6.xml)
1818
FASTTYPEGEN_TARGET(simple_types7 simple7.xml)
1919
FASTTYPEGEN_TARGET(simple_types8 simple8.xml)
2020
FASTTYPEGEN_TARGET(simple_types9 simple9.xml)
21+
FASTTYPEGEN_TARGET(simple_types10 simple10.xml)
2122

2223

2324
FASTTYPEGEN_TARGET(test_types1 test1.xml test2.xml)
@@ -51,6 +52,7 @@ add_executable (mfast_test
5152
${FASTTYPEGEN_simple_types7_OUTPUTS}
5253
${FASTTYPEGEN_simple_types8_OUTPUTS}
5354
${FASTTYPEGEN_simple_types9_OUTPUTS}
55+
${FASTTYPEGEN_simple_types10_OUTPUTS}
5456
fast_type_gen_test.cpp
5557
dictionary_builder_test.cpp
5658
json_test.cpp

tests/simple10.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version=" 1.0 "?>
2+
<templates xmlns="http://www.fixprotocol.org/ns/template-definition"
3+
templateNs="http://www.fixprotocol.org/ns/templates/sample" ns="http://www.fixprotocol.org/ns/fix">
4+
<template name="Test" id="1">
5+
<sequence name="sequence1">
6+
<length id="110">
7+
<constant value="1"/>
8+
</length>
9+
<int64 name="field1" id="111">
10+
<copy/>
11+
</int64>
12+
</sequence>
13+
</template>
14+
</templates>

tests/simple_coder_test.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "simple7.h"
3535
#include "simple8.h"
3636
#include "simple9.h"
37+
#include "simple10.h"
3738

3839
#include "byte_stream.h"
3940
#include "debug_allocator.h"
@@ -294,3 +295,31 @@ TEST_CASE("test fast coder v2 for a simple template with absent optional fields
294295
REQUIRE(test_case.decoding("\xA0\x81\x83\x80\x84\x82\x80", msg_ref));
295296
}
296297

298+
299+
TEST_CASE("test fast decoder for a simple template with constant len in a sequence", "[constant_sequence_length_test]")
300+
{
301+
fast_coding_test_case<simple10::templates_description> test_case;
302+
303+
debug_allocator alloc;
304+
simple10::Test msg(&alloc);
305+
simple10::Test_mref msg_ref = msg.mref();
306+
307+
simple10::Test_mref::sequence1_mref seq(msg_ref.set_sequence1());
308+
seq.resize(1);
309+
seq[0].set_field1().as(10);
310+
311+
// The value of a constant field is never transferred.
312+
// ...
313+
// A field will not occupy any bit in the presence map if it is mandatory and has the constant operator.
314+
// ...
315+
// The default, copy, and increment operators have the following presence map and NULL utilization:
316+
// - Mandatory integer, decimal, string and byte vector fields – one bit. If set, the value appears in the stream.
317+
REQUIRE(test_case.encoding(msg_ref,
318+
// pmap | elem1 pmap | f1 |
319+
// 80 C0 8A
320+
"\x80\xC0\x8A"
321+
));
322+
323+
REQUIRE(test_case.decoding("\x80\xC0\x8A", msg_ref, true));
324+
}
325+

0 commit comments

Comments
 (0)