Decoding fails when using string type developer field [FIT SDK C++]

Former Member
Former Member
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