mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-01-19 04:02:09 +01:00
Improved FIT parser error handling
This commit is contained in:
parent
324ac2e0f4
commit
87a4398131
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
const quint32 FIT_MAGIC = 0x5449462E; // .FIT
|
const quint32 FIT_MAGIC = 0x5449462E; // .FIT
|
||||||
|
|
||||||
|
#define RECORD_MESSAGE 20
|
||||||
|
#define TIMESTAMP_FIELD 253
|
||||||
|
|
||||||
|
|
||||||
FITParser::FITParser(QList<TrackData> &tracks, QList<RouteData> &routes,
|
FITParser::FITParser(QList<TrackData> &tracks, QList<RouteData> &routes,
|
||||||
QList<Waypoint> &waypoints) : Parser(tracks, routes, waypoints)
|
QList<Waypoint> &waypoints) : Parser(tracks, routes, waypoints)
|
||||||
@ -12,11 +15,21 @@ FITParser::FITParser(QList<TrackData> &tracks, QList<RouteData> &routes,
|
|||||||
memset(_defs, 0, sizeof(_defs));
|
memset(_defs, 0, sizeof(_defs));
|
||||||
}
|
}
|
||||||
|
|
||||||
FITParser::~FITParser()
|
void FITParser::clearDefinitions()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++) {
|
||||||
if (_defs[i].fields)
|
if (_defs[i].fields) {
|
||||||
delete[] _defs[i].fields;
|
delete[] _defs[i].fields;
|
||||||
|
_defs[i].fields = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FITParser::warning(const char *text) const
|
||||||
|
{
|
||||||
|
const QFile *file = static_cast<QFile *>(_device);
|
||||||
|
fprintf(stderr, "%s:%d: %s\n", qPrintable(file->fileName()),
|
||||||
|
_len, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FITParser::readData(char *data, size_t size)
|
bool FITParser::readData(char *data, size_t size)
|
||||||
@ -162,6 +175,11 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
if (!def->fields) {
|
||||||
|
_errorString = "Undefined data message";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_endian = def->endian;
|
_endian = def->endian;
|
||||||
|
|
||||||
for (i = 0; i < def->num_fields; i++) {
|
for (i = 0; i < def->num_fields; i++) {
|
||||||
@ -169,9 +187,9 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset)
|
|||||||
if (!readField(field, val))
|
if (!readField(field, val))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (field->id == 253)
|
if (field->id == TIMESTAMP_FIELD)
|
||||||
_timestamp = timestamp = val;
|
_timestamp = timestamp = val;
|
||||||
else if (def->global_id == 20) {
|
else if (def->global_id == RECORD_MESSAGE) {
|
||||||
switch (field->id) {
|
switch (field->id) {
|
||||||
case 0:
|
case 0:
|
||||||
if (val != 0x7fffffff)
|
if (val != 0x7fffffff)
|
||||||
@ -206,9 +224,19 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->global_id == 20 && trackpoint.coordinates().isValid()) {
|
if (def->global_id == RECORD_MESSAGE) {
|
||||||
trackpoint.setTimestamp(QDateTime::fromTime_t(timestamp + 631065600));
|
if (trackpoint.coordinates().isValid()) {
|
||||||
|
trackpoint.setTimestamp(QDateTime::fromTime_t(timestamp
|
||||||
|
+ 631065600));
|
||||||
_tracks.last().append(trackpoint);
|
_tracks.last().append(trackpoint);
|
||||||
|
} else {
|
||||||
|
if (trackpoint.coordinates().isNull())
|
||||||
|
warning("Missing coordinates");
|
||||||
|
else {
|
||||||
|
_errorString = "Invalid coordinates";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -216,7 +244,7 @@ bool FITParser::parseData(MessageDefinition *def, quint8 offset)
|
|||||||
|
|
||||||
bool FITParser::parseDataMessage(quint8 header)
|
bool FITParser::parseDataMessage(quint8 header)
|
||||||
{
|
{
|
||||||
int local_id = header & 0x1f;
|
int local_id = header & 0xf;
|
||||||
MessageDefinition* def = &_defs[local_id];
|
MessageDefinition* def = &_defs[local_id];
|
||||||
return parseData(def, 0);
|
return parseData(def, 0);
|
||||||
}
|
}
|
||||||
@ -235,6 +263,11 @@ bool FITParser::parseRecord()
|
|||||||
if (!readValue(header))
|
if (!readValue(header))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (header & 0x20) {
|
||||||
|
_errorString = "Developer data not supported";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (header & 0x80)
|
if (header & 0x80)
|
||||||
return parseCompressedMessage(header);
|
return parseCompressedMessage(header);
|
||||||
else if (header & 0x40)
|
else if (header & 0x40)
|
||||||
@ -261,7 +294,7 @@ bool FITParser::parseHeader()
|
|||||||
|
|
||||||
_len = qFromLittleEndian(hdr.data_size);
|
_len = qFromLittleEndian(hdr.data_size);
|
||||||
|
|
||||||
if (hdr.header_size > 12)
|
if (hdr.header_size > sizeof(hdr))
|
||||||
if (!readData((char *)&crc, sizeof(crc)))
|
if (!readData((char *)&crc, sizeof(crc)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -273,6 +306,7 @@ bool FITParser::loadFile(QFile *file)
|
|||||||
_device = file;
|
_device = file;
|
||||||
_endian = 0;
|
_endian = 0;
|
||||||
_timestamp = 0;
|
_timestamp = 0;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
if (!parseHeader())
|
if (!parseHeader())
|
||||||
return false;
|
return false;
|
||||||
@ -280,8 +314,10 @@ bool FITParser::loadFile(QFile *file)
|
|||||||
_tracks.append(TrackData());
|
_tracks.append(TrackData());
|
||||||
|
|
||||||
while (_len)
|
while (_len)
|
||||||
if (!parseRecord())
|
if ((ret = parseRecord()) == false)
|
||||||
return false;
|
break;
|
||||||
|
|
||||||
return true;
|
clearDefinitions();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ class FITParser : public Parser
|
|||||||
public:
|
public:
|
||||||
FITParser(QList<TrackData> &tracks, QList<RouteData> &routes,
|
FITParser(QList<TrackData> &tracks, QList<RouteData> &routes,
|
||||||
QList<Waypoint> &waypoints);
|
QList<Waypoint> &waypoints);
|
||||||
~FITParser();
|
~FITParser() {}
|
||||||
|
|
||||||
bool loadFile(QFile *file);
|
bool loadFile(QFile *file);
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
@ -37,6 +37,9 @@ private:
|
|||||||
} MessageDefinition;
|
} MessageDefinition;
|
||||||
|
|
||||||
|
|
||||||
|
void warning(const char *text) const;
|
||||||
|
void clearDefinitions();
|
||||||
|
|
||||||
bool readData(char *data, size_t size);
|
bool readData(char *data, size_t size);
|
||||||
template<class T> bool readValue(T &val);
|
template<class T> bool readValue(T &val);
|
||||||
bool skipValue(size_t size);
|
bool skipValue(size_t size);
|
||||||
@ -49,7 +52,6 @@ private:
|
|||||||
bool parseData(MessageDefinition *def, quint8 offset);
|
bool parseData(MessageDefinition *def, quint8 offset);
|
||||||
bool readField(Field *f, quint32 &val);
|
bool readField(Field *f, quint32 &val);
|
||||||
|
|
||||||
|
|
||||||
QIODevice *_device;
|
QIODevice *_device;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user