Packages

A high-performance Elixir library for decoding Garmin .fit files using a C++ NIF.

Current section

Files

Jump to
fit_decoder c_src fit_sdk cpp fit_mesg_definition.cpp
Raw

c_src/fit_sdk/cpp/fit_mesg_definition.cpp

/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.171.0Release
// Tag = production/release/21.171.0-0-g57fed75
/////////////////////////////////////////////////////////////////////////////////////////////
#include <ostream>
#include "fit_mesg_definition.hpp"
#include "fit_developer_field_definition.hpp"
namespace fit
{
MesgDefinition::MesgDefinition(void)
: num(FIT_MESG_NUM_INVALID)
, localNum(0)
, fields()
, devFields()
{
}
MesgDefinition::MesgDefinition(const Mesg& mesg)
: num(mesg.GetNum())
, localNum(mesg.GetLocalNum())
{
for (FIT_UINT16 i=0; i < (FIT_UINT16)mesg.GetNumFields(); i++)
fields.push_back(FieldDefinition(mesg.GetFieldByIndex(i)));
for ( auto field : mesg.GetDeveloperFields() )
{
devFields.push_back( DeveloperFieldDefinition(field) );
}
}
FIT_UINT16 MesgDefinition::GetNum() const
{
return num;
}
FIT_UINT8 MesgDefinition::GetLocalNum() const
{
return localNum;
}
void MesgDefinition::SetNum(const FIT_UINT16 newNum)
{
num = newNum;
}
void MesgDefinition::SetLocalNum(const FIT_UINT8 newLocalNum)
{
localNum = newLocalNum;
}
void MesgDefinition::AddField(const FieldDefinition& fieldDef)
{
fields.push_back(fieldDef);
}
void MesgDefinition::AddDevField(const DeveloperFieldDefinition& fieldDef)
{
devFields.push_back(fieldDef);
}
void MesgDefinition::ClearFields()
{
fields.clear();
devFields.clear();
}
int MesgDefinition::GetNumFields() const
{
return ((int) fields.size());
}
int MesgDefinition::GetNumDevFields() const
{
return ((int) devFields.size());
}
std::vector<FieldDefinition>& MesgDefinition::GetFields()
{
return fields;
}
std::vector<DeveloperFieldDefinition>& MesgDefinition::GetDevFields()
{
return devFields;
}
FieldDefinition* MesgDefinition::GetField(const FIT_UINT8 fieldNum)
{
for (int i=0; i<(int)fields.size(); i++)
{
if (fieldNum == fields[i].GetNum())
return &(fields[i]);
}
return FIT_NULL;
}
FieldDefinition* MesgDefinition::GetFieldByIndex(const FIT_UINT16 index)
{
if (index < fields.size())
return &(fields[index]);
return FIT_NULL;
}
DeveloperFieldDefinition* MesgDefinition::GetDevFieldByIndex(const FIT_UINT16 index)
{
if (index < devFields.size())
return &devFields[index];
return FIT_NULL;
}
const std::vector<FieldDefinition>& MesgDefinition::GetFields() const
{
return fields;
}
const std::vector<DeveloperFieldDefinition>& MesgDefinition::GetDevFields() const
{
return devFields;
}
const FieldDefinition* MesgDefinition::GetField(const FIT_UINT8 fieldNum) const
{
for (int i=0; i<(int)fields.size(); i++)
{
if (fieldNum == fields[i].GetNum())
return &(fields[i]);
}
return FIT_NULL;
}
const FieldDefinition* MesgDefinition::GetFieldByIndex(const FIT_UINT16 index) const
{
if (index < fields.size())
return &(fields[index]);
return FIT_NULL;
}
const DeveloperFieldDefinition* MesgDefinition::GetDevFieldByIndex(const FIT_UINT16 index) const
{
if (index < devFields.size())
return &devFields[index];
return FIT_NULL;
}
FIT_BOOL MesgDefinition::operator==(const MesgDefinition& mesgDef) const
{
if (num != mesgDef.num)
return FIT_FALSE;
if (localNum != mesgDef.localNum)
return FIT_FALSE;
if (fields.size() != mesgDef.fields.size())
return FIT_FALSE;
for (int i=0; i<(int)fields.size(); i++)
{
if (fields[i] != mesgDef.fields[i])
return FIT_FALSE;
}
return FIT_TRUE;
}
FIT_BOOL MesgDefinition::operator!=(const MesgDefinition& mesgDef) const
{
return !(*this == mesgDef);
}
FIT_BOOL MesgDefinition::Supports(const Mesg& mesg) const
{
return Supports(MesgDefinition(mesg));
}
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;
}
// 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;
}
return FIT_TRUE;
}
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;
}
int MesgDefinition::Write(std::ostream &file) const
{
int mesgSize = 6;
if ( devFields.size() > 0 )
{
file.put( ( FIT_HDR_TYPE_DEF_BIT | FIT_HDR_DEV_FIELD_BIT ) | ( localNum & FIT_HDR_TYPE_MASK ) ); // Message definition record header with local message number.
}
else
{
file.put((FIT_HDR_TYPE_DEF_BIT) | (localNum & FIT_HDR_TYPE_MASK)); // Message definition record header with local message number.
}
file.put(0); // Reserved
file.put(GetArch());
if (GetArch())
{ // Big Endian
file.put((FIT_UINT8)(num >> 8));
file.put((FIT_UINT8)num);
}
else
{
file.put((FIT_UINT8)num);
file.put((FIT_UINT8)(num >> 8));
}
file.put((FIT_UINT8)fields.size());
for (FIT_UINT8 i=0; i<fields.size(); i++)
{
int fieldSize = fields[i].Write(file);
if (fieldSize == 0)
return 0;
mesgSize += fieldSize;
}
if ( devFields.size() > 0 )
{
file.put( ( FIT_UINT8 )devFields.size() );
mesgSize += 1;
}
for ( FIT_UINT8 i = 0; i < devFields.size(); i++ )
{
int fieldSize = devFields[i].Write( file );
mesgSize += fieldSize;
}
return mesgSize;
}
int MesgDefinition::GetDeveloperFieldTotalSize() const
{
int totalSize = 0;
for (int i = 0; i < (int)devFields.size(); i++)
{
totalSize += devFields[i].GetSize();
}
return totalSize;
}
} // namespace fit