[QFJ-962] FieldMap.setField(int key, Field<?> field) does not properly convert values Created: 15/Nov/18 Updated: 15/Jun/20 |
|
Status: | Open |
Project: | QuickFIX/J |
Component/s: | Engine |
Affects Version/s: | 2.1.0 |
Fix Version/s: | 3.0.0 |
Type: | Bug | Priority: | Default |
Reporter: | amichair | Assignee: | Wojciech Zankowski |
Resolution: | Unresolved | Votes: | 0 |
Labels: | None |
Issue Links: |
|
Description |
However, this is misleading and introduces a bug, since the two are not equivalent. Specifically, the type-specific overloads do proper type conversions on the value, while the generic setField does not. For example, if you pass a DoubleField with a very large or small value, it will convert it into a string in scientific notation (with exponent) which is invalid in the FIX protocol, whereas calling the type-specific setField(DoubleField field) will properly use the DoubleConverter to convert it correctly. When this method was non-public this was less of a problem, assuming its internal usages are correct (I don't know if this is the case, but assume it is). However making it public now creates a pitfall for anyone using this method in client code which will likely result in a bug on some data. The solution would be to either implement it fully with proper type conversion (e.g. using the switch statement from |
Comments |
Comment by Christoph John [ 16/Nov/18 ] |
Hi amichair, maybe we should add the javadoc comment as you suggested and provide an additional method, say setFieldConverted(int key, Field<?> field) , so users can choose which method suits them best. Cheers, |
Comment by Christoph John [ 16/Nov/18 ] |
Briefly had a look at this. What about making Field abstract (According to a comment in the class it is only non-abstract to have JNI compatibility. But that was like 10 years ago.) and adding an abstract convertToString() method that does the necessary conversion in the subclasses? Example for BooleanField: @Override public String convertToString() { return BooleanConverter.convert(getValue()); } Then we can call in FieldMap: public void setField(int key, Field<?> field) { setString(key, field.convertToString()); } That way we can ensure that we always have a conversion method for a field and don't need a lengthy if-else statement. What do you think? |
Comment by amichair [ 22/Nov/18 ] |
Encapsulating the converters inside the Field classes sounds like a good idea regardless of this issue or of Field being abstract I have't delved into this one yet, but perhaps instead of convertToString, maybe toString itself should just do this properly? |
Comment by Wojciech Zankowski [ 29/Jul/19 ] |
Pull request created with implementation of the idea: https://github.com/quickfix-j/quickfixj/pull/226 |