If you encode a file under the following conditions, decoding will not be possible.
- Use the FIT SDK C++ (v21.47)
- Create a Developer field of String type and write values of different lengths.
fit::FieldDescriptionMesg fieldDesc; fieldDesc.SetDeveloperDataIndex(0); fieldDesc.SetFieldDefinitionNumber(0); fieldDesc.SetFitBaseTypeId(FIT_BASE_TYPE_STRING); fieldDesc.SetFieldName(0, L"str_dev_field"); for (FIT_UINT8 i = 0; i < 2; i++) { fit::DeviceInfoMesg newDeviceInfo; fit::DeveloperField strDevField(fieldDesc, devId); if (i == 0) { strDevField.SetSTRINGValue(@"a".toWString); } else { strDevField.SetSTRINGValue(@"aa".toWString); } newDeviceInfo.AddDeveloperField(strDevField); records.push_back(newDeviceInfo); }
This problem does not occur with FIT SDK Java.
# How to Reproduce
- Open examples/exampleios/exampleios.xcodeproj
- Click the Run button in Xcode.
- The following decoding failure log will be output
Decoder not in correct state after last data byte in file Check message definitions. Error at byte: 0
# Workaround
If you fix the following part, it will work correctly. (I imitated FIT SDK Java)
fit_mesg_definition.hpp:
FIT_BOOL Supports(const MesgDefinition& mesgDef) const; //region Workaround const DeveloperFieldDefinition* GetDevField(const FIT_UINT8 developerIndex, const FIT_UINT8 num) const; //endregion
fit_mesg_definition.cpp:
FIT_BOOL MesgDefinition::Supports(const MesgDefinition& mesgDef) const { if (num != mesgDef.num) return FIT_FALSE; if (localNum != mesgDef.localNum) return FIT_FALSE; for (int i=0; i<(int)mesgDef.fields.size(); i++) { const FieldDefinition* supportedFieldDef = GetField(mesgDef.fields[i].GetNum()); if (supportedFieldDef == FIT_NULL) // Could not find field with matching number. return FIT_FALSE; if (mesgDef.fields[i].GetSize() > supportedFieldDef->GetSize()) // Other field definition is larger than this field definition. return FIT_FALSE; } //region Workaround // Check to make sure that all field developer fields are defined for (int i=0; i<(int)mesgDef.devFields.size(); i++) { const DeveloperFieldDefinition fieldDef = mesgDef.devFields[i]; const DeveloperFieldDefinition* supportedDef = GetDevField(fieldDef.GetDeveloperDataIndex(), fieldDef.GetNum()); // There is a Field Definition that we don't have a description for if (supportedDef == FIT_NULL) return FIT_FALSE; // The definition is a larger size that we dont support if (fieldDef.GetSize() > supportedDef->GetSize()) return FIT_FALSE; } //endregion return FIT_TRUE; } //region Workaround const DeveloperFieldDefinition* MesgDefinition::GetDevField(const FIT_UINT8 developerIndex, const FIT_UINT8 num) const { for (int i=0; i<(int)devFields.size(); i++) { if (devFields[i].GetNum() == num && devFields[i].GetDeveloperDataIndex() == developerIndex) return &(devFields[i]); } return FIT_NULL; } //endregion