#include "mil2525d_to_mil2525c.h" #include "logging.h" #include #include #include #include #include #include #include #include namespace PlanEditor { namespace MIL2525 { class Converter::Internal { class CodePair : public QSharedData { public: unsigned int m_code2525d; QString m_sidc2525c; QRegularExpression m_sidcQuery; QString m_kindOfRubberband; explicit CodePair(unsigned int code, QString sidc, const QString &kindOfRubberband) : m_code2525d(code) , m_sidc2525c(sidc) , m_kindOfRubberband(kindOfRubberband) { sidc.replace(QLatin1Char('*'), QLatin1Char('.')); m_sidcQuery = QRegularExpression(sidc); if (m_kindOfRubberband.isEmpty()) m_kindOfRubberband = QStringLiteral("PointFeature"); } ~CodePair() = default; }; typedef QExplicitlySharedDataPointer CodePairPointer; QVector m_codePairList; QHash m_2525dToSidc; QHash> m_kindOfRubberbandHash; Logger m_logger; bool parseLine(const QString &line) { if (line.isEmpty()) return true; QVector tokenList = line.splitRef(QLatin1Char(';')); QRegularExpression sidcTemplate(QStringLiteral("^[A-Z]{1,1}\\*[A-Z]+[\\-\\*X]+$")); QString sidc; foreach (const auto &t, tokenList) { if (t.size() != 15) continue; const QString token(t.toString()); if (sidcTemplate.match(token).hasMatch()) { sidc = token; break; } } if (sidc.isEmpty()) return true; bool isNumber = false; const QStringRef &code2525d = tokenList.last(); unsigned int code = code2525d.toUInt(&isNumber); if (!isNumber) { return true; } if (m_2525dToSidc.contains(code)) return true; QStringRef kindOfRubberband; foreach (auto token, tokenList) { if (token.startsWith(QStringLiteral("gct_"))) { kindOfRubberband = token; break; } } CodePairPointer codePair(new CodePair(code, sidc.left(10), kindOfRubberband.toString())); m_2525dToSidc[code] = codePair; m_codePairList += codePair; m_kindOfRubberbandHash[codePair->m_kindOfRubberband] += codePair; return true; } public: Internal() : m_logger(getLogger("MIL2525-Converter")) { auto stripLeadingAndTrailingQuotes = [](QString str) -> QString { str = str.simplified(); if (str.startsWith(QLatin1Char('"'))) { str.remove(0, 1); if (str.endsWith(QLatin1Char('"'))) str.chop(1); } return str; }; QFile file(QCoreApplication::applicationDirPath() + QStringLiteral("/MIL2525D_to_MIL2525C.def")); if (file.exists()) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { unsigned int lineNo = 0; while (!file.atEnd()) { lineNo++; QString line(QString::fromLatin1(file.readLine())); if (lineNo > 1) { if (!parseLine(stripLeadingAndTrailingQuotes(line))) ERROR_LOG(m_logger) << "Error while parsing MIL2525D_toMIL2525C.def in line " << lineNo << ENDLOG(); } } file.close(); #ifdef LOG_gct_token file.setFileName(QStringLiteral("C:/MIL2525D_RubberbandKinds.txt")); if (file.open(QIODevice::OpenModeFlag::ReadWrite | QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::Text)) { QTextStream ostream(&file); for (auto keyIter = m_kindOfRubberbandHash.keyBegin(); keyIter != m_kindOfRubberbandHash.keyEnd(); ++keyIter) { const QString &kindOfRubberband = *keyIter; const QLinkedList &codeList = m_kindOfRubberbandHash[kindOfRubberband]; ostream.setFieldWidth(35); ostream.setFieldAlignment(QTextStream::FieldAlignment::AlignLeft); ostream << kindOfRubberband; ostream.setFieldAlignment(QTextStream::FieldAlignment::AlignRight); ostream.setFieldWidth(-1); foreach (const auto code, codeList) { ostream << '\n'; ostream.setFieldWidth(35); ostream << ' '; ostream.setFieldWidth(16); ostream << code->m_sidc2525c; ostream.setFieldWidth(9); ostream << code->m_code2525d; ostream.setFieldWidth(-1); } ostream << '\n'; ostream.flush(); } file.close(); } #endif } else ERROR_LOG(m_logger) << "Open file for reading failed: " << file.fileName() << ENDLOG(); } else ERROR_LOG(m_logger) << "File doesn't exist: " << file.fileName() << ENDLOG(); } ~Internal() { m_2525dToSidc.clear(); m_codePairList.clear(); m_codePairList.clear(); } QString baseSymbolFromSidc(const QString &sidc) const { foreach (auto codePairPtr, m_codePairList) { if (codePairPtr->m_sidcQuery.match(sidc).hasMatch()) return QString::number(codePairPtr->m_code2525d); } return QString(); } QString baseSymbolToSidc(const QString &baseSymbolCode) const { bool ok = false; unsigned int code = baseSymbolCode.toUInt(&ok); if (!ok) return QString(); auto it = m_2525dToSidc.find(code); if (it == m_2525dToSidc.end()) return QString(); return it.value()->m_sidc2525c; } }; Converter::Converter() : m_internal(new Internal()) {;} Converter::~Converter() { delete m_internal; } QString Converter::baseSymbolFromSidc(const QString &sidc) const { return m_internal->baseSymbolFromSidc(sidc); } QString Converter::baseSymbolToSidc(const QString &baseSymbolCode) const { return m_internal->baseSymbolToSidc(baseSymbolCode); } } }