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