mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-04-22 05:09:10 +02:00
Assure that ddf data is valid when accessing it
This commit is contained in:
parent
b9396e6bbd
commit
b6c7fe9cd1
@ -22,23 +22,22 @@ struct DR {
|
||||
char FieldTagSize;
|
||||
};
|
||||
|
||||
|
||||
const QVariant *ISO8211::Field::data(quint32 name, int idx) const
|
||||
const QVariant *ISO8211::data(const Field &field, quint32 name, int idx) const
|
||||
{
|
||||
const QVector<QVariant> &v = _data.at(idx);
|
||||
const QVector<QVariant> &v = field.data().at(idx);
|
||||
|
||||
for (int i = 0; i < _subFields->size(); i++)
|
||||
if (_subFields->at(i) == name)
|
||||
for (int i = 0; i < field.subFields()->size(); i++)
|
||||
if (field.subFields()->at(i) == name)
|
||||
return &v.at(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
|
||||
bool ISO8211::subfield(const Field &field, quint32 name, int *val, int idx) const
|
||||
{
|
||||
bool ok;
|
||||
|
||||
const QVariant *v = data(name, idx);
|
||||
const QVariant *v = data(field, name, idx);
|
||||
if (!v)
|
||||
return false;
|
||||
*val = v->toInt(&ok);
|
||||
@ -46,11 +45,11 @@ bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
|
||||
bool ISO8211::subfield(const Field &field, quint32 name, uint *val, int idx) const
|
||||
{
|
||||
bool ok;
|
||||
|
||||
const QVariant *v = data(name, idx);
|
||||
const QVariant *v = data(field, name, idx);
|
||||
if (!v)
|
||||
return false;
|
||||
*val = v->toUInt(&ok);
|
||||
@ -58,9 +57,10 @@ bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool ISO8211::Field::subfield(quint32 name, QByteArray *val, int idx) const
|
||||
bool ISO8211::subfield(const Field &field, quint32 name, QByteArray *val,
|
||||
int idx) const
|
||||
{
|
||||
const QVariant *v = data(name, idx);
|
||||
const QVariant *v = data(field, name, idx);
|
||||
if (!v)
|
||||
return false;
|
||||
*val = v->toByteArray();
|
||||
|
@ -15,20 +15,15 @@ public:
|
||||
class Field
|
||||
{
|
||||
public:
|
||||
Field() : _subFields(0) {}
|
||||
Field() : _tag(0), _subFields(0) {}
|
||||
Field(quint32 tag, const QVector<quint32> &subFields, const Data &data)
|
||||
: _tag(tag), _subFields(&subFields), _data(data) {}
|
||||
|
||||
quint32 tag() const {return _tag;}
|
||||
const Data &data() const {return _data;}
|
||||
|
||||
bool subfield(quint32 name, int *val, int idx = 0) const;
|
||||
bool subfield(quint32 name, uint *val, int idx = 0) const;
|
||||
bool subfield(quint32 name, QByteArray *val, int idx = 0) const;
|
||||
const QVector<quint32> *subFields() const {return _subFields;}
|
||||
|
||||
private:
|
||||
const QVariant *data(quint32 name, int idx = 0) const;
|
||||
|
||||
quint32 _tag;
|
||||
const QVector<quint32> *_subFields;
|
||||
Data _data;
|
||||
@ -40,6 +35,11 @@ public:
|
||||
bool readDDR();
|
||||
bool readRecord(Record &record);
|
||||
|
||||
bool subfield(const Field &field, quint32 name, int *val, int idx = 0) const;
|
||||
bool subfield(const Field &field, quint32 name, uint *val, int idx = 0) const;
|
||||
bool subfield(const Field &field, quint32 name, QByteArray *val,
|
||||
int idx = 0) const;
|
||||
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
static const Field *field(const Record &record, quint32 name);
|
||||
@ -103,6 +103,7 @@ private:
|
||||
bool readDDA(const FieldDefinition &def, SubFields &fields);
|
||||
bool readUDA(quint64 pos, const FieldDefinition &def,
|
||||
const QVector<SubFieldDefinition> &fields, bool repeat, Data &data);
|
||||
const QVariant *data(const Field &field, quint32 name, int idx = 0) const;
|
||||
|
||||
QFile _file;
|
||||
FieldsMap _map;
|
||||
|
@ -104,11 +104,11 @@ static uint order(uint type)
|
||||
return (it == orderMap.constEnd()) ? (type>>16) + 512 : it.value();
|
||||
}
|
||||
|
||||
static void warning(const ISO8211::Field &frid, uint prim)
|
||||
static void warning(const ISO8211 &ddf, const ISO8211::Field &frid, uint prim)
|
||||
{
|
||||
uint rcid = 0xFFFFFFFF;
|
||||
frid.subfield(RCID, &rcid);
|
||||
uint rcid;
|
||||
|
||||
if (ddf.subfield(frid, RCID, &rcid)) {
|
||||
switch (prim) {
|
||||
case PRIM_P:
|
||||
qWarning("%u: invalid point feature", rcid);
|
||||
@ -120,6 +120,7 @@ static void warning(const ISO8211::Field &frid, uint prim)
|
||||
qWarning("%u: invalid area feature", rcid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pointBounds(const Coordinates &c, double min[2], double max[2])
|
||||
@ -760,7 +761,7 @@ MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
|
||||
return (path.isEmpty() ? 0 : new Poly(objl, path, attributes(r), huni));
|
||||
}
|
||||
|
||||
bool MapData::processRecord(const ISO8211::Record &record,
|
||||
bool MapData::processRecord(const ISO8211 &ddf, const ISO8211::Record &record,
|
||||
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
|
||||
RecordMap &vf, uint &comf, uint &somf, uint &huni)
|
||||
{
|
||||
@ -795,9 +796,9 @@ bool MapData::processRecord(const ISO8211::Record &record,
|
||||
} else if (tag == FRID) {
|
||||
fe.append(record);
|
||||
} else if (tag == DSPM) {
|
||||
if (!(f.subfield(COMF, &comf) && f.subfield(SOMF, &somf)))
|
||||
if (!(ddf.subfield(f, COMF, &comf) && ddf.subfield(f, SOMF, &somf)))
|
||||
return false;
|
||||
if (!f.subfield(HUNI, &huni))
|
||||
if (!ddf.subfield(f, HUNI, &huni))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -820,7 +821,7 @@ MapData::MapData(const QString &path)
|
||||
if (!ddf.readDDR())
|
||||
return;
|
||||
while (ddf.readRecord(record))
|
||||
if (!processRecord(record, fe, vi, vc, ve, vf, comf, somf, huni))
|
||||
if (!processRecord(ddf, record, fe, vi, vc, ve, vf, comf, somf, huni))
|
||||
qWarning("Invalid S-57 record");
|
||||
|
||||
for (int i = 0; i < fe.size(); i++) {
|
||||
@ -846,7 +847,7 @@ MapData::MapData(const QString &path)
|
||||
pointBounds(point->pos(), min, max);
|
||||
_points.Insert(min, max, point);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(ddf, f, prim);
|
||||
}
|
||||
break;
|
||||
case PRIM_L:
|
||||
@ -854,14 +855,14 @@ MapData::MapData(const QString &path)
|
||||
rectcBounds(line->bounds(), min, max);
|
||||
_lines.Insert(min, max, line);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(ddf, f, prim);
|
||||
break;
|
||||
case PRIM_A:
|
||||
if ((poly = polyObject(r, vc, ve, comf, objl, huni))) {
|
||||
rectcBounds(poly->bounds(), min, max);
|
||||
_areas.Insert(min, max, poly);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(ddf, f, prim);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ private:
|
||||
static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc,
|
||||
const RecordMap &ve, uint comf, uint objl, uint huni);
|
||||
|
||||
static bool processRecord(const ISO8211::Record &record,
|
||||
static bool processRecord(const ISO8211 &ddf, const ISO8211::Record &record,
|
||||
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
|
||||
RecordMap &vf, uint &comf, uint &somf, uint &huni);
|
||||
|
||||
|
@ -61,32 +61,32 @@ ENCAtlas::IntendedUsage ENCAtlas::usage(const QString &path)
|
||||
return (IntendedUsage)iu;
|
||||
}
|
||||
|
||||
bool ENCAtlas::processRecord(const ISO8211::Record &record, QByteArray &file,
|
||||
RectC &bounds)
|
||||
bool ENCAtlas::processRecord(const ISO8211 &ddf, const ISO8211::Record &record,
|
||||
QByteArray &file, RectC &bounds)
|
||||
{
|
||||
if (record.size() < 2)
|
||||
return false;
|
||||
|
||||
const ENC::ISO8211::Field &f = record.at(1);
|
||||
const ENC::ISO8211::Field &field = record.at(1);
|
||||
|
||||
if (f.tag() == CATD) {
|
||||
if (field.tag() == CATD) {
|
||||
QByteArray impl;
|
||||
|
||||
if (!f.subfield(IMPL, &impl))
|
||||
if (!ddf.subfield(field, IMPL, &impl))
|
||||
return false;
|
||||
if (!f.subfield(F1LE, &file))
|
||||
if (!ddf.subfield(field, F1LE, &file))
|
||||
return false;
|
||||
|
||||
if (impl == "BIN" && file.endsWith("000")) {
|
||||
QByteArray slat, wlon, nlat, elon;
|
||||
|
||||
if (!f.subfield(SLAT, &slat))
|
||||
if (!ddf.subfield(field, SLAT, &slat))
|
||||
return false;
|
||||
if (!f.subfield(WLON, &wlon))
|
||||
if (!ddf.subfield(field, WLON, &wlon))
|
||||
return false;
|
||||
if (!f.subfield(NLAT, &nlat))
|
||||
if (!ddf.subfield(field, NLAT, &nlat))
|
||||
return false;
|
||||
if (!f.subfield(ELON, &elon))
|
||||
if (!ddf.subfield(field, ELON, &elon))
|
||||
return false;
|
||||
|
||||
bool ok1, ok2, ok3, ok4;
|
||||
@ -142,7 +142,7 @@ ENCAtlas::ENCAtlas(const QString &fileName, QObject *parent)
|
||||
return;
|
||||
}
|
||||
while (ddf.readRecord(record)) {
|
||||
if (processRecord(record, file, bounds))
|
||||
if (processRecord(ddf, record, file, bounds))
|
||||
addMap(dir, file, bounds);
|
||||
}
|
||||
if (!ddf.errorString().isNull()) {
|
||||
|
@ -76,8 +76,8 @@ private:
|
||||
void addMap(const QDir &dir, const QByteArray &file, const RectC &bounds);
|
||||
QList<ENC::Data*> levels() const;
|
||||
|
||||
static bool processRecord(const ENC::ISO8211::Record &record,
|
||||
QByteArray &file, RectC &bounds);
|
||||
static bool processRecord(const ENC::ISO8211 &ddf,
|
||||
const ENC::ISO8211::Record &record, QByteArray &file, RectC &bounds);
|
||||
static Range zooms(IntendedUsage usage);
|
||||
static IntendedUsage usage(const QString &path);
|
||||
|
||||
|
@ -104,7 +104,7 @@ bool ENCMap::bounds(const QVector<ISO8211::Record> &gv, Rect &b)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ENCMap::processRecord(const ISO8211::Record &record,
|
||||
bool ENCMap::processRecord(const ISO8211 &ddf, const ISO8211::Record &record,
|
||||
QVector<ISO8211::Record> &rv, uint &comf, QByteArray &dsnm)
|
||||
{
|
||||
if (record.size() < 2)
|
||||
@ -116,10 +116,10 @@ bool ENCMap::processRecord(const ISO8211::Record &record,
|
||||
if (tag == VRID) {
|
||||
rv.append(record);
|
||||
} else if (tag == DSID) {
|
||||
if (!f.subfield(DSNM, &dsnm))
|
||||
if (!ddf.subfield(f, DSNM, &dsnm))
|
||||
return false;
|
||||
} else if (tag == DSPM) {
|
||||
if (!f.subfield(COMF, &comf))
|
||||
if (!ddf.subfield(f, COMF, &comf))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ ENCMap::ENCMap(const QString &fileName, QObject *parent)
|
||||
return;
|
||||
}
|
||||
while (ddf.readRecord(record)) {
|
||||
if (!processRecord(record, gv, comf, dsnm)) {
|
||||
if (!processRecord(ddf, record, gv, comf, dsnm)) {
|
||||
_errorString = "Invalid S-57 record";
|
||||
return;
|
||||
}
|
||||
|
@ -96,8 +96,9 @@ private:
|
||||
|
||||
static bool bounds(const ENC::ISO8211::Record &record, Rect &rect);
|
||||
static bool bounds(const QVector<ENC::ISO8211::Record> &gv, Rect &b);
|
||||
static bool processRecord(const ENC::ISO8211::Record &record,
|
||||
QVector<ENC::ISO8211::Record> &rv, uint &comf, QByteArray &dsnm);
|
||||
static bool processRecord(const ENC::ISO8211 &ddf,
|
||||
const ENC::ISO8211::Record &record, QVector<ENC::ISO8211::Record> &rv,
|
||||
uint &comf, QByteArray &dsnm);
|
||||
|
||||
QString _name;
|
||||
ENC::MapData *_data;
|
||||
|
Loading…
x
Reference in New Issue
Block a user