Has anyone worked with the C++ SDK enough to explain MesgListeners to me?
It appears that I can AddListener an Encode object which implements MesgListener to the MesgBroadcaster which I pass to Decode::Read.
Since Encode::OnMesg just contains Write(mesg), this causes all recognized decoded messages to be re encoded to the output file.
In addition, I would like Decode to call the OnMesg of a special RecordMesgListener for record messages rather than Encode::OnMesg so I can correct some records.
However, when I AddLIstener a stub RecordMesgListener to the MesgBroadcaster which just does Write(mesg) like Encode::OnMesg, I do not see identical output as I would expect.
Instead, I get an output that has some additional (but not duplicates of all) records and other corruption and a bad CRC.
Why is this happening?
Here's my Recode function:
int Recode(Listener& listener, fit::MesgBroadcaster& mesgBroadcaster, char* filename)
{
// Open file to decode
fit::Decode decode;
fstream inFile;
inFile.open(filename, ios::in | ios::binary);
if (!inFile.is_open())
{
printf("Error opening file %s\n", filename);
return -1;
}
if (!decode.CheckIntegrity(inFile))
{
printf("FIT file integrity failed.\nAttempting to decode...\n");
}
// Open the file to encode
std::fstream outFile;
outFile.open("badFileRecode.fit", std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
if (!outFile.is_open())
{
printf("Error opening file badFileRecode.fit\n");
return -1;
}
// Create a FIT Encode object
fit::Encode encode(fit::ProtocolVersion::V20);
try
{
// Write the FIT header to the output stream
encode.Open(outFile);
// Allow the RecordMesgListener to encode after fixes
listener.encode = encode;
// Other decoded messages are written by encode without changes
mesgBroadcaster.AddListener((fit::MesgListener&)encode);
decode.Read(inFile, mesgBroadcaster);
}
catch (const fit::RuntimeException& e)
{
printf("Exception decoding file: %s\n", e.what());
return -1;
}
catch (...)
{
printf("Exception decoding file");
return -1;
}
try {
// Update the data size in the header and calculate the CRC
if (!encode.Close())
{
printf("Error closing encode.\n");
return -1;
}
// Close the file
outFile.close();
printf("Encoded FIT file badFileRecode.fit.\n");
return 0;
}
catch (...)
{
throw std::exception("Exception encoding activity file");
}
}
Here's the Listener specific to RecordMesg
class Listener
: public fit::RecordMesgListener
{
public:
fit::Encode encode;
void OnMesg( fit::RecordMesg& record ) override
{
encode.Write(record);
}
};