Skip to content

[Go] generator does not support dimensionType as a group parameter. #937

Open
@sergiu128

Description

@sergiu128

Take the following group:

<group name="NoOrderIDEntries" id="37705" description="Number of OrderID entries" blockLength="24" dimensionType="groupSize8Byte">
    <field name="OrderID" id="37" type="uInt64" description="Unique Order ID" offset="0" semanticType="int"/>
    <field name="MDOrderPriority" id="37707" type="uInt64NULL" description="Order priority for execution on the order book" offset="8" semanticType="int"/>
    <field name="MDDisplayQty" id="37706" type="Int32NULL" description="Visible qty of order" offset="16" semanticType="Qty"/>
    <field name="ReferenceID" id="9633" type="uInt8NULL" description="Reference to corresponding Price and Security ID, sequence of MD entry in the message" offset="20" semanticType="int"/>
    <field name="OrderUpdateAction" id="37708" type="OrderUpdateAction" description="Order book update action to be applied to the order referenced by OrderID" offset="21" semanticType="int"/>
</group>

where groupSize8Byte is:

<composite name="groupSize8Byte" description="8 Byte aligned repeating group dimensions" semanticType="NumInGroup">
    <type name="blockLength" description="Length" primitiveType="uint16"/>
    <type name="numInGroup" description="NumInGroup" offset="7" primitiveType="uint8"/>
</composite>

The go generator does not take into account the dimensionType. The C++ generator does, which leads to correct decoding.

This is what the Go generator does right now:

if m.NoOrderIDEntriesInActingVersion(actingVersion) {
    var NoOrderIDEntriesBlockLength uint16
    if err := _m.ReadUint16(_r, &NoOrderIDEntriesBlockLength); err != nil {
        return err
    }
    var NoOrderIDEntriesNumInGroup uint8
    if err := _m.ReadUint8(_r, &NoOrderIDEntriesNumInGroup); err != nil {
        return err
    }
    if cap(m.NoOrderIDEntries) < int(NoOrderIDEntriesNumInGroup) {
        m.NoOrderIDEntries = make([]MDIncrementalRefreshBook46NoOrderIDEntries, NoOrderIDEntriesNumInGroup)
    }
    m.NoOrderIDEntries = m.NoOrderIDEntries[:NoOrderIDEntriesNumInGroup]
    for i := range m.NoOrderIDEntries {
        if err := m.NoOrderIDEntries[i].Decode(_m, _r, actingVersion, uint(NoOrderIDEntriesBlockLength)); err != nil {
            return err
        }
    }
}

This is what the Go generator should do:

if m.NoOrderIDEntriesInActingVersion(actingVersion) {
    groupSize := &GroupSize8Byte{}
    if err := groupSize.Decode(_m, _r, actingVersion); err != nil {
        return err
    }

    if cap(m.NoOrderIDEntries) < int(groupSize.NumInGroup) {
        m.NoOrderIDEntries = make([]MDIncrementalRefreshBook46NoOrderIDEntries, groupSize.NumInGroup)
    }
    m.NoOrderIDEntries = m.NoOrderIDEntries[:groupSize.NumInGroup]
    for i := range m.NoOrderIDEntries {
        if err := m.NoOrderIDEntries[i].Decode(_m, _r, actingVersion, uint(groupSize.BlockLength)); err != nil {
            return err
        }
    }
}

This is what the C++ generator does:

inline void wrapForDecode(
    char *buffer,
    std::uint64_t *pos,
    const std::uint64_t actingVersion,
    const std::uint64_t bufferLength,
) {
    GroupSize8Byte dimensions(buffer, *pos, bufferLength, actingVersion);
    m_buffer = buffer;
    m_bufferLength = bufferLength;
    m_blockLength = dimensions.blockLength();
    m_count = dimensions.numInGroup();
    m_index = 0;
    m_actingVersion = actingVersion;
    m_initialPosition = *pos;
    m_positionPtr = pos;
    *m_positionPtr = *m_positionPtr + 8;
}

You can run the example above here.

CC @theodosiosandreou

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions