diff --git a/src/map/ENC/iso8211.cpp b/src/map/ENC/iso8211.cpp index 7ec18b72..b81585c0 100644 --- a/src/map/ENC/iso8211.cpp +++ b/src/map/ENC/iso8211.cpp @@ -28,12 +28,23 @@ struct DR { char FieldTagSize; }; + +const QVariant *ISO8211::Field::data(const QByteArray &name, int idx) const +{ + const QVector &v = _data.at(idx); + + for (int i = 0; i < _subFields.size(); i++) + if (_subFields.at(i) == name) + return &v.at(i); + + return 0; +} + bool ISO8211::Field::subfield(const char *name, int *val, int idx) const { - const QVariant *v; bool ok; - v = data().field(name, idx); + const QVariant *v = data(name, idx); if (!v) return false; *val = v->toInt(&ok); @@ -43,10 +54,9 @@ bool ISO8211::Field::subfield(const char *name, int *val, int idx) const bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const { - const QVariant *v; bool ok; - v = data().field(name, idx); + const QVariant *v = data(name, idx); if (!v) return false; *val = v->toUInt(&ok); @@ -56,9 +66,7 @@ bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const { - const QVariant *v; - - v = data().field(name, idx); + const QVariant *v = data(name, idx); if (!v) return false; *val = v->toByteArray(); @@ -66,25 +74,24 @@ bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const return true; } -ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt, - const QByteArray &tag) +ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt) { if (str == "A" || str == "I" || str == "R") - return SubFieldDefinition(tag, String, cnt); + return SubFieldDefinition(String, cnt); else if (str == "B") - return SubFieldDefinition(tag, Array, cnt / 8); + return SubFieldDefinition(Array, cnt / 8); else if (str == "b11") - return SubFieldDefinition(tag, U8, 1); + return SubFieldDefinition(U8, 1); else if (str == "b12") - return SubFieldDefinition(tag, U16, 2); + return SubFieldDefinition(U16, 2); else if (str == "b14") - return SubFieldDefinition(tag, U32, 4); + return SubFieldDefinition(U32, 4); else if (str == "b21") - return SubFieldDefinition(tag, S8, 1); + return SubFieldDefinition(S8, 1); else if (str == "b22") - return SubFieldDefinition(tag, S16, 2); + return SubFieldDefinition(S16, 2); else if (str == "b24") - return SubFieldDefinition(tag, S32, 4); + return SubFieldDefinition(S32, 4); else return SubFieldDefinition(); } @@ -138,6 +145,7 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields) QByteArray ba; bool repeat = false; QVector defs; + QVector defTags; ba.resize(def.size); if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size())) @@ -155,6 +163,7 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields) int tag = 0; defs.resize(tags.size()); + defTags.resize(tags.size()); while (it.hasNext()) { QRegularExpressionMatch match = it.next(); @@ -176,16 +185,17 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields) } for (uint i = 0; i < cnt; i++) { - SubFieldDefinition sfd(fieldType(typeStr, size, tags.at(tag))); + SubFieldDefinition sfd(fieldType(typeStr, size)); if (sfd.type() == Unknown) return false; defs[tag] = sfd; + defTags[tag] = tags.at(tag); tag++; } } } - fields = SubFields(defs, repeat); + fields = SubFields(defTags, defs, repeat); return true; } @@ -223,7 +233,8 @@ bool ISO8211::readDDR() return true; } -bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data) +bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, + const QVector &fields, bool repeat, Data &data) { QByteArray ba; @@ -238,10 +249,10 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data) do { QVector row; - row.resize(data.fields()->size()); + row.resize(fields.size()); - for (int i = 0; i < data.fields()->size(); i++) { - const SubFieldDefinition &f = data.fields()->at(i); + for (int i = 0; i < fields.size(); i++) { + const SubFieldDefinition &f = fields.at(i); switch (f.type()) { case String: @@ -287,7 +298,7 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data) } data.append(row); - } while (data.fields()->repeat() && dp < ep); + } while (repeat && dp < ep); return true; } @@ -299,9 +310,9 @@ bool ISO8211::readRecord(Record &record) QVector fields; qint64 pos = _file.pos(); - int len = readDR(fields); - if (len < 0) { + + if (readDR(fields) < 0) { _errorString = "Error reading DR"; return false; } @@ -310,6 +321,7 @@ bool ISO8211::readRecord(Record &record) for (int i = 0; i < fields.size(); i++) { const FieldDefinition &def = fields.at(i); + Data data; FieldsMap::const_iterator it = _map.find(def.tag); if (it == _map.constEnd()) { @@ -317,15 +329,13 @@ bool ISO8211::readRecord(Record &record) return false; } - Data data(&it.value()); - - if (!readUDA(pos, def, data)) { + if (!readUDA(pos, def, it->defs(), it->repeat(), data)) { _errorString = QString("Error reading %1 record") .arg(QString(def.tag)); return false; } - record[i] = Field(def.tag, data); + record[i] = Field(def.tag, it->tags(), data); } return true; diff --git a/src/map/ENC/iso8211.h b/src/map/ENC/iso8211.h index 9ecd89d2..14f83dfa 100644 --- a/src/map/ENC/iso8211.h +++ b/src/map/ENC/iso8211.h @@ -17,87 +17,17 @@ namespace ENC { class ISO8211 { public: - enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32}; - - struct FieldDefinition - { - QByteArray tag; - int pos; - int size; - }; - - class SubFieldDefinition - { - public: - SubFieldDefinition() : _type(Unknown), _size(0) {} - SubFieldDefinition(const QByteArray &tag, FieldType type, int size) - : _tag(tag), _type(type), _size(size) {} - - const QByteArray &tag() const {return _tag;} - FieldType type() const {return _type;} - int size() const {return _size;} - - private: - QByteArray _tag; - FieldType _type; - int _size; - }; - - class SubFields - { - public: - SubFields() : _repeat(false) {} - SubFields(const QVector &defs, bool repeat) - : _defs(defs), _repeat(repeat) {} - - int size() const {return _defs.size();} - const SubFieldDefinition &at(int i) const {return _defs.at(i);} - - bool repeat() const {return _repeat;} - - private: - QVector _defs; - bool _repeat; - }; - - class Data - { - public: - Data() : _fields(0) {} - Data(const SubFields *fields) : _fields(fields) {} - - int size() const {return _data.size();} - const QVector &at(int i) const {return _data.at(i);} - - const SubFields *fields() const {return _fields;} - const QVariant *field(const QByteArray &name, int idx = 0) const - { - const QVector &v = _data.at(idx); - - for (int i = 0; i < _fields->size(); i++) - if (_fields->at(i).tag() == name) - return &v.at(i); - - return 0; - } - - private: - friend class ISO8211; - - void append(QVector &row) {_data.append(row);} - - QVector > _data; - const SubFields *_fields; - }; + typedef QVector > Data; class Field { public: Field() {} - Field(const QByteArray &tag, const Data &data) - : _tag(tag), _data(data) {} + Field(const QByteArray &tag, const QVector &subFields, + const Data &data) : _tag(tag), _subFields(subFields), _data(data) {} const QByteArray &tag() const {return _tag;} + const QVector subFields() const {return _subFields;} const Data &data() const {return _data;} bool subfield(const char *name, int *val, int idx = 0) const; @@ -105,7 +35,10 @@ public: bool subfield(const char *name, QByteArray *val, int idx = 0) const; private: + const QVariant *data(const QByteArray &name, int idx = 0) const; + QByteArray _tag; + QVector _subFields; Data _data; }; @@ -120,14 +53,57 @@ public: static const Field *field(const Record &record, const QByteArray &name); private: + enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32}; + + struct FieldDefinition + { + QByteArray tag; + int pos; + int size; + }; + + class SubFieldDefinition + { + public: + SubFieldDefinition() : _type(Unknown), _size(0) {} + SubFieldDefinition(FieldType type, int size) + : _type(type), _size(size) {} + + FieldType type() const {return _type;} + int size() const {return _size;} + + private: + FieldType _type; + int _size; + }; + + class SubFields + { + public: + SubFields() : _repeat(false) {} + SubFields(const QVector &tags, + const QVector &defs, bool repeat) + : _tags(tags), _defs(defs), _repeat(repeat) {} + + const QVector &tags() const {return _tags;} + const QVector &defs() const {return _defs;} + + bool repeat() const {return _repeat;} + + private: + QVector _tags; + QVector _defs; + bool _repeat; + }; + typedef QMap FieldsMap; - static SubFieldDefinition fieldType(const QString &str, int cnt, - const QByteArray &tag); + static SubFieldDefinition fieldType(const QString &str, int cnt); int readDR(QVector &fields); bool readDDA(const FieldDefinition &def, SubFields &fields); - bool readUDA(quint64 pos, const FieldDefinition &def, Data &data); + bool readUDA(quint64 pos, const FieldDefinition &def, + const QVector &fields, bool repeat, Data &data); QFile _file; FieldsMap _map; @@ -135,22 +111,9 @@ private: }; #ifndef QT_NO_DEBUG -inline QDebug operator<<(QDebug dbg, const ISO8211::FieldDefinition &def) -{ - dbg.nospace() << "FieldDefinition(" << def.tag << ", " << def.size << ")"; - return dbg.space(); -} - -inline QDebug operator<<(QDebug dbg, const ISO8211::SubFieldDefinition &def) -{ - dbg.nospace() << "SubField(" << def.tag() << ", " << def.type() << ", " - << def.size() << ")"; - return dbg.space(); -} - inline QDebug operator<<(QDebug dbg, const ISO8211::Field &field) { - dbg.nospace() << "Field(" << field.tag() << ")"; + dbg.nospace() << "Field(" << field.tag() << ", " << field.subFields() << ")"; return dbg.space(); } #endif // QT_NO_DEBUG