Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in OpenFAST.Template.Scalar.cs #2

Open
scholtz opened this issue Aug 31, 2017 · 0 comments
Open

Bug in OpenFAST.Template.Scalar.cs #2

scholtz opened this issue Aug 31, 2017 · 0 comments

Comments

@scholtz
Copy link

scholtz commented Aug 31, 2017

There is bug in OpenFAST/Template/Scalar.cs file

If value is optional, and uses the previous value (for example copy), then the null value is not stored.

Way to reproduce:
Object: string? Param

Msg1: "test"
Msg2: null
Msg3: null

There is error in decoding Msg3. Msg3 is decoded as "test", but should be decoded as null.

Error is in the fact, that null value is not stored, so when a message is sent using other Fast library, the presence bit is set to false because the value repeats it self, and the message is decoded from context, which is wrong in OpenFAST.net

To fix this, decode method in Scalar.cs should look like:

public override IFieldValue Decode(Stream inStream, Group decodeTemplate, Context context,
                                           BitVectorReader presenceMapReader)
        {
            try
            {
                ScalarValue priorValue = null;
                IDictionary dict = null;
                QName key = Key;

                ScalarValue value;
                int pmapIndex = presenceMapReader.Index;
                if (IsPresent(presenceMapReader))
                {
                    if (context.TraceEnabled)
                        inStream = new RecordingInputStream(inStream);

                    if (!_operatorCodec.ShouldDecodeType)
                        return _operatorCodec.DecodeValue(null, null, this);

                    if (_operatorCodec.DecodeNewValueNeedsPrevious)
                    {
                        dict = context.GetDictionary(Dictionary);
                        priorValue = context.Lookup(dict, decodeTemplate, key);
                        ValidateDictionaryTypeAgainstFieldType(priorValue, _fastType);
                    }

                    ScalarValue decodedValue = _typeCodec.Decode(inStream);
                    value = _operatorCodec.DecodeValue(decodedValue, priorValue, this);

                }
                else
                {
                    if (_operatorCodec.DecodeEmptyValueNeedsPrevious)
                    {
                        dict = context.GetDictionary(Dictionary);
                        priorValue = context.Lookup(dict, decodeTemplate, key);
                        ValidateDictionaryTypeAgainstFieldType(priorValue, _fastType);
                    }

                    value = _operatorCodec.DecodeEmptyValue(priorValue, this);
                }

                ValidateDecodedValueIsCorrectForType(value, _fastType);

#warning TODO: Review if this previous "if" statement is needed.
                // if (Operator != Template.Operator.Operator.DELTA || value != null)
                if (value != null &&
                    (_operatorCodec.DecodeNewValueNeedsPrevious || _operatorCodec.DecodeEmptyValueNeedsPrevious))
                {
                    context.Store(dict ?? context.GetDictionary(Dictionary), decodeTemplate, key, value);
                }
                if (value == null &&
                    (_operatorCodec.DecodeNewValueNeedsPrevious || _operatorCodec.DecodeEmptyValueNeedsPrevious)) {
                    context.Store(dict ?? context.GetDictionary(Dictionary), decodeTemplate, key, value);
                }

                return value;
            }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant