TetraIF migration and Unittest Implementation for it

Entire-Checkpoint: 14d1fef0cf36
This commit is contained in:
berrux-dev committed 2026-09-12 13:54:34 +02:00
1 parent a86f9b5bac
commit ba212f9dce
78 files changed
+1611 -640

No files matched your search

Vendored
+25 -9
View File
@@ -1,9 +1,13 @@
pipeline {
agent {
docker {
image 'lifemaps/ci-cpp:latest'
// Unified build image, built from ci/Dockerfile.ci:
// docker build -f ci/Dockerfile.ci -t legatus-build:26.04 ci
// Push it to the registry the Jenkins agents pull from before enabling this.
image 'legatus-build:26.04'
reuseNode true
args '-u root:root'
// RTI Connext is not part of the image and has to be mounted read-only.
args '-u root:root -v /opt/rti_connext_dds-7.7.0:/opt/rti_connext_dds-7.7.0:ro'
}
}
@@ -13,12 +17,18 @@ pipeline {
}
environment {
PROJECT_DIR = "qt6-after/qt6-migrated-benchmark"
BUILD_DIR = "build"
PROJECT_DIR = "qt6-after/qt6-migrated-legatus"
BUILD_DIR = "qt6-after/qt6-migrated-legatus/build-ci"
CHANGE_TARGET = "${env.CHANGE_TARGET ?: 'origin/main'}"
QT_QPA_PLATFORM = "offscreen"
LANG = "C.UTF-8"
LC_ALL = "C.UTF-8"
// Targets known to build and test green today. A full `cmake --build` still
// fails outside TetraIF: Z/src/nglwidgets has an unfinished Poppler port, and
// several targets compile the RTI headers without -DRTI_UNIX. Widen this list
// as those modules get migrated.
BUILD_TARGETS = "CoPrtCnv PrtCnvLib PrtCnv LogView_console CoPrtCnvTests PrtCnvTests LogViewTests"
TEST_REGEX = "CoPrtCnvRadioTelegramTest|PrtCnvMemberTest|PrtCnvStoredTelegramTest|LogViewFieldTest|LogViewTetraTelegramsParserTest"
}
stages {
@@ -47,8 +57,8 @@ pipeline {
echo "QT_QPA_PLATFORM=$QT_QPA_PLATFORM"
echo "LANG=$LANG"
echo "LC_ALL=$LC_ALL"
dpkg -l | grep -E "qt6-base-dev|qtbase5-dev|qt6-tools" || true
pkg-config --list-all | grep -i qt || true
dpkg -l | grep -E "qt6-base-dev|qt6-tools|qt6-websockets-dev" || true
ls /opt/rti_connext_dds-7.7.0 >/dev/null && echo "RTI Connext mounted" || echo "RTI Connext MISSING"
'''
}
}
@@ -61,19 +71,25 @@ pipeline {
stage('Configure') {
steps {
sh 'cmake -S ${PROJECT_DIR} -B ${BUILD_DIR} -G Ninja -DCMAKE_BUILD_TYPE=Debug'
// The project pins CMAKE_CXX_STANDARD to 17; do not override it here.
sh '''
cmake -S ${PROJECT_DIR} -B ${BUILD_DIR} \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_RTI=ON \
-DBUILD_ARCGIS=OFF
'''
}
}
stage('Build') {
steps {
sh 'cmake --build ${BUILD_DIR} --parallel'
sh 'cmake --build ${BUILD_DIR} --parallel --target ${BUILD_TARGETS}'
}
}
stage('Test') {
steps {
sh 'QT_QPA_PLATFORM=offscreen LANG=C.UTF-8 LC_ALL=C.UTF-8 ctest --test-dir ${BUILD_DIR} --output-on-failure'
sh 'ctest --test-dir ${BUILD_DIR} -R "${TEST_REGEX}" --output-on-failure'
}
}
}
+70 -67
View File
@@ -1,88 +1,91 @@
# Unified build/CI image for the Legatus Qt6 migration.
#
# Build (context is ci/, which holds the RTI licence file):
# docker build -f ci/Dockerfile.ci -t legatus-build:26.04 ci
#
# RTI Connext is not baked into the image, it is mounted at run time:
# -v /path/to/rti_connext_dds-7.7.0:/opt/rti_connext_dds-7.7.0:ro
#
# Qt comes from the Ubuntu 26.04 packages (6.10.2). It is deliberately not
# installed through aqtinstall: libkf6texttemplate-dev, which Lts/Common/CodeGen
# requires, is linked against the distribution Qt6, and loading a second Qt6
# from /opt/Qt beside it would put two copies of QtCore in the same process.
FROM ubuntu:26.04
ENV DEBIAN_FRONTEND=noninteractive
ENV QT_VERSION=6.10.2
ENV QT_ARCH=linux_gcc_64
ENV QT_BASE_DIR=/opt/Qt
ENV QT_ROOT=/opt/Qt/6.10.2/gcc_64
ENV Qt6_ROOT=/opt/Qt/6.10.2/gcc_64
ENV CMAKE_PREFIX_PATH=/usr/local:/opt/Qt/6.10.2/gcc_64
ENV PATH=/opt/Qt/6.10.2/gcc_64/bin:$PATH
ENV LD_LIBRARY_PATH=/opt/Qt/6.10.2/gcc_64/lib:${LD_LIBRARY_PATH:-}
RUN apt-get update && \
apt-get install -y --no-install-recommends \
# Toolchain, CI tooling (policy checks and formatting), Qt 6.10.2 with every
# module the project's find_package() calls ask for, KDE text templating for
# Lts/Common/CodeGen, GoogleTest, and the third-party libraries the services link.
RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
build-essential \
g++ \
make \
cmake \
ninja-build \
pkg-config \
binutils \
gdb \
file \
less \
git \
ca-certificates \
openssh-client \
python3 \
python3-pip \
python3-venv \
clang-format \
cmake \
ninja-build \
git \
g++ \
make \
ca-certificates \
openssh-client \
pkg-config \
libpq-dev \
libbz2-dev \
qt6-base-dev \
qt6-tools-dev \
qt6-tools-dev-tools \
qt6-l10n-tools \
qt6-declarative-dev \
qt6-multimedia-dev \
qt6-positioning-dev \
qt6-serialport-dev \
qt6-svg-dev \
qt6-webengine-dev \
qt6-websockets-dev \
qt6-5compat-dev \
libgl-dev \
libkf6texttemplate-dev \
libgtest-dev \
libboost-all-dev \
libxml2-dev \
libbz2-dev \
libcurl4-openssl-dev \
libpq-dev \
libssl-dev \
libcurl4-openssl-dev && \
rm -rf /var/lib/apt/lists/*
libxml2-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Qt 6.10.2 via aqtinstall
RUN python3 -m venv /opt/venv && \
/opt/venv/bin/pip install --upgrade pip setuptools wheel && \
/opt/venv/bin/pip install aqtinstall && \
mkdir -p "${QT_BASE_DIR}" && \
/opt/venv/bin/python -m aqt install-qt linux desktop "${QT_VERSION}" "${QT_ARCH}" -m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine qtpdf qtwebview --outputdir "${QT_BASE_DIR}" && \
test -f "${QT_ROOT}/lib/cmake/Qt6/Qt6Config.cmake"
# Headless Qt, for tests that instantiate widgets.
ENV QT_QPA_PLATFORM=offscreen
# Install Log4Qt for Qt6
RUN git clone --depth 1 https://github.com/MEONMedical/Log4Qt.git /tmp/log4qt && \
cd /tmp/log4qt && \
mkdir -p build && cd build && \
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=23 \
-DCMAKE_CXX_EXTENSIONS=OFF \
-DCMAKE_PREFIX_PATH="${QT_ROOT}" \
-DCMAKE_INSTALL_PREFIX="/usr/local" \
-DBUILD_SHARED_LIBS=ON .. && \
cmake --build . -- -j$(nproc) && \
cmake --install . && \
rm -rf /tmp/log4qt
# Log4Qt is deliberately NOT installed. Its public header log4qt/level.h declares
# a defaulted C++20 operator<=>, so every consumer must be compiled with
# -std=c++20 or later. This project targets C++17, and pulling Log4Qt in makes
# Z/src/NGLLogger fail to compile. NGLLogger falls back to its own log4qt_stub.h
# when the package is absent. Re-enabling Log4Qt would require moving the whole
# project to C++20 first.
# Create minimal CMake config for Log4Qt
RUN mkdir -p /usr/local/lib/cmake/Log4Qt && \
cat > /usr/local/lib/cmake/Log4Qt/Log4QtConfig.cmake << 'EOF'
if (NOT TARGET Log4Qt::log4qt)
add_library(Log4Qt::log4qt UNKNOWN IMPORTED)
set_target_properties(Log4Qt::log4qt PROPERTIES
IMPORTED_LOCATION "/usr/local/lib/liblog4qt.so"
INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include"
)
endif()
set(Log4Qt_FOUND TRUE CACHE INTERNAL "Log4Qt found by package config")
set(Log4Qt_INCLUDE_DIRS "/usr/local/include" CACHE INTERNAL "Log4Qt include dir")
set(Log4Qt_LIBRARIES "/usr/local/lib/liblog4qt.so" CACHE INTERNAL "Log4Qt library")
EOF
# RTI Connext DDS - mounted at run time, see the header comment.
ENV RTI_CONNEXT_HOME=/opt/rti_connext_dds-7.7.0 \
NDDSHOME=/opt/rti_connext_dds-7.7.0 \
DDS_PATH=/opt/rti_connext_dds-7.7.0 \
PATH=/opt/rti_connext_dds-7.7.0/bin:$PATH \
LD_LIBRARY_PATH=/opt/rti_connext_dds-7.7.0/lib/x64Linux4gcc8.5.0
# Set Qt platform for headless testing
# ArcGIS SDK configuration
# Developer licence file. Override RTI_LICENSE_FILE to point at another one.
COPY rti_license.dat /root/rti_license.dat
ENV RTI_LICENSE_FILE=/root/rti_license.dat
# ArcGIS SDK - only needed with -DBUILD_ARCGIS=ON, mounted at run time.
ENV ARCGIS_ROOT=/repo/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk
ENV ARCGIS_INC_DIR=${ARCGIS_ROOT}/include
ENV ARCGIS_LIB_DIR=${ARCGIS_ROOT}/linux/x64/lib
# Set Qt platform for headless testing
ENV QT_QPA_PLATFORM=offscreen
# Configure git for containerized environments
# Containerised checkouts are owned by a different uid than the build user.
RUN git config --global --add safe.directory "*"
# Setup RTI Connext license (developer license file)
COPY rti_license.dat /root/rti_license.dat
ENV RTI_LICENSE_FILE=/root/rti_license.dat
WORKDIR /workspace
CMD ["bash"]
-13
View File
@@ -1,13 +0,0 @@
FROM lifemaps/ci-cpp:latest
# Qt6Multimedia ist bereits im Basis-Image installiert (libqt6multimedia6)
# RTI Connext wird zur Laufzeit gemounted (nicht im Image kopieren)
# Erwartet: -v /pfad/zu/rti_connext_dds-7.7.0:/opt/rti_connext_dds-7.7.0
ENV RTI_LICENSE_FILE=/root/rti_license.dat
ENV RTI_CONNEXT_HOME=/opt/rti_connext_dds-7.7.0
ENV NDDSHOME=/opt/rti_connext_dds-7.7.0
ENV PATH=/opt/rti_connext_dds-7.7.0/bin:$PATH
ENV LD_LIBRARY_PATH=/opt/rti_connext_dds-7.7.0/lib/x64Linux4gcc7.3.0:$LD_LIBRARY_PATH
ENV CMAKE_PREFIX_PATH=/opt/rti_connext_dds-7.7.0/lib/cmake:$CMAKE_PREFIX_PATH
WORKDIR /workspace
-36
View File
@@ -1,36 +0,0 @@
#!/bin/bash
# Install RTI Connext into existing Docker image
set -e
RTI_SOURCE="/home/torsten/swy/sandbox/external/rti_connext_dds-7.7.0"
BASE_IMAGE="lifemaps/ci-cpp:latest"
TARGET_IMAGE="lifemaps/ci-cpp:rti"
echo "Step 1: Create container from base image..."
CONTAINER_ID=$(docker create --name rti-install-temp $BASE_IMAGE /bin/bash)
echo "Step 2: Copy RTI Connext into container..."
docker cp "$RTI_SOURCE" "$CONTAINER_ID:/opt/rti_connext_dds-7.7.0"
echo "Step 3: Commit container as new image..."
docker commit $CONTAINER_ID $TARGET_IMAGE
echo "Step 4: Remove temporary container..."
docker rm $CONTAINER_ID
echo "Step 5: Set environment variables in image..."
docker run --rm $TARGET_IMAGE /bin/bash -c '
echo "RTI Connext installed successfully"
ls -la /opt/rti_connext_dds-7.7.0 | head -10
'
echo ""
echo "RTI Connext installed in image: $TARGET_IMAGE"
echo "To use this image, set environment variables:"
echo " docker run -e RTI_CONNEXT_HOME=/opt/rti_connext_dds-7.7.0 \\"
echo " -e NDDSHOME=/opt/rti_connext_dds-7.7.0 \\"
echo " -e PATH=/opt/rti_connext_dds-7.7.0/bin:\$PATH \\"
echo " -e LD_LIBRARY_PATH=/opt/rti_connext_dds-7.7.0/lib/x64Linux4gcc7.3.0:\$LD_LIBRARY_PATH \\"
echo " -e CMAKE_PREFIX_PATH=/opt/rti_connext_dds-7.7.0/lib/cmake:\$CMAKE_PREFIX_PATH \\"
echo " $TARGET_IMAGE"
+41 -1
View File
@@ -96,7 +96,12 @@ include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsCore)
include_directories(${CMAKE_SOURCE_DIR}/include/Viewer/SituationMap)
include_directories(${CMAKE_SOURCE_DIR}/include/OperatorManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/FileManagement)
SET(CMAKE_CXX_STANDARD 17)
# The project targets C++17. This was a plain SET() before, which silently
# shadowed any -DCMAKE_CXX_STANDARD= passed on the command line; the IF guard
# makes that override work again without changing the default.
IF(NOT CMAKE_CXX_STANDARD)
SET(CMAKE_CXX_STANDARD 17)
ENDIF()
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
SET(CMAKE_CXX_VISIBILITY_PRESET hidden)
@@ -180,6 +185,34 @@ ENDIF()
ENABLE_TESTING()
INCLUDE(CTest)
# GoogleTest is resolved once here so that every unittest/ subdirectory can just
# link GTest::gtest_main. Set LTS_FETCH_GOOGLETEST=OFF on an offline build machine
# that has no system-wide GTest; the unit tests are then skipped instead of
# failing the configure step.
OPTION(LTS_FETCH_GOOGLETEST "Download GoogleTest when no system-wide GTest is found" ON)
IF(BUILD_TESTING)
FIND_PACKAGE(GTest QUIET)
IF(NOT TARGET GTest::gtest_main AND LTS_FETCH_GOOGLETEST)
INCLUDE(FetchContent)
FETCHCONTENT_DECLARE(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
SET(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
FETCHCONTENT_MAKEAVAILABLE(googletest)
ENDIF()
IF(TARGET GTest::gtest_main)
SET(LTS_HAVE_GTEST TRUE)
ELSE()
SET(LTS_HAVE_GTEST FALSE)
MESSAGE(STATUS "GoogleTest not available - unit tests will not be built")
ENDIF()
ELSE()
SET(LTS_HAVE_GTEST FALSE)
ENDIF()
CONFIGURE_FILE(CTestCustom.ctest ${CMAKE_BINARY_DIR}/CTestCustom.ctest COPYONLY)
CONFIGURE_FILE(lts-cc.conf ${CMAKE_BINARY_DIR}/lts-cc.conf.distrib COPYONLY)
@@ -418,6 +451,13 @@ if(NOT TARGET Qt6::OpenGL)
message(STATUS "Created stub target for Qt6::OpenGL (library not available)")
endif()
# WebSockets is not part of the component list of the first find_package() above,
# and that call succeeds, so the fallback block that does request it never runs.
# Look the module up on its own before deciding whether a stub is needed.
if(NOT TARGET Qt6::WebSockets)
find_package(Qt6 6.2 COMPONENTS WebSockets QUIET)
endif()
# Stub Qt6::WebSockets target if not available (needed by LtsWebSocket, httq, etc.)
if(NOT TARGET Qt6::WebSockets)
add_library(Qt6::WebSockets INTERFACE IMPORTED)
@@ -1,34 +0,0 @@
# docker build -f Dockerfile.build -t legatus-build:26.04 .
FROM ubuntu:26.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
build-essential \
cmake \
libkf6texttemplate-dev \
libqt6core6 \
libqt6gui6 \
libqt6widgets6 \
qt6-base-dev \
qt6-tools-dev-tools \
qt6-tools-dev \
qt6-l10n-tools \
libgtest-dev \
git \
file \
binutils \
gdb \
less \
&& rm -rf /var/lib/apt/lists/*
ENV QT_QPA_PLATFORM=offscreen
ENV RTI_LICENSE_FILE=/workspace/rti_license.dat \
DDS_PATH=/opt/rti_connext_dds-7.7.0 \
NDDSHOME=/opt/rti_connext_dds-7.7.0 \
CMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64 \
LD_LIBRARY_PATH=/workspace/qt6-after/qt6-migrated-legatus/build4/lib:/opt/rti_connext_dds-7.7.0/lib/x64Linux4gcc8.5.0
WORKDIR /workspace/qt6-after/qt6-migrated-legatus
CMD ["bash"]
@@ -44,6 +44,11 @@ SET(SRCS_telegrams
training_area_telegrams.h
)
NGL_ADD_LIBRARY(AAR SV WS HLA tabTelegrams STATIC ${SRCS_telegrams})
# This static library is linked into shared libraries (CoPrtCnv among others),
# so its objects have to be position independent.
IF(TARGET tabTelegrams)
SET_TARGET_PROPERTIES(tabTelegrams PROPERTIES POSITION_INDEPENDENT_CODE ON)
ENDIF()
NGL_TARGET_INCLUDE_DIRECTORIES(tabTelegrams
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..
@@ -37,3 +37,8 @@ NGL_TARGET_INCLUDE_DIRECTORIES(CoPrtCnv
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}
)
# Unit tests (LTS_HAVE_GTEST is set by the top-level CMakeLists.txt)
if(BUILD_TESTING AND LTS_HAVE_GTEST)
add_subdirectory(unittest)
endif()
@@ -16,6 +16,7 @@
#include "CoPrtCnvRadioTelegram.hpp"
#include <QtCore/QByteArray>
#include <QtCore/QString>
#include <NGLLogger/NGLLoggerBootstrap.h>
static std::string dumpSammeldeaktivierung(const N_CoPrtCnv::CoPrtCnvRadioTelegram* sammelTelegram)
@@ -129,7 +130,7 @@ QByteArray telegramId2String(gef_telegramm_id_et telId)
Q_ASSERT(str);
if (!str)
str = "Unknown";
return str + QByteArray(" (") + QByteArray::number(int(telId)) + ")";
return QByteArray(str) + QByteArray(" (") + QByteArray::number(static_cast<int>(telId)) + ")";
}
QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wirkfeldTyp)
@@ -137,29 +138,29 @@ QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wir
switch(wirkfeldTyp)
{
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::MineArea:
return QLatin1String("MINENSPERRE");
return QStringLiteral("MINENSPERRE");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionArea:
return QLatin1String("FLAECHENFEUER");
return QStringLiteral("FLAECHENFEUER");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionSingle:
return QLatin1String("EINZELFEUER");
return QStringLiteral("EINZELFEUER");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::NContamination:
return QLatin1String("A_KAMPF");
return QStringLiteral("A_KAMPF");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::CContamination:
return QLatin1String("C_KAMPF");
return QStringLiteral("C_KAMPF");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::FunctionalArea:
return QLatin1String("FUNKTIONS_RAUM");
return QStringLiteral("FUNKTIONS_RAUM");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::TechnicalArea:
return QLatin1String("FUNKTIONS_RAUM_TECHNIK");
return QStringLiteral("FUNKTIONS_RAUM_TECHNIK");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::GasPipeDetonation:
return QLatin1String("GAS_PIPE_DETONATION");
return QStringLiteral("GAS_PIPE_DETONATION");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::SpecialArea:
return QLatin1String("SPECIAL_AREA");
return QStringLiteral("SPECIAL_AREA");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::Unknown:
return QLatin1String("DUS");
return QStringLiteral("DUS");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::DusSingleMineSimulator:
return QLatin1String("DUS_SINGLE_MINE_SIMULATOR");
return QStringLiteral("DUS_SINGLE_MINE_SIMULATOR");
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::BeStillWarning:
return QLatin1String("BE_STILL_WARNING");
return QStringLiteral("BE_STILL_WARNING");
}
return QStringLiteral("Unknown Wirkfeldtyp <%1>").arg(static_cast<int>(wirkfeldTyp));
}
@@ -14,6 +14,7 @@
#pragma once
#include <QtCore/QString>
#include <QtCore/QByteArray>
#include <NGLLogger/INGLLogger.h>
#include <TrainingAreaBase/training_area_telegrams.h>
#include "coprtcnv_export.h"
@@ -24,9 +25,10 @@ namespace N_CoPrtCnv
class CoPrtCnvRadioTelegram;
}
COPRTCNV_EXPORT QByteArray telegramId2String(gef_telegramm_id_et telId);
// Qt6/C++17: [[nodiscard]] indicates return value should not be ignored
[[nodiscard]] COPRTCNV_EXPORT QByteArray telegramId2String(gef_telegramm_id_et telId);
COPRTCNV_EXPORT void dumpTelegram(NGL::INGLLogger &m_logger,
int id,
N_CoPrtCnv::CoPrtCnvRadioTelegram *a_radioTelegram,
const char *prefix = nullptr);
COPRTCNV_EXPORT QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wirkfeldTyp);
[[nodiscard]] COPRTCNV_EXPORT QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wirkfeldTyp);
@@ -296,13 +296,13 @@ uint32_t CoPrtCnvRadioTelegram::getPayloadDataUInt32(size_t a_offset, uint16_t a
{
case 4:
ptrValue[3] = ptr[a_offset++];
Q_FALLTHROUGH();
[[fallthrough]];
case 3:
ptrValue[2] = ptr[a_offset++];
Q_FALLTHROUGH();
[[fallthrough]];
case 2:
ptrValue[1] = ptr[a_offset++];
Q_FALLTHROUGH();
[[fallthrough]];
case 1:
ptrValue[0] = ptr[a_offset++];
break;
@@ -949,7 +949,7 @@ bool CoPrtCnvRadioTelegram::isContentValid()
case GEF_WIRKFELD_EINZELMINENSIMULATOR:
wirkfeldkennung = getPayloadDataUInt32(5, 2);
wirkfeldtyp = 3;
Q_FALLTHROUGH();
[[fallthrough]];
case GEF_DEAKTIVIERUNG_WIRKFELD:
case GEF_WIRKFELD_AENDERUNG_BEZEICHNER:
if (GEF_DEAKTIVIERUNG_WIRKFELD == getTelID() || GEF_WIRKFELD_AENDERUNG_BEZEICHNER == getTelID())
@@ -1239,7 +1239,7 @@ bool CoPrtCnvRadioTelegram::mustBeSentAsBroadcast(time_t a_currentTime, bool& a_
break;
}
++m_BroadcastCounter;
Q_FALLTHROUGH();
[[fallthrough]];
case 1:
if (s_3rdDelay >= 0)
{
@@ -1249,7 +1249,7 @@ bool CoPrtCnvRadioTelegram::mustBeSentAsBroadcast(time_t a_currentTime, bool& a_
break;
}
++m_BroadcastCounter;
Q_FALLTHROUGH();
[[fallthrough]];
default:
INFO_LOG(m_logger) << "3rd Broadcast-Telegram telId=" << getTelID()
<< " BC=" << getBroadcastIndex();
@@ -0,0 +1,20 @@
# Unit tests for the CoPrtCnv library.
# GoogleTest is resolved once in the top-level CMakeLists.txt.
add_executable(CoPrtCnvTests
${CMAKE_CURRENT_SOURCE_DIR}/../../unittest_main.cpp
CoPrtCnvRadioTelegramTest.cpp
)
target_include_directories(CoPrtCnvTests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..
)
target_link_libraries(CoPrtCnvTests PRIVATE
CoPrtCnv
Qt6::Core
GTest::gtest
)
include(GoogleTest)
gtest_discover_tests(CoPrtCnvTests)
@@ -0,0 +1,167 @@
/**
* @file CoPrtCnvRadioTelegramTest.cpp
* @brief Unit tests for N_CoPrtCnv::CoPrtCnvRadioTelegram.
*
* Covers the constructors that build a telegram from scratch, the header
* accessors (ISSIs, telegram id, PDU type, identity) and the payload helpers.
* Payload words are stored MSB first, which several of these tests pin down.
*/
#include <gtest/gtest.h>
#include <QtCore/QByteArray>
#include "CoPrtCnvRadioTelegram.hpp"
#include "tetra_telegram_ids.h"
using N_CoPrtCnv::CoPrtCnvRadioTelegram;
TEST(CoPrtCnvRadioTelegramTest, RegisterIndCarriesSourceIssi)
{
const uint32_t sourceISSI = 0x123456;
const CoPrtCnvRadioTelegram telegram(sourceISSI);
EXPECT_EQ(telegram.getSrcISSI(), sourceISSI);
EXPECT_EQ(telegram.getPDU_Type(), CoPrtCnvRadioTelegram::e_RegisterInd);
EXPECT_EQ(telegram.getSize(), 9);
}
TEST(CoPrtCnvRadioTelegramTest, HeaderStartsWithMagicNumber)
{
const CoPrtCnvRadioTelegram telegram(1234);
ASSERT_GT(telegram.getSize(), 0);
EXPECT_EQ(static_cast<uint8_t>(telegram.data().at(0)), CoPrtCnvRadioTelegram::MAGIC_NUMBER);
}
TEST(CoPrtCnvRadioTelegramTest, SetSrcIssiOverwritesPreviousValue)
{
CoPrtCnvRadioTelegram telegram(1);
telegram.setSrcISSI(0xABCDEF);
EXPECT_EQ(telegram.getSrcISSI(), 0xABCDEFu);
telegram.setSrcISSI(0);
EXPECT_EQ(telegram.getSrcISSI(), 0u);
}
TEST(CoPrtCnvRadioTelegramTest, TelegramIdConstructorSetsIdAndIdentity)
{
const uint16_t payloadSize = 8;
const uint16_t identity = 0x0042;
const CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, payloadSize, identity);
EXPECT_EQ(telegram.getTelID(), GEF_POSITIONS_MELDUNG);
EXPECT_EQ(telegram.getIdentity(), identity);
EXPECT_EQ(telegram.getPDU_Type(), CoPrtCnvRadioTelegram::e_DataIndReq);
EXPECT_EQ(telegram.getSize(),
payloadSize + CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH);
}
TEST(CoPrtCnvRadioTelegramTest, TelegramIdConstructorProducesANormalTelegram)
{
const CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
EXPECT_TRUE(telegram.isNormalTelegram());
EXPECT_FALSE(telegram.isLoginTelegram());
}
TEST(CoPrtCnvRadioTelegramTest, SetIdentityIsReadBack)
{
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setIdentity(0x1234);
EXPECT_EQ(telegram.getIdentity(), 0x1234);
// The identity lives behind the telegram id, which must survive the write.
EXPECT_EQ(telegram.getTelID(), GEF_POSITIONS_MELDUNG);
}
TEST(CoPrtCnvRadioTelegramTest, TelegramIdIsTruncatedToASingleByte)
{
// The telegram id is written into one payload byte, so ids of 256 and above
// are stored truncated. GEF_GEFECHTSFELDTELEGRAMM (300) reads back as 44.
const CoPrtCnvRadioTelegram telegram(GEF_GEFECHTSFELDTELEGRAMM, 8, 0);
EXPECT_EQ(static_cast<int>(telegram.getTelID()), GEF_GEFECHTSFELDTELEGRAMM & 0xFF);
EXPECT_NE(static_cast<int>(telegram.getTelID()), int(GEF_GEFECHTSFELDTELEGRAMM));
}
TEST(CoPrtCnvRadioTelegramTest, PayloadWordsAreStoredMostSignificantByteFirst)
{
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setPayloadDataWithIndex(4, 0x00112233, 4);
EXPECT_EQ(telegram.getPayloadDataUInt32(4, 4), 0x00112233u);
EXPECT_EQ(telegram.getPayloadDataUInt8(4), 0x00);
EXPECT_EQ(telegram.getPayloadDataUInt8(5), 0x11);
EXPECT_EQ(telegram.getPayloadDataUInt8(6), 0x22);
EXPECT_EQ(telegram.getPayloadDataUInt8(7), 0x33);
}
TEST(CoPrtCnvRadioTelegramTest, PayloadDataUInt32HonoursRequestedWidth)
{
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setPayloadDataWithIndex(4, 0x00112233, 4);
EXPECT_EQ(telegram.getPayloadDataUInt32(4, 1), 0x00u);
EXPECT_EQ(telegram.getPayloadDataUInt32(5, 2), 0x1122u);
EXPECT_EQ(telegram.getPayloadDataUInt32(5, 3), 0x112233u);
}
TEST(CoPrtCnvRadioTelegramTest, ConstructingFromRawDataPreservesBytes)
{
const CoPrtCnvRadioTelegram source(0x00ABCD);
const QByteArray raw = source.data();
const CoPrtCnvRadioTelegram restored(raw);
EXPECT_EQ(restored.data(), raw);
EXPECT_EQ(restored.getSrcISSI(), source.getSrcISSI());
EXPECT_EQ(restored.getPDU_Type(), source.getPDU_Type());
}
TEST(CoPrtCnvRadioTelegramTest, TelegramLengthLimits)
{
EXPECT_TRUE(CoPrtCnvRadioTelegram::isTelegramLengthOk(1));
EXPECT_TRUE(CoPrtCnvRadioTelegram::isTelegramLengthOk(
CoPrtCnvRadioTelegram::MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH));
EXPECT_FALSE(CoPrtCnvRadioTelegram::isTelegramLengthOk(0xFFFF));
}
TEST(CoPrtCnvRadioTelegramTest, LoginTelegramIsRecognised)
{
const CoPrtCnvRadioTelegram login(CoPrtCnvRadioTelegram::e_LoginRequest, 0x0001, 0x001234);
EXPECT_TRUE(login.isLoginTelegram());
EXPECT_FALSE(login.isNormalTelegram());
EXPECT_EQ(login.getIdentity(), 0x0001);
EXPECT_EQ(login.getDestISSI(), 0x001234u);
}
TEST(CoPrtCnvRadioTelegramTest, BroadcastIndexRoundTrips)
{
// getBroadcastIndex() only reports an index when the payload extends past
// offset 4, so the telegram needs more than five payload bytes.
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setBroadcastIndex(0x0107);
EXPECT_EQ(telegram.getBroadcastIndex(), 0x0107);
}
TEST(CoPrtCnvRadioTelegramTest, CounterRoundTrips)
{
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setZaehler(0x2A);
EXPECT_EQ(telegram.zaehler(), 0x2A);
}
TEST(CoPrtCnvRadioTelegramTest, DestIssiRoundTrips)
{
CoPrtCnvRadioTelegram telegram(GEF_POSITIONS_MELDUNG, 8, 0);
telegram.setDestISSI(0x00FEDC);
EXPECT_EQ(telegram.getDestISSI(), 0x00FEDCu);
}
@@ -65,7 +65,10 @@ SET(my_SRCS
zsksxd_tetraForLogView.x
)
QT5_ADD_RESOURCES(my_SRCS LogViewResources.qrc)
# Qt6 replaces the QT5_ADD_RESOURCES macro with qt6_add_resources.
if(QT6_GUI_AVAILABLE)
qt6_add_resources(my_SRCS LogViewResources.qrc)
endif()
NGL_ADD_TOOL_ICON(my_SRCS)
NGL_ADD_EXECUTABLE(AAR SV NO_TRANSLATION LogView ${my_SRCS})
@@ -114,3 +117,7 @@ if (TARGET LogView)
endif()
endif()
# Unit tests (LTS_HAVE_GTEST is set by the top-level CMakeLists.txt)
if(BUILD_TESTING AND LTS_HAVE_GTEST)
add_subdirectory(unittest)
endif()
@@ -30,7 +30,7 @@ QByteArray formatTime(quint64 t)
const quint64 secs = t >> 32;
const quint64 usecs = t & 0xFFFFFFFF;
const quint64 msecs = usecs / 1000;
return QDateTime::fromMSecsSinceEpoch(secs * 1000 + msecs).toString(QLatin1String("yy-MM-dd hh:mm:ss.zzz")).toUtf8();
return QDateTime::fromMSecsSinceEpoch(secs * 1000 + msecs).toString(QStringLiteral("yy-MM-dd hh:mm:ss.zzz")).toUtf8();
}
int main(int argc, char **argv)
@@ -46,7 +46,7 @@ LogViewDateTimeEdit::LogViewDateTimeEdit(LogViewField* a_field, QWidget* a_paren
setDateTime(QDateTime::fromMSecsSinceEpoch(unixTime));
setDisplayFormat(QLatin1String("dd MMM yyyy hh:mm:ss"));
setDisplayFormat(QStringLiteral("dd MMM yyyy hh:mm:ss"));
setCalendarPopup(true);
updateToolTip(QString::number(unixTime));
@@ -31,7 +31,8 @@ LogViewField::LogViewField(const QString& a_name, const E_FieldKind a_kind, cons
m_HasContent(true),
m_bDeleteXdr(false),
m_Kind(a_kind),
m_XdrElement(a_xdrElement)
m_XdrElement(a_xdrElement),
m_logger(getLogger("LogViewField"))
{
}
@@ -143,8 +144,8 @@ int64_t LogViewField::getHighestValue() const
uint16_t bitSize = 8*static_cast<const LogViewXdrStandardType*>(m_XdrElement)->getEditSize();
if ((0 == m_Name.compare(QLatin1String("utm nordwert"), Qt::CaseInsensitive)) ||
(0 == m_Name.compare(QLatin1String("utm ostwert"), Qt::CaseInsensitive)))
if ((0 == m_Name.compare(QStringLiteral("utm nordwert"), Qt::CaseInsensitive)) ||
(0 == m_Name.compare(QStringLiteral("utm ostwert"), Qt::CaseInsensitive)))
bitSize -= 8;
switch (static_cast<const LogViewXdrStandardType*>(m_XdrElement)->getValueKind()) {
@@ -152,7 +153,7 @@ int64_t LogViewField::getHighestValue() const
return 1;
case LogViewXdrStandardType::e_Signed:
bitSize--;
Q_FALLTHROUGH();
[[fallthrough]];
case LogViewXdrStandardType::e_Unsigned:
case LogViewXdrStandardType::e_Data:
highest = highest << bitSize;
@@ -228,7 +229,7 @@ QString LogViewField::makeClean(const QString &text)
{
QString a_uncleanText = text;
if (a_uncleanText.endsWith(QLatin1String("_rt")))
if (a_uncleanText.endsWith(QStringLiteral("_rt")))
a_uncleanText = a_uncleanText.left(a_uncleanText.length() - 3);
@@ -255,13 +256,13 @@ QString LogViewField::makeClean(const QString &text)
bool LogViewField::isDateTimeField() const
{
QString name = m_Name.toLower();
return name == QLatin1String("gps_zeit");
return name == QStringLiteral("gps_zeit");
}
bool LogViewField::isMSecsField() const
{
QString name = m_Name.toLower();
return (name == QLatin1String("timestamp")) || (name == QLatin1String("effectstart"));
return (name == QStringLiteral("timestamp")) || (name == QStringLiteral("effectstart"));
}
@@ -133,6 +133,8 @@ namespace N_LogView
const LogViewXdrElement *m_XdrElement;
LOGGER_T m_logger;
private:
};
}
@@ -72,8 +72,9 @@ LogViewGui::LogViewGui(QWidget* a_parent)
, m_InjectionThread(nullptr)
, m_replayTimer(new QTimer(this))
, m_currentReplayRow(-1)
, m_logger(getLogger("LogViewGui"))
{
setWindowIcon(QIcon(QLatin1String(":icons/16x16/rde_16x16.png")));
setWindowIcon(QIcon(QStringLiteral(":icons/16x16/rde_16x16.png")));
QSettings settings;
settings.beginGroup(WINDOW_GROUP);
@@ -96,7 +97,7 @@ LogViewGui::LogViewGui(QWidget* a_parent)
QString tipText;
QAction* action = new QAction(tr("Neue Log-Datei"), this);
action->setIcon(QIcon(QLatin1String(":icons/16x16/document-new.png")));
action->setIcon(QIcon(QStringLiteral(":icons/16x16/document-new.png")));
action->setShortcut(tr("Ctrl+N"));
tipText = tr("Eine neue Telegram-Log-Datei anzeigen (Ctrl-N)");
action->setStatusTip(tipText);
@@ -105,7 +106,7 @@ LogViewGui::LogViewGui(QWidget* a_parent)
toolBar->addAction(action);
action = new QAction(tr("Log-Datei hinzu"), this);
action->setIcon(QIcon(QLatin1String(":icons/16x16/document-import.png")));
action->setIcon(QIcon(QStringLiteral(":icons/16x16/document-import.png")));
action->setShortcut(tr("Ctrl+O"));
tipText = tr("Eine weitere Telegramm-Log-Datei anzeigen (Ctrl-O)");
action->setStatusTip(tipText);
@@ -116,7 +117,7 @@ LogViewGui::LogViewGui(QWidget* a_parent)
m_reloadAction = new QAction(tr("&Reload"), this);
m_reloadAction->setCheckable(true);
m_reloadAction->setChecked(m_DoReload);
m_reloadAction->setIcon(QIcon(QLatin1String(":icons/16x16/edit-redo.png")));
m_reloadAction->setIcon(QIcon(QStringLiteral(":icons/16x16/edit-redo.png")));
m_reloadAction->setShortcut(tr("Ctrl+R"));
tipText = tr("Reload des Logfiles ein-/ausschalten (Ctrl-R)");
m_reloadAction->setStatusTip(tipText);
@@ -125,7 +126,7 @@ LogViewGui::LogViewGui(QWidget* a_parent)
toolBar->addAction(m_reloadAction);
action = new QAction(tr("&Einstellungen"), this);
action->setIcon(QIcon(QLatin1String(":icons/16x16/configure.png")));
action->setIcon(QIcon(QStringLiteral(":icons/16x16/configure.png")));
action->setShortcut(tr("Ctrl+E"));
tipText = tr("Verhalten des Programmes einstellen (Ctrl-E)");
action->setStatusTip(tipText);
@@ -135,7 +136,7 @@ LogViewGui::LogViewGui(QWidget* a_parent)
toolBar->addSeparator();
action = new QAction(tr("&Beenden"), this);
action->setIcon(QIcon(QLatin1String(":icons/16x16/edit-delete.png")));
action->setIcon(QIcon(QStringLiteral(":icons/16x16/edit-delete.png")));
action->setShortcut(tr("Alt-F4"));
tipText = tr("LogView beenden (Alt-F4)");
action->setStatusTip(tipText);
@@ -176,11 +177,11 @@ LogViewGui::LogViewGui(QWidget* a_parent)
m_ToolBox = new QToolBox(this);
m_ToolBox->addItem(m_CentralSelectionGroup, QIcon(QLatin1String(":/image/Central.png")), tr("&Zentral-Telegramm-Filter"));
m_ToolBox->addItem(m_TetraSelectionGroup, QIcon(QLatin1String(":/image/Tetra.png")), tr("TET&RA-Telegramm-Filter"));
m_ToolBox->addItem(m_WlsSelectionGroup, QIcon(QLatin1String(":/image/Wls.png")), tr("&WLS-Telegramm-Filter"));
m_ToolBox->addItem(m_ParticipantSelectionGroup, QIcon(QLatin1String(":/image/TNE.png")), tr("Teilnehmer-&Filter"));
m_ToolBox->addItem(m_EditTelegramController->tableView(), QIcon(QLatin1String(":icons/16x16/document-edit.png")), tr("&Edit && Sende Telegramme"));
m_ToolBox->addItem(m_CentralSelectionGroup, QIcon(QStringLiteral(":/image/Central.png")), tr("&Zentral-Telegramm-Filter"));
m_ToolBox->addItem(m_TetraSelectionGroup, QIcon(QStringLiteral(":/image/Tetra.png")), tr("TET&RA-Telegramm-Filter"));
m_ToolBox->addItem(m_WlsSelectionGroup, QIcon(QStringLiteral(":/image/Wls.png")), tr("&WLS-Telegramm-Filter"));
m_ToolBox->addItem(m_ParticipantSelectionGroup, QIcon(QStringLiteral(":/image/TNE.png")), tr("Teilnehmer-&Filter"));
m_ToolBox->addItem(m_EditTelegramController->tableView(), QIcon(QStringLiteral(":icons/16x16/document-edit.png")), tr("&Edit && Sende Telegramme"));
m_ToolBox->setCurrentIndex(settings.value(TOOLBOXINDEX).toInt());
@@ -273,13 +274,13 @@ LogViewGui::LogViewGui(QWidget* a_parent)
void LogViewGui::createCentralSelectionWidget()
{
m_SentCentralTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/P2C.png"));
m_SentCentralTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QStringLiteral(":/image/P2C.png"));
m_ReceivedCentralTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/C2P.png"));
m_ReceivedCentralTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QStringLiteral(":/image/C2P.png"));
m_PosCentralTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/CentralPos.png"));
m_PosCentralTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QStringLiteral(":/image/CentralPos.png"));
m_ackCentralTelCheckBox = createRadioButton(tr("&Bestaetigungstelegramme"), QLatin1String(":/image/CentralAck.png"));
m_ackCentralTelCheckBox = createRadioButton(tr("&Bestaetigungstelegramme"), QStringLiteral(":/image/CentralAck.png"));
QVBoxLayout* centralFilterBox = new QVBoxLayout;
centralFilterBox->addWidget(m_SentCentralTelCheckBox);
@@ -298,21 +299,21 @@ void LogViewGui::createCentralSelectionWidget()
void LogViewGui::createTetraSelectionWidget()
{
m_SentTetraTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/T2P.png"));
m_SentTetraTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QStringLiteral(":/image/T2P.png"));
m_ReceivedTetraTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/P2T.png"));
m_ReceivedTetraTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QStringLiteral(":/image/P2T.png"));
m_PosTetraTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/TetraPos.png"));
m_PosTetraTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QStringLiteral(":/image/TetraPos.png"));
m_FragmentedTetraTelCheckBox = createRadioButton(tr("&Fragmentierte Meldungen"), QLatin1String(":/image/TetraFragmented.png"));
m_FragmentedTetraTelCheckBox = createRadioButton(tr("&Fragmentierte Meldungen"), QStringLiteral(":/image/TetraFragmented.png"));
m_LoginTetraTelCheckBox = createRadioButton(tr("&Loginmeldungen"), QLatin1String(":/image/TetraLogin.png"));
m_LoginTetraTelCheckBox = createRadioButton(tr("&Loginmeldungen"), QStringLiteral(":/image/TetraLogin.png"));
m_RegisterTetraTelCheckBox = createRadioButton(tr("&Registermeldungen"), QLatin1String(":/image/TetraRegister.png"));
m_RegisterTetraTelCheckBox = createRadioButton(tr("&Registermeldungen"), QStringLiteral(":/image/TetraRegister.png"));
m_ReportTetraTelCheckBox = createRadioButton(tr("&Reportmeldungen"), QLatin1String(":/image/TetraReport.png"));
m_ReportTetraTelCheckBox = createRadioButton(tr("&Reportmeldungen"), QStringLiteral(":/image/TetraReport.png"));
m_AirInterfaceLoadTetraTelCheckBox = createRadioButton(tr("&Air-Load Meldungen"), QLatin1String(":/image/TetraAirInterface.png"));
m_AirInterfaceLoadTetraTelCheckBox = createRadioButton(tr("&Air-Load Meldungen"), QStringLiteral(":/image/TetraAirInterface.png"));
QVBoxLayout* tetraFilterBox = new QVBoxLayout;
tetraFilterBox->addWidget(m_SentTetraTelCheckBox);
@@ -335,11 +336,11 @@ void LogViewGui::createTetraSelectionWidget()
void LogViewGui::createWlsSelectionWidget()
{
m_SentWlsTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QLatin1String(":/image/P2W.png"));
m_SentWlsTelCheckBox = createRadioButton(tr("&gesendete Telegramme"), QStringLiteral(":/image/P2W.png"));
m_ReceivedWlsTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QLatin1String(":/image/W2P.png"));
m_ReceivedWlsTelCheckBox = createRadioButton(tr("&empfangene Telegramme"), QStringLiteral(":/image/W2P.png"));
m_PosWlsTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QLatin1String(":/image/WlsPos.png"));
m_PosWlsTelCheckBox = createRadioButton(tr("&Positionsmeldungen"), QStringLiteral(":/image/WlsPos.png"));
QVBoxLayout* wlsFilterBox = new QVBoxLayout;
wlsFilterBox->addWidget(m_SentWlsTelCheckBox);
@@ -405,7 +406,7 @@ void LogViewGui::showHexData()
void LogViewGui::exportAsCsv()
{
const int idx = m_ActualLogfile.lastIndexOf(QLatin1Char('.'));
const QString suggestion = m_ActualLogfile.left(idx) + QLatin1String(".csv");
const QString suggestion = m_ActualLogfile.left(idx) + QStringLiteral(".csv");
const QString fn = QFileDialog::getSaveFileName(this, tr("Export logdata as CSV"), suggestion, tr("CSV file (*.csv)"));
if (fn.isEmpty())
return;
@@ -445,7 +446,7 @@ void LogViewGui::exportAsCsv()
void LogViewGui::exportAsJson()
{
const int idx = m_ActualLogfile.lastIndexOf(QLatin1Char('.'));
const QString suggestion = m_ActualLogfile.left(idx) + QLatin1String(".csv");
const QString suggestion = m_ActualLogfile.left(idx) + QStringLiteral(".csv");
const QString fn = QFileDialog::getSaveFileName(this, tr("Export logdata as Json"), suggestion, tr("JSon file (*.json)"));
if (fn.isEmpty())
return;
@@ -542,7 +543,7 @@ void LogViewGui::loadSpecificationFiles()
settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
QString defString = QCoreApplication::applicationDirPath() + QLatin1String("/training_area_telegrams.h");
QString defString = QCoreApplication::applicationDirPath() + QStringLiteral("/training_area_telegrams.h");
QString filename = settings.value(LogViewOptionDialog::P0_FILENAME, defString).toString();
INFO_LOG(m_logger) << "Load central-protocol spezification-file: " << filename.toStdString();
if (!QFile::exists(filename))
@@ -553,7 +554,7 @@ void LogViewGui::loadSpecificationFiles()
LogViewTelegram::jsonParser()->parse(filename);
defString = QCoreApplication::applicationDirPath() + QLatin1String("/zsksxd_tetraForLogView.x");
defString = QCoreApplication::applicationDirPath() + QStringLiteral("/zsksxd_tetraForLogView.x");
filename = settings.value(LogViewOptionDialog::P5_FILENAME, defString).toString();
INFO_LOG(m_logger) << "Load tetra-protocol spezification-file: " << filename.toStdString();
if (!QFile::exists(filename))
@@ -589,7 +590,7 @@ void LogViewGui::loadTelegramFile()
{
const QLatin1String DIR("Dir");
QSettings settings;
settings.beginGroup(QLatin1String("LogFiles"));
settings.beginGroup(QStringLiteral("LogFiles"));
QString filename = QFileDialog::getOpenFileName(this, tr("Bitte eine Log-Datei auswaehlen"), settings.value(DIR).toString(), LogViewOptionDialog::KRLOG_FILES);
if (filename.isEmpty())
@@ -655,7 +656,7 @@ void LogViewGui::updateLogfile()
QString filePath(fileInfo.absolutePath() + QLatin1Char('/'));
const QString baseName = fileInfo.baseName();
const QVector<QStringRef> parts = baseName.splitRef(QLatin1Char('_'));
const QList<QStringView> parts = QStringView(baseName).split(QLatin1Char('_'));
for (int iterator = 0; iterator < parts.size() - 2; ++iterator)
filePath += parts.at(iterator).toString() + QLatin1Char('_');
@@ -909,19 +910,19 @@ void LogViewGui::startInjectionThread()
m_InjectionThread = new LogViewInjectionThread();
QSettings settings;
settings.beginGroup(QLatin1String("LogFiles"));
QString filePath = settings.value(QLatin1String("Dir")).toString();
settings.beginGroup(QStringLiteral("LogFiles"));
QString filePath = settings.value(QStringLiteral("Dir")).toString();
QString exerciseName;
QVector<QStringRef> parts = filePath.splitRef(QLatin1Char('/'));
const QList<QStringView> parts = QStringView(filePath).split(QLatin1Char('/'));
if (parts.size() >= 2)
exerciseName = QLatin1Char('_') + parts.at(parts.size() - 2).toString();
QString portFilePath = QCoreApplication::applicationDirPath() + QDir::separator() + QLatin1String("PrtCnv") + exerciseName + QLatin1String(".dat");
QString portFilePath = QCoreApplication::applicationDirPath() + QDir::separator() + QStringLiteral("PrtCnv") + exerciseName + QStringLiteral(".dat");
QFileInfo checkPortFile(portFilePath);
if(checkPortFile.exists() && checkPortFile.isFile())
{
QSettings portSetting(portFilePath, QSettings::IniFormat);
m_InjectionThread->setPort(portSetting.value(QLatin1String("Injection/Port")).toInt());
m_InjectionThread->setPort(portSetting.value(QStringLiteral("Injection/Port")).toInt());
}
m_EditTelegramController->setInjectionThread(m_InjectionThread);
@@ -182,6 +182,9 @@ protected slots:
private slots:
void onSettingsChanged(uint32_t changedFlags);
private:
LOGGER_T m_logger;
};
}
@@ -28,6 +28,7 @@ LogViewInjectionThread::LogViewInjectionThread()
, m_SendingPossible(false)
, m_Socket(nullptr)
, m_Timer(nullptr)
, m_logger(getLogger("LogViewInjectionThread"))
{
QSettings settings;
@@ -36,7 +37,7 @@ LogViewInjectionThread::LogViewInjectionThread()
if (m_Hostname.isEmpty())
{
m_Hostname = QLatin1String("localhost");
m_Hostname = QStringLiteral("localhost");
settings.setValue(LogViewOptionDialog::INJECTION_HOSTNAME, m_Hostname);
}
m_Port = settings.value(LogViewOptionDialog::INJECTION_PORT).toInt();
@@ -50,7 +51,7 @@ LogViewInjectionThread::LogViewInjectionThread()
void LogViewInjectionThread::run()
{
emit updateStatus(QLatin1String(":/image/RedLamp.png"),
emit updateStatus(QStringLiteral(":/image/RedLamp.png"),
tr("LogView ist nicht mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
QTimer::singleShot(100, this, &LogViewInjectionThread::tryToConnect);
@@ -106,7 +107,7 @@ void LogViewInjectionThread::doConnect()
INFO_LOG(m_logger) << "LogView has successful connected to injection-server of TETRA-If";
m_SendingPossible = true;
m_Timer->stop();
emit updateStatus(QLatin1String(":/image/GreenLamp.png"),
emit updateStatus(QStringLiteral(":/image/GreenLamp.png"),
tr("LogView ist mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
}
@@ -116,7 +117,7 @@ void LogViewInjectionThread::doDisconnect()
{
INFO_LOG(m_logger) << "LogView was disconnected from injection-server of TETRA-If";
m_SendingPossible = false;
emit updateStatus(QLatin1String(":/image/RedLamp.png"),
emit updateStatus(QStringLiteral(":/image/RedLamp.png"),
tr("LogView ist nicht mehr mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
tryToConnect();
}
@@ -70,6 +70,8 @@ namespace N_LogView
void updateStatus(const QString& a_picName, const QString& a_toolTipText);
protected:
LOGGER_T m_logger;
};
}
@@ -1,5 +1,6 @@
#include <nglapplication/nglapplication.h>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtCore/QSettings>
#include <QNetworkProxy>
#ifndef WIN32
@@ -39,8 +40,8 @@ int main(int argc, char *argv[])
QNetworkProxy::setApplicationProxy(QNetworkProxy());
app.createLogger("LogView", logConfigFileName.c_str());
QCoreApplication::setOrganizationName(QLatin1String("RME"));
QCoreApplication::setApplicationName(QLatin1String("LogView"));
QCoreApplication::setOrganizationName(QStringLiteral("RME"));
QCoreApplication::setApplicationName(QStringLiteral("LogView"));
QSettings settings;
settings.beginGroup(N_LogView::LogViewGui::WINDOW_GROUP);
@@ -48,7 +49,12 @@ int main(int argc, char *argv[])
settings.endGroup();
QScreen *screen = QGuiApplication::screens().value(screenNbr, QGuiApplication::primaryScreen());
N_LogView::LogViewGui* logViewGui = new N_LogView::LogViewGui(screen);
N_LogView::LogViewGui* logViewGui = new N_LogView::LogViewGui(nullptr);
// A QScreen is not a QWidget in Qt6, so the target screen can no longer be passed as the
// parent widget. Create the native window first, then assign it to the requested screen.
logViewGui->winId();
if (screen && logViewGui->windowHandle())
logViewGui->windowHandle()->setScreen(screen);
logViewGui->show();
int ret = app.exec();
@@ -55,7 +55,7 @@ QVariant ParticipantModel::data(const QModelIndex &index, int role) const
break;
}
}
if (role == Qt::BackgroundColorRole)
if (role == Qt::BackgroundRole)
{
if (p.first == 0)
return QVariant();
@@ -3,7 +3,7 @@
#pragma once
#include <QtGui/QAbstractTableModel>
#include <QtCore/QAbstractTableModel>
#include <QtCore/QSharedPointer>
#include <QtCore/QSortFilterProxyModel>
#include <set>
@@ -59,7 +59,7 @@ LogViewOptionDialog::LogViewOptionDialog(QWidget* a_parent)
QLabel* p0Label = new QLabel(tr("&Zentrale - Protokollkonverter"), this);
groupLayout->addWidget(p0Label, 0, 0, 1, 2);
QString defString = QCoreApplication::applicationDirPath() + QLatin1String("/training_area_telegrams.h");
QString defString = QCoreApplication::applicationDirPath() + QStringLiteral("/training_area_telegrams.h");
m_P0Edit = new QLineEdit(m_Settings.value(P0_FILENAME, defString).toString(), this);
m_P0Edit->setMinimumWidth(400);
groupLayout->addWidget(m_P0Edit);
@@ -70,7 +70,7 @@ LogViewOptionDialog::LogViewOptionDialog(QWidget* a_parent)
QLabel* p5Label = new QLabel(tr("Protokollkonverter - &TETRA"), this);
groupLayout->addWidget(p5Label, 2, 0, 1, 2);
defString = QCoreApplication::applicationDirPath() + QLatin1String("/zsksxd_tetraForLogView.x");
defString = QCoreApplication::applicationDirPath() + QStringLiteral("/zsksxd_tetraForLogView.x");
m_P5Edit = new QLineEdit(m_Settings.value(P5_FILENAME, defString).toString(), this);
groupLayout->addWidget(m_P5Edit);
QPushButton* p5Browse = new QPushButton(tr("Browse"), this);
@@ -88,7 +88,7 @@ void LogViewTableWidget::changeSize(const int a_newSize)
this, &LogViewTableWidget::checkAndOvertakeContent);
for (int i = 0; i < a_newSize; i++)
changeRow(i, QLatin1String("0"));
changeRow(i, QStringLiteral("0"));
connect(this, &LogViewTableWidget::itemChanged,
this, &LogViewTableWidget::checkAndOvertakeContent);
@@ -73,6 +73,7 @@ LogViewTelegram::LogViewTelegram(const LogViewTelegram &o)
, m_data(o.m_data)
, m_json(o.m_json)
, m_TetraTelegram(nullptr)
, m_logger(getLogger("LogViewTelegram"))
{
if (!m_data.isEmpty())
m_TetraTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(m_data);
@@ -100,6 +101,7 @@ LogViewTelegram::LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnv
, m_LogTime(0)
, m_GpsTime(0)
, m_TetraTelegram(nullptr)
, m_logger(getLogger("LogViewTelegram"))
{
const uint32_t &waitTime = qgetenv("LogViewWaitTime").toUInt();
if (waitTime > 0)
@@ -143,6 +145,7 @@ LogViewTelegram::LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnv
, m_GpsTime(0)
, m_data(a_telegramData)
, m_TetraTelegram(nullptr)
, m_logger(getLogger("LogViewTelegram"))
{
const uint32_t &waitTime = qgetenv("LogViewWaitTime").toUInt();
if (waitTime > 0)
@@ -155,10 +158,10 @@ LogViewTelegram::LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnv
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolWls:
{
m_json = QJsonDocument::fromJson(a_telegramData).object();
m_TelId = m_json.value(QLatin1String("typeId")).toInt();
m_TelId = m_json.value(QStringLiteral("typeId")).toInt();
m_Name = m_json.value(QLatin1String("type")).toString();
m_Name = m_json.value(QStringLiteral("type")).toString();
switch (getTelId())
{
case TrainingAreaBase::TetraIcd::BESTAETIGUNG:
@@ -167,9 +170,9 @@ LogViewTelegram::LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnv
m_ParticipantId = m_json.value(QLatin1String("data"))
.toObject().value(QLatin1String("header"))
.toObject().value(QLatin1String("equipmentNumber")).toInt();
m_ParticipantId = m_json.value(QStringLiteral("data"))
.toObject().value(QStringLiteral("header"))
.toObject().value(QStringLiteral("equipmentNumber")).toInt();
break;
}
break;
@@ -356,7 +359,7 @@ QString LogViewTelegram::getLogTimeText() const
if (m_logTimeText.isEmpty())
{
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(getLogTimeMsec()));
m_logTimeText = dt.toString(QLatin1String("ddd, MMM dd, yyyy hh:mm:ss.zzz"));
m_logTimeText = dt.toString(QStringLiteral("ddd, MMM dd, yyyy hh:mm:ss.zzz"));
}
return m_logTimeText;
}
@@ -373,9 +376,9 @@ QString LogViewTelegram::getDestinationText() const
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral: {
switch (dest) {
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive:
return QLatin1String("C > P");
return QStringLiteral("C > P");
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend:
return QLatin1String("P > C");
return QStringLiteral("P > C");
default:
break;
}
@@ -384,9 +387,9 @@ QString LogViewTelegram::getDestinationText() const
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolWls: {
switch (dest) {
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive:
return QLatin1String("W > C");
return QStringLiteral("W > C");
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend:
return QLatin1String("C > W");
return QStringLiteral("C > W");
default:
break;
}
@@ -395,9 +398,9 @@ QString LogViewTelegram::getDestinationText() const
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolTetra: {
switch (dest) {
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestReceive:
return QLatin1String("P > T");
return QStringLiteral("P > T");
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend:
return QLatin1String("T > P");
return QStringLiteral("T > P");
default:
break;
}
@@ -418,7 +421,7 @@ QString LogViewTelegram::getDestinationText() const
QString LogViewTelegram::getGpsTimeText() const
{
if (m_GpsTime != 0)
return QDateTime::fromMSecsSinceEpoch(m_GpsTime * 1000LL).toString(QLatin1String("hh:mm:ss"));
return QDateTime::fromMSecsSinceEpoch(m_GpsTime * 1000LL).toString(QStringLiteral("hh:mm:ss"));
return QString();
}
@@ -462,11 +465,11 @@ QString LogViewTelegram::getToolTipText(const E_Column a_col)
}
if(a_col == e_ColGpsTime && m_ToolTipText[e_ColGpsTime].isNull()) {
if(m_GpsTime == 0) {
m_ToolTipText[e_ColGpsTime] = QLatin1String("");
m_ToolTipText[e_ColGpsTime] = QStringLiteral("");
} else {
const QDateTime dtGpsTime(QDateTime::fromMSecsSinceEpoch(m_GpsTime * 1000LL));
m_ToolTipText[e_ColGpsTime] = QStringLiteral("%1<br><nobr>Unixzeit: %2 <b>0x%3</b></nobr>")
.arg(dtGpsTime.toString(QLatin1String("ddd, MMM dd, yyyy hh:mm:ss")))
.arg(dtGpsTime.toString(QStringLiteral("ddd, MMM dd, yyyy hh:mm:ss")))
.arg(m_GpsTime)
.arg(m_GpsTime, 8, 16, QLatin1Char('0'));
}
@@ -487,12 +490,12 @@ void LogViewTelegram::createToolTipTextForColName()
{
const QString jsonStr = QString::fromUtf8(QJsonDocument(m_json).toJson(QJsonDocument::JsonFormat::Indented));
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Telegram Id"), getTelId())
+ formatToolTipLine(QObject::tr("Counter"), getUInt32(POS_CENTRAL_COUNTER))
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ formatToolTipLine(QObject::tr("Json Data"), jsonStr, jsonStr.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
}
@@ -502,26 +505,26 @@ void LogViewTelegram::createToolTipTextForColName()
{
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterInd:
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Host ISSI"), m_TetraTelegram->getSrcISSI())
+ formatToolTipLine(QObject::tr("Counter"), m_TetraTelegram->zaehler())
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterRsp:
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Registration Status"), m_TetraTelegram->getRegistrationStatusAsText(), m_TetraTelegram->getRegistrationStatus())
+ formatToolTipLine(QObject::tr("Counter"), m_TetraTelegram->zaehler())
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_DataIndReq: {
int frameSize = 1;
if(m_TetraTelegram->getWithCrc())
frameSize += 2;
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Source ISSI"), m_TetraTelegram->getSrcISSI())
+ formatToolTipLine(QObject::tr("Destination ISSI"), m_TetraTelegram->getDestISSI())
+ formatToolTipLine(QObject::tr("Protocol Identifier"), m_TetraTelegram->getProtocolIdentifierAsText(), m_TetraTelegram->getProtocolIdentifier())
@@ -534,12 +537,12 @@ void LogViewTelegram::createToolTipTextForColName()
+ formatToolTipLine(QObject::tr("Real Payload in Bytes"), m_TetraTelegram->getLengthInBytes() - frameSize)
+ formatToolTipLine(QObject::tr("Counter"), m_TetraTelegram->zaehler())
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
}
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_ReportIndReq:
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Source ISSI"), m_TetraTelegram->getSrcISSI())
+ formatToolTipLine(QObject::tr("Destination ISSI"), m_TetraTelegram->getDestISSI())
+ formatToolTipLine(QObject::tr("Protocol Identifier"), m_TetraTelegram->getProtocolIdentifierAsText(), m_TetraTelegram->getProtocolIdentifier())
@@ -548,15 +551,15 @@ void LogViewTelegram::createToolTipTextForColName()
+ formatToolTipLine(QObject::tr("Delivery"), m_TetraTelegram->getDeliveryAsText(), m_TetraTelegram->getDelivery())
+ formatToolTipLine(QObject::tr("Counter"), m_TetraTelegram->zaehler())
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_AirInterfaceLoadReq:
default:
m_ToolTipText[e_ColName] = QLatin1String("<table>")
m_ToolTipText[e_ColName] = QStringLiteral("<table>")
+ formatToolTipLine(QObject::tr("Counter"), m_TetraTelegram->zaehler())
+ formatToolTipLine(QObject::tr("Size"), m_data.size())
+ QLatin1String("</table>");
+ QStringLiteral("</table>");
break;
}
break;
@@ -645,24 +648,24 @@ LogViewField* LogViewTelegram::getFieldTree()
{
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterInd:
m_ActOffset = START_OFFSET_TETRA_REGISTER;
structName = QLatin1String("TETRA_register_indication_rt");
structName = QStringLiteral("TETRA_register_indication_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_RegisterRsp:
m_ActOffset = START_OFFSET_TETRA_REGISTER;
structName = QLatin1String("TETRA_register_response_rt");
structName = QStringLiteral("TETRA_register_response_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_DataIndReq:
if (m_TetraTelegram->isLoginTelegram())
{
m_ActOffset = START_OFFSET_TETRA_LOGIN;
structName = QLatin1String("TETRA_login_telegram_rt");
structName = QStringLiteral("TETRA_login_telegram_rt");
}
else if (m_TetraTelegram->isNormalTelegram())
{
structName = getStructName();
if (structName == QLatin1String("gef_automatic_conversion_rt"))
if (structName == QStringLiteral("gef_automatic_conversion_rt"))
{
auto centralTelegram = N_CoPrtCnv::CoPrtCnvTelegramConverter::convertToCentral(m_TetraTelegram);
@@ -692,15 +695,15 @@ LogViewField* LogViewTelegram::getFieldTree()
{
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_FirstFragment:
m_ActOffset = START_OFFSET_TETRA_FRAGMENT;
structName = QLatin1String("TETRA_first_fragment_rt");
structName = QStringLiteral("TETRA_first_fragment_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_MiddleFragment:
m_ActOffset = START_OFFSET_TETRA_FRAGMENT;
structName = QLatin1String("TETRA_middle_fragment_rt");
structName = QStringLiteral("TETRA_middle_fragment_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_LastFragment:
m_ActOffset = START_OFFSET_TETRA_FRAGMENT;
structName = QLatin1String("TETRA_last_fragment_rt");
structName = QStringLiteral("TETRA_last_fragment_rt");
break;
default:
break;
@@ -710,22 +713,22 @@ LogViewField* LogViewTelegram::getFieldTree()
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_GroupMonitorReq:
m_ActOffset = START_OFFSET_TETRA_REGISTER;
structName = QLatin1String("TETRA_group_monitoring_ind_rt");
structName = QStringLiteral("TETRA_group_monitoring_ind_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_StatusIndReq:
m_ActOffset = START_OFFSET_TETRA_REGISTER;
structName = QLatin1String("TETRA_status_ind_req_rt");
structName = QStringLiteral("TETRA_status_ind_req_rt");
break;
case N_CoPrtCnv::CoPrtCnvRadioTelegram::e_AirInterfaceLoadReq:
m_ActOffset = START_OFFSET_TETRA_AIRLOAD;
structName = QLatin1String("TETRA_air_interface_load_req_rt");
structName = QStringLiteral("TETRA_air_interface_load_req_rt");
break;
default:
m_ActOffset = 0;
structName = QLatin1String("TETRA_unknown_PDU_rt");
structName = QStringLiteral("TETRA_unknown_PDU_rt");
break;
}
return getFieldTree(structName, structName, 1);
@@ -1095,7 +1098,7 @@ LogViewField* LogViewTelegram::getFieldTree(const QString& a_type, const QString
return getFieldTree(xdrElement->getName(), a_name, a_arraySize);
}
}
Q_FALLTHROUGH();
[[fallthrough]];
case LogViewXdrElement::e_KindStandardType:
{
@@ -1471,10 +1474,10 @@ void LogViewTelegram::setJsonValue(const QStringList &path, const QJsonValue &va
{
m_data.clear();
updateJsonValue(path, val, m_json);
if (path.size() && path.last() == QLatin1String("equipmentNumber"))
m_ParticipantId = m_json.value(QLatin1String("data"))
.toObject().value(QLatin1String("header"))
.toObject().value(QLatin1String("equipmentNumber")).toInt();
if (path.size() && path.last() == QStringLiteral("equipmentNumber"))
m_ParticipantId = m_json.value(QStringLiteral("data"))
.toObject().value(QStringLiteral("header"))
.toObject().value(QStringLiteral("equipmentNumber")).toInt();
}
@@ -1485,7 +1488,7 @@ void LogViewTelegram::updateJsonValue(const QStringList &path, const QJsonValue
if (path.size() > 1)
{
QString key = path.first();
static const QLatin1String arrayMarker(QLatin1String("array: "));
static const QString arrayMarker = QStringLiteral("array: ");
const bool isArray = key.startsWith(arrayMarker);
if (isArray)
{
@@ -1518,11 +1521,11 @@ void LogViewTelegram::updateJsonValue(const QStringList &path, const QJsonValue
return;
const QString &key = path.first();
static const QLatin1String indexMarker(QLatin1String("index: "));
static const QString indexMarker = QStringLiteral("index: ");
if (!key.startsWith(indexMarker))
return;
const int arrayIdx = key.midRef(indexMarker.size()).toInt();
const int arrayIdx = QStringView(key).mid(indexMarker.size()).toInt();
while (arr.size() <= arrayIdx)
arr.append(QJsonValue());
@@ -1543,13 +1546,13 @@ void LogViewTelegram::updateJsonValue(const QStringList &path, const QJsonValue
QIcon LogViewTelegram::getIcon() const
{
static const QIcon c2p(QLatin1String(":/image/C2P.png"));
static const QIcon p2c(QLatin1String(":/image/P2C.png"));
static const QIcon w2p(QLatin1String(":/image/W2P.png"));
static const QIcon p2w(QLatin1String(":/image/P2W.png"));
static const QIcon t2p(QLatin1String(":/image/T2P.png"));
static const QIcon p2t(QLatin1String(":/image/P2T.png"));
static const QIcon unk(QLatin1String(":/image/Unknown.png"));
static const QIcon c2p(QStringLiteral(":/image/C2P.png"));
static const QIcon p2c(QStringLiteral(":/image/P2C.png"));
static const QIcon w2p(QStringLiteral(":/image/W2P.png"));
static const QIcon p2w(QStringLiteral(":/image/P2W.png"));
static const QIcon t2p(QStringLiteral(":/image/T2P.png"));
static const QIcon p2t(QStringLiteral(":/image/P2T.png"));
static const QIcon unk(QStringLiteral(":/image/Unknown.png"));
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol protocol, dest;
protocol =(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol)(m_Destination & N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolMask);
dest = (N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol)(m_Destination & N_CoPrtCnv::CoPrtCnvLogHeader::e_DestDirectionMask);
@@ -1627,10 +1630,10 @@ void LogViewTelegram::showMessageBox(const QString& a_errorText, const QString&
quint64 logTimeMicroSec = m_LogTime & 0x00FFFFFFFFULL;
const QDateTime dt(QDateTime::fromMSecsSinceEpoch(logTimeSec * 1000 + logTimeMicroSec/1000));
const QString destStr((m_Destination&N_CoPrtCnv::CoPrtCnvLogHeader::e_DestDirectionMask)==N_CoPrtCnv::CoPrtCnvLogHeader::e_DestSend ?
QLatin1String("gesendete") : QLatin1String("gelesene"));
QStringLiteral("gesendete") : QStringLiteral("gelesene"));
QMessageBox::warning(QApplication::topLevelWidgets()[0], a_title,
QString::fromUtf8("Das %5 Telegramm mit Protokoll %6 von %1 (Unix-Zeit: %2) und Länge %3 ist fehlerhaft:<br><br><b>%4</b>")
.arg(dt.toString(Qt::SystemLocaleLongDate)).arg(logTimeSec).arg(m_data.size()).arg(a_errorText, destStr).arg(m_Protocol));
.arg(QLocale().toString(dt, QLocale::LongFormat)).arg(logTimeSec).arg(m_data.size()).arg(a_errorText, destStr).arg(m_Protocol));
}
@@ -1667,12 +1670,12 @@ uint16_t LogViewTelegram::getDynArraySize(uint16_t& a_offset) const
QString LogViewTelegram::formatToolTipLine(const QString& a_name, const QString& a_text, const uint32_t a_value)
{
static const QString s1(QLatin1String("<tr><td><nobr>%1: </nobr></td><td align=right><b><nobr>%2</nobr></b></td><td align=right><nobr>0x%3</nobr></td><td align=right><nobr>0b%4</nobr></td></tr>"));
static const QString s2(QLatin1String("%1"));
static const QString s1(QStringLiteral("<tr><td><nobr>%1: </nobr></td><td align=right><b><nobr>%2</nobr></b></td><td align=right><nobr>0x%3</nobr></td><td align=right><nobr>0b%4</nobr></td></tr>"));
static const QString s2(QStringLiteral("%1"));
QString num16 = s2.arg(a_value, 2, 16, QLatin1Char('0'));
QString num2 = s2.arg(a_value, 8, 2, QLatin1Char('0'));
QString ret = s1.arg(a_name, a_text, num16, num2);
ret = ret.replace(QLatin1Char('\n'), QLatin1String("<br/>"));
ret = ret.replace(QLatin1Char('\n'), QStringLiteral("<br/>"));
return ret;
}
@@ -15,6 +15,7 @@
#include "LogViewXdrStandardType.hpp"
#include "LogViewField.hpp"
#include "logger.h"
#include <CoPrtCnv/CoPrtCnvLogHeader.hpp>
#include <QtGui/QIcon>
#include <QJsonObject>
@@ -364,5 +365,6 @@ namespace N_LogView
private:
friend class LogViewTabWidget;
LOGGER_T m_logger;
};
}
@@ -50,6 +50,7 @@ namespace N_LogView
LogViewTelegramDialog::LogViewTelegramDialog(QWidget *a_parent, const bool a_readonly)
: QDialog(a_parent)
, m_ReadOnly(a_readonly)
, m_logger(getLogger("LogViewTelegramDialog"))
{
setAttribute(Qt::WA_DeleteOnClose);
}
@@ -139,7 +140,7 @@ void LogViewTelegramDialog::showDataDump(const QSharedPointer<LogViewTelegram> &
layout->addWidget(new QLabel(tr("HexData from \'%1\' - telegram:").arg(a_telegram->getName())));
QString theDump = QLatin1String("<code>");
QString theDump = QStringLiteral("<code>");
const QByteArray &data = a_telegram->getData();
for (int i = 0; i < data.size(); i++)
{
@@ -148,13 +149,13 @@ void LogViewTelegramDialog::showDataDump(const QSharedPointer<LogViewTelegram> &
theDump += QStringLiteral(" %1").arg(static_cast<unsigned char>(data[i]), 2, 16, QLatin1Char('0'));
if (7 == (i % 8))
theDump += QLatin1String("<br>");
theDump += QStringLiteral("<br>");
}
theDump += QLatin1String("</code>");
theDump += QStringLiteral("</code>");
QTextEdit *telegramDump = new QTextEdit(theDump);
layout->addWidget(telegramDump);
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
QPushButton *btnClose = new QPushButton(QIcon(QStringLiteral(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addStretch();
btnLayout->addWidget(btnClose);
@@ -282,7 +283,7 @@ void LogViewTelegramDialog::showButtons(QLayout *a_layout)
{
if (N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral == m_Telegram->getProtocol())
{
QPushButton *btnSend = new QPushButton(QIcon(QLatin1String(":icons/16x16/mail-send.png")), tr("&Send"));
QPushButton *btnSend = new QPushButton(QIcon(QStringLiteral(":icons/16x16/mail-send.png")), tr("&Send"));
btnSend->setEnabled(true);
connect(btnSend, &QPushButton::clicked, this, &LogViewTelegramDialog::sendCurrentTelegram);
a_layout->addWidget(btnSend);
@@ -290,18 +291,18 @@ void LogViewTelegramDialog::showButtons(QLayout *a_layout)
if (m_ReadOnly)
{
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
QPushButton *btnClose = new QPushButton(QIcon(QStringLiteral(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
connect(btnClose, &QPushButton::clicked, this, &LogViewTelegramDialog::reject);
a_layout->addWidget(btnClose);
}
else
{
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Abbrechen"));
QPushButton *btnClose = new QPushButton(QIcon(QStringLiteral(":icons/16x16/edit-delete.png")), tr("&Abbrechen"));
connect(btnClose, &QPushButton::clicked, this, &LogViewTelegramDialog::reject);
a_layout->addWidget(btnClose);
QPushButton *btnOk = new QPushButton(QIcon(QLatin1String(":icons/16x16/dialog-ok-apply.png")), tr("&OK"));
QPushButton *btnOk = new QPushButton(QIcon(QStringLiteral(":icons/16x16/dialog-ok-apply.png")), tr("&OK"));
btnOk->setDefault(true);
connect(btnOk, &QPushButton::clicked, this, &LogViewTelegramDialog::saveTelegram);
@@ -392,7 +393,7 @@ void LogViewTelegramDialog::showEditField(LogViewField *a_logViewField, QGridLay
break;
}
Q_FALLTHROUGH();
[[fallthrough]];
case 0:
if (m_ReadOnly)
{
@@ -401,7 +402,7 @@ void LogViewTelegramDialog::showEditField(LogViewField *a_logViewField, QGridLay
break;
}
Q_FALLTHROUGH();
[[fallthrough]];
default:
{
@@ -69,6 +69,7 @@ private:
QLineEdit *m_NameEdit = nullptr;
QLineEdit *m_WaitTimeEdit = nullptr;
bool m_ReadOnly = false;
LOGGER_T m_logger;
};
}
@@ -43,20 +43,21 @@ QString TelegramEdit::s_TELEGRAMLIST_FILES()
TelegramEdit::TelegramEdit(QWidget *parent)
: QObject(parent)
, m_addTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-add.png")), tr("Add Telegram"), this))
, m_editTeleAction(new QAction(QIcon(QLatin1String(":/image/Edit.png")), tr("Edit Telegram"), this))
, m_copyTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-copy.png")), tr("Copy Telegram"), this))
, m_pasteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-paste.png")), tr("Paste Telegram"), this))
, m_deleteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-remove.png")), tr("Delete Telegram"), this))
, m_moveTeleUpAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-up.png")), tr("Move up"), this))
, m_moveTeleDownAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-down.png")), tr("Move down"), this))
, m_teleListLoad(new QAction(QIcon(QLatin1String(":icons/16x16/document-open-data.png")), tr("Load Telegram list"), this))
, m_addTeleAction(new QAction(QIcon(QStringLiteral(":icons/16x16/list-add.png")), tr("Add Telegram"), this))
, m_editTeleAction(new QAction(QIcon(QStringLiteral(":/image/Edit.png")), tr("Edit Telegram"), this))
, m_copyTeleAction(new QAction(QIcon(QStringLiteral(":icons/16x16/edit-copy.png")), tr("Copy Telegram"), this))
, m_pasteTeleAction(new QAction(QIcon(QStringLiteral(":icons/16x16/edit-paste.png")), tr("Paste Telegram"), this))
, m_deleteTeleAction(new QAction(QIcon(QStringLiteral(":icons/16x16/list-remove.png")), tr("Delete Telegram"), this))
, m_moveTeleUpAction(new QAction(QIcon(QStringLiteral(":icons/16x16/go-up.png")), tr("Move up"), this))
, m_moveTeleDownAction(new QAction(QIcon(QStringLiteral(":icons/16x16/go-down.png")), tr("Move down"), this))
, m_teleListLoad(new QAction(QIcon(QStringLiteral(":icons/16x16/document-open-data.png")), tr("Load Telegram list"), this))
, m_teleListAppend(new QAction(QIcon(), tr("Telegrammliste anhaengen"), this))
, m_teleListSave(new QAction(QIcon(QLatin1String(":icons/16x16/document-save.png")), tr("Save Telegram list"), this))
, m_teleListSave(new QAction(QIcon(QStringLiteral(":icons/16x16/document-save.png")), tr("Save Telegram list"), this))
, m_tableView(new QTableView(parent))
, m_DoLoop(false)
, m_InjectionThread(nullptr)
, m_EditModel(new TelegramEditModel(this))
, m_logger(getLogger("TelegramEdit"))
{
m_addTeleAction->setShortcut(tr("Ctrl+A"));
m_editTeleAction->setShortcut(tr("Ctrl+E"));
@@ -151,12 +152,12 @@ void TelegramEdit::tableViewCustomContextMenu(const QPoint &pos)
if (isInjectionPossible())
{
QAction *action = menu.addAction(QIcon(QLatin1String(":/image/InjectCentral.png")), tr("Injektiere Zentral-Telegramm"));
QAction *action = menu.addAction(QIcon(QStringLiteral(":/image/InjectCentral.png")), tr("Injektiere Zentral-Telegramm"));
action->setEnabled(itemSelected && isCentral);
connect(action, &QAction::triggered, this, &TelegramEdit::injectCentralTelegram);
action = menu.addAction(QIcon(QLatin1String(":/image/InjectTetra.png")), tr("Injektiere Tetra-Telegramm"));
action = menu.addAction(QIcon(QStringLiteral(":/image/InjectTetra.png")), tr("Injektiere Tetra-Telegramm"));
action->setEnabled(itemSelected && isCentral);
connect(action, &QAction::triggered, this, &TelegramEdit::injectTetraTelegram);
@@ -165,21 +166,21 @@ void TelegramEdit::tableViewCustomContextMenu(const QPoint &pos)
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/mail-send.png")), tr("Sende Telegramm"));
action = menu.addAction(QIcon(QStringLiteral(":icons/16x16/mail-send.png")), tr("Sende Telegramm"));
action->setEnabled(itemSelected && isCentral);
connect(action, &QAction::triggered, this, &TelegramEdit::sendCurrentTelegram);
if (m_DoLoop)
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-stop.png")), tr("Stop Loopen"));
action = menu.addAction(QIcon(QStringLiteral(":icons/16x16/media-playback-stop.png")), tr("Stop Loopen"));
else
{
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-start.png")), tr("Loop Telegramme"));
action = menu.addAction(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")), tr("Loop Telegramme"));
action->setEnabled(itemSelected);
}
connect(action, &QAction::triggered, this, &TelegramEdit::loopTelegrams);
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-play-normal.png")), tr("Sende Sequenz"));
action = menu.addAction(QIcon(QStringLiteral(":icons/16x16/media-play-normal.png")), tr("Sende Sequenz"));
action->setEnabled(itemSelected);
connect(action, &QAction::triggered, this, &TelegramEdit::sequenceTelegrams);
@@ -440,7 +441,7 @@ void TelegramEdit::saveTelegramList()
if (!newFilename.isEmpty())
{
if (!newFilename.contains(QLatin1Char('.')))
newFilename += QLatin1String(".tgl");
newFilename += QStringLiteral(".tgl");
QDir dir;
@@ -4,7 +4,8 @@
#pragma once
#include "LogViewTelegram.hpp"
#include <QtGui/QModelIndex>
#include <QtCore/QModelIndex>
#include "logger.h"
class QAction;
class QTableView;
@@ -114,5 +115,8 @@ protected Q_SLOTS:
void editTelegramDialogFinished();
void onSelectionChanged();
protected:
LOGGER_T m_logger;
};
}
@@ -3,7 +3,7 @@
#pragma once
#include <QtGui/QAbstractTableModel>
#include <QtCore/QAbstractTableModel>
#include <QtCore/QSharedPointer>
#include <QtCore/QSet>
#include "LogViewTelegram.hpp"
@@ -6,6 +6,7 @@
#include <QtCore/QFile>
#include <QtCore/QVector>
#include <QtCore/QStringView>
namespace N_LogView
{
@@ -87,29 +88,29 @@ bool LogViewTetraTelegramsParser::parse(const QString &filename)
const QString content = QString::fromUtf8(f.readAll());
f.close();
const QVector<QStringRef> lines = content.splitRef(QLatin1Char('\n'));
QVector<QStringRef> linesTrimmed;
const QList<QStringView> lines = QStringView(content).split(QLatin1Char('\n'));
QList<QStringView> linesTrimmed;
linesTrimmed.reserve(lines.size());
for (const QStringRef &line : lines)
for (QStringView line : lines)
linesTrimmed += line.trimmed();
int i = 0;
while (i < linesTrimmed.size())
{
const QStringRef &line = linesTrimmed.at(i);
if (line.startsWith(QLatin1String("struct")))
const QStringView line = linesTrimmed.at(i);
if (line.startsWith(QStringLiteral("struct")))
{
i = parseStruct(linesTrimmed, i);
if (i < 0)
return false;
}
else if (line.startsWith(QLatin1String("enum")))
else if (line.startsWith(QStringLiteral("enum")))
{
i = parseEnum(linesTrimmed, i, QString());
if (i < 0)
return false;
}
else if (line.startsWith(QLatin1String("template <> struct Constraints")))
else if (line.startsWith(QStringLiteral("template <> struct Constraints")))
{
i = parseConstraint(linesTrimmed, i);
if (i < 0)
@@ -136,12 +137,12 @@ void LogViewTetraTelegramsParser::insertPod(const QString &type, int byteLen, bo
}
int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, int iStartPos)
int LogViewTetraTelegramsParser::parseStruct(const QList<QStringView> &lines, int iStartPos)
{
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
const QList<QStringView> tokens = tokenize(lines.at(iStartPos));
if (tokens.size() < 2)
return -1;
const QStringRef &structType = tokens.at(1);
const QStringView structType = tokens.at(1);
if (structType.endsWith(QLatin1Char(';')))
return iStartPos;
@@ -149,7 +150,7 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
si.type = structType.toString();
if (tokens.size() > 2)
{
if (tokens.at(2) != QLatin1String(":"))
if (tokens.at(2) != QStringLiteral(":"))
{
WARNING_LOG(m_logger) << "Could not parse struct: '" << lines.at(iStartPos).toString() << "', line: " << iStartPos + 1;
return -1;
@@ -162,10 +163,10 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
WARNING_LOG(m_logger) << "Could not parse struct: '" << lines.at(iStartPos).toString() << "', line: " << iStartPos + 1;
return -1;
}
QStringRef base = tokens.at(i);
if (base == QLatin1String("public") ||
base == QLatin1String("protected") ||
base == QLatin1String("private"))
QStringView base = tokens.at(i);
if (base == QStringLiteral("public") ||
base == QStringLiteral("protected") ||
base == QStringLiteral("private"))
continue;
if (base.endsWith(QLatin1Char(',')))
base.chop(1);
@@ -181,15 +182,15 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
int i = iStartPos + 1;
while (i < lines.size())
{
const QVector<QStringRef> tokens = tokenize(lines.at(i));
const QList<QStringView> tokens = tokenize(lines.at(i));
if (!validStructTokens(tokens))
{
++i;
continue;
}
if (tokens.at(0) == QLatin1String("};"))
if (tokens.at(0) == QStringLiteral("};"))
break;
if (tokens.at(0) == QLatin1String("enum"))
if (tokens.at(0) == QStringLiteral("enum"))
{
i = parseEnum(lines, i, si.type, &si);
if (i < 0)
@@ -201,35 +202,35 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
MemberInformation mi;
if (tokens.size() > 2)
{
const int parserCommentPos = tokens.at(2) == QLatin1String("=") ? 4 : 2;
const int parserCommentPos = tokens.at(2) == QStringLiteral("=") ? 4 : 2;
if (tokens.size() > parserCommentPos)
{
const QStringRef &comment = tokens.at(parserCommentPos);
const QStringView comment = tokens.at(parserCommentPos);
DEBUG_LOG(m_logger) << "comment: " << comment.toString();
if (comment.startsWith(QLatin1String("//@array: ")))
if (comment.startsWith(QStringLiteral("//@array: ")))
{
const QStringRef hint = comment.mid(QLatin1String("//@array: ").size());
QString structStr = QLatin1String("struct ") + si.type + QLatin1String("::") + tokens.at(0).toString() + QLatin1Char('\n') + hint.toString();
structStr.replace(QLatin1Char(';'), QLatin1String(";\n"));
const QStringView hint = comment.mid(QStringLiteral("//@array: ").size());
QString structStr = QStringLiteral("struct ") + si.type + QStringLiteral("::") + tokens.at(0).toString() + QLatin1Char('\n') + hint.toString();
structStr.replace(QLatin1Char(';'), QStringLiteral(";\n"));
DEBUG_LOG(m_logger) << "structStr: " << structStr;
parseStruct(structStr.splitRef(QLatin1Char('\n')), 0);
parseStruct(QStringView(structStr).split(QLatin1Char('\n')), 0);
mi.type = si.type + QLatin1String("::") + tokens.at(0).toString();
mi.type = si.type + QStringLiteral("::") + tokens.at(0).toString();
mi.isArray = true;
}
if (comment == QLatin1String("//@invisible"))
if (comment == QStringLiteral("//@invisible"))
mi.isVisible = false;
}
}
QStringRef name = tokens.at(1);
QStringView name = tokens.at(1);
if (name.endsWith(QLatin1Char(';')))
name.chop(1);
if (mi.type.isEmpty())
mi.type += tokens.at(0).toString();
categorizeMember(mi);
mi.name = name.toString();
if (mi.isEnum && !mi.type.contains(QLatin1String("::")))
if (mi.isEnum && !mi.type.contains(QStringLiteral("::")))
{
for (const auto &ei : std::as_const(m_enums))
@@ -237,7 +238,7 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
if (ei.type == mi.type)
{
if (!ei.ns.isEmpty())
mi.type = ei.ns + QLatin1String("::") + mi.type;
mi.type = ei.ns + QStringLiteral("::") + mi.type;
break;
}
}
@@ -265,13 +266,13 @@ int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, i
return i;
}
int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int iStartPos, const QString &ns, StructInformation *si)
int LogViewTetraTelegramsParser::parseEnum(const QList<QStringView> &lines, int iStartPos, const QString &ns, StructInformation *si)
{
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
const QList<QStringView> tokens = tokenize(lines.at(iStartPos));
if (tokens.size() < 2)
return -1;
QStringRef enumName = tokens.at(1);
if (enumName == QLatin1String("class"))
QStringView enumName = tokens.at(1);
if (enumName == QStringLiteral("class"))
{
if (tokens.size() < 3)
return -1;
@@ -287,19 +288,19 @@ int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int
int i = iStartPos + 1;
while (i < lines.size())
{
const QVector<QStringRef> tokens = tokenize(lines.at(i).split(QStringLiteral("//")).first());
const QList<QStringView> tokens = tokenize(lines.at(i).split(QStringLiteral("//")).first());
if (tokens.isEmpty() ||
(tokens.at(0) == QLatin1String("{")))
(tokens.at(0) == QStringLiteral("{")))
{
++i;
continue;
}
if (tokens.at(0) == QLatin1String("};"))
if (tokens.at(0) == QStringLiteral("};"))
break;
if ((tokens.size() != 1 && tokens.size() != 3) ||
(tokens.size() == 3 && tokens.at(1) != QLatin1String("=")))
(tokens.size() == 3 && tokens.at(1) != QStringLiteral("=")))
{
if (tokens.size() == 4 && tokens.at(0) == QLatin1String("}") && tokens.at(3).endsWith(QLatin1Char(';')) && si)
if (tokens.size() == 4 && tokens.at(0) == QStringLiteral("}") && tokens.at(3).endsWith(QLatin1Char(';')) && si)
{
MemberInformation mi;
@@ -320,7 +321,7 @@ int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int
ev.key = tokens.at(0).toString();
if (tokens.size() == 3)
{
QStringRef value = tokens.at(2);
QStringView value = tokens.at(2);
if (value.endsWith(QLatin1Char(',')))
value.chop(1);
ev.value = value.toInt();
@@ -338,7 +339,7 @@ int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int
for (const EnumValue &ev : std::as_const(ei.values))
DEBUG_LOG(m_logger) << "Member[" << i << "]: " << ev.key << " = " << ev.value;
if (ei.type == QLatin1String("TelegramId"))
if (ei.type == QStringLiteral("TelegramId"))
m_telegramIdEnum = ei;
m_enums.push_back(std::move(ei));
@@ -346,49 +347,49 @@ int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int
return i;
}
int LogViewTetraTelegramsParser::parseConstraint(const QVector<QStringRef> &lines, int iStartPos)
int LogViewTetraTelegramsParser::parseConstraint(const QList<QStringView> &lines, int iStartPos)
{
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
const QList<QStringView> tokens = tokenize(lines.at(iStartPos));
if (tokens.size() != 4)
{
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(iStartPos).toString() << "'";
return -1;
}
const QStringRef &cs = tokens.at(3);
if (!cs.startsWith(QLatin1String("Constraints<")) || !cs.endsWith(QLatin1Char('>')))
const QStringView cs = tokens.at(3);
if (!cs.startsWith(QStringLiteral("Constraints<")) || !cs.endsWith(QLatin1Char('>')))
{
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(iStartPos).toString() << "'";
return -1;
}
QStringRef structName = cs.mid(QLatin1String("Constraints<").size());
QStringView structName = cs.mid(QStringLiteral("Constraints<").size());
structName.chop(1);
DEBUG_LOG(m_logger) << "Constraint: " << structName.toString();
int i = iStartPos + 1;
while (i < lines.size())
{
const QVector<QStringRef> tokens = tokenize(lines.at(i));
const QList<QStringView> tokens = tokenize(lines.at(i));
if (tokens.isEmpty() ||
(tokens.at(0) == QLatin1String("{")))
(tokens.at(0) == QStringLiteral("{")))
{
++i;
continue;
}
if (tokens.at(0) == QLatin1String("};"))
if (tokens.at(0) == QStringLiteral("};"))
break;
if (tokens.size() != 8 || tokens.at(2) != QLatin1String("TelegramId"))
if (tokens.size() != 8 || tokens.at(2) != QStringLiteral("TelegramId"))
{
++i;
continue;
}
const QVector<QStringRef> parts = tokens.at(6).split(QLatin1String("::"));
const QList<QStringView> parts = tokens.at(6).split(QStringLiteral("::"));
if (parts.size() != 2)
{
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(i).toString() << "'";
return -1;
}
QStringRef enumKey = parts.at(1);
QStringView enumKey = parts.at(1);
if (enumKey.endsWith(QLatin1Char(';')))
enumKey.chop(1);
bool bFound = false;
@@ -427,14 +428,14 @@ void LogViewTetraTelegramsParser::categorizeMember(MemberInformation &mi) const
{
mi.isPod = isPod(mi.type);
mi.isEnum = mi.isPod ? false : isEnum(mi.type);
if (mi.type.startsWith(QLatin1String("std::vector<")))
if (mi.type.startsWith(QStringLiteral("std::vector<")))
mi.isArray = true;
mi.isStruct = mi.isArray ? false : isStruct(mi.type);
mi.isString = (mi.type == QLatin1String("std::string") || mi.type == QLatin1String("QString"));
mi.isBinary = (mi.type == QLatin1String("std::vector<unsigned char>") || mi.type == QLatin1String("QByteArray"));
mi.isString = (mi.type == QStringLiteral("std::string") || mi.type == QStringLiteral("QString"));
mi.isBinary = (mi.type == QStringLiteral("std::vector<unsigned char>") || mi.type == QStringLiteral("QByteArray"));
}
static inline void bracketCount(const QStringRef &str, int &cntLt, int &cntGt)
static inline void bracketCount(QStringView str, int &cntLt, int &cntGt)
{
cntLt = 0;
cntGt = 0;
@@ -447,20 +448,20 @@ static inline void bracketCount(const QStringRef &str, int &cntLt, int &cntGt)
}
}
QVector<QStringRef> LogViewTetraTelegramsParser::tokenize(const QStringRef &line) const
QList<QStringView> LogViewTetraTelegramsParser::tokenize(QStringView line) const
{
QVector<QStringRef> ret = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
QList<QStringView> ret = line.split(QLatin1Char(' '), Qt::SkipEmptyParts);
int i = 0;
while (i < ret.size())
{
const QStringRef &token = ret.at(i);
if (token.startsWith(QLatin1String("//")))
const QStringView token = ret.at(i);
if (token.startsWith(QStringLiteral("//")))
{
if (i == ret.size() - 1)
break;
const QStringRef &lastToken = ret.last();
const QStringRef newToken = QStringRef(token.string(), token.position(), lastToken.position() - token.position() + lastToken.size());
const QStringView lastToken = ret.last();
const QStringView newToken(token.data(), lastToken.data() - token.data() + lastToken.size());
DEBUG_LOG(m_logger) << "New Token: " << newToken.toString();
ret.resize(i + 1);
ret[i] = newToken;
@@ -476,8 +477,8 @@ QVector<QStringRef> LogViewTetraTelegramsParser::tokenize(const QStringRef &line
++i;
continue;
}
const QStringRef &nextToken = ret.at(i + 1);
const QStringRef newToken = QStringRef(token.string(), token.position(), nextToken.position() - token.position() + nextToken.size());
const QStringView nextToken = ret.at(i + 1);
const QStringView newToken(token.data(), nextToken.data() - token.data() + nextToken.size());
DEBUG_LOG(m_logger) << "New Token: " << newToken.toString();
ret.removeAt(i + 1);
ret[i] = newToken;
@@ -486,21 +487,21 @@ QVector<QStringRef> LogViewTetraTelegramsParser::tokenize(const QStringRef &line
return ret;
}
bool LogViewTetraTelegramsParser::validStructTokens(const QVector<QStringRef> &tokens)
bool LogViewTetraTelegramsParser::validStructTokens(const QList<QStringView> &tokens)
{
if (tokens.isEmpty() ||
(tokens.at(0) == QLatin1String("{")) ||
(tokens.at(0) == QLatin1String("{}")) ||
(tokens.at(0) == QLatin1String("}")) ||
(tokens.at(0) == QLatin1String(":")) ||
(tokens.at(0) == QLatin1String(",")) ||
(tokens.at(0) == QLatin1String("virtual")))
(tokens.at(0) == QStringLiteral("{")) ||
(tokens.at(0) == QStringLiteral("{}")) ||
(tokens.at(0) == QStringLiteral("}")) ||
(tokens.at(0) == QStringLiteral(":")) ||
(tokens.at(0) == QStringLiteral(",")) ||
(tokens.at(0) == QStringLiteral("virtual")))
return false;
if (tokens.at(0) == QLatin1String("};") || tokens.at(0) == QLatin1String("enum"))
if (tokens.at(0) == QStringLiteral("};") || tokens.at(0) == QStringLiteral("enum"))
return true;
const int len = tokens.last().startsWith(QLatin1String("//")) ? tokens.size() - 1 : tokens.size();
const int len = tokens.last().startsWith(QStringLiteral("//")) ? tokens.size() - 1 : tokens.size();
if (len == 2)
return true;
@@ -508,7 +509,7 @@ bool LogViewTetraTelegramsParser::validStructTokens(const QVector<QStringRef> &t
if (len < 4)
return false;
if (len >= 4 && tokens.at(2) == QLatin1String("="))
if (len >= 4 && tokens.at(2) == QStringLiteral("="))
return true;
return false;
@@ -6,6 +6,7 @@
#include <QtCore/QHash>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QStringView>
#include "logger.h"
namespace N_LogView
@@ -72,13 +73,14 @@ public:
static QString getInnerType(const QString &type);
private:
void insertPod(const QString &type, int byteLen, bool isSigned, bool isIntegral, bool isBoolean = false);
int parseStruct(const QVector<QStringRef> &lines, int iStartPos);
int parseEnum(const QVector<QStringRef> &lines, int iStartPos, const QString &ns, StructInformation *si = nullptr);
int parseConstraint(const QVector<QStringRef> &lines, int iStartPos);
int parseStruct(const QList<QStringView> &lines, int iStartPos);
int parseEnum(const QList<QStringView> &lines, int iStartPos, const QString &ns, StructInformation *si = nullptr);
int parseConstraint(const QList<QStringView> &lines, int iStartPos);
void categorizeMember(MemberInformation &mi) const;
QVector<QStringRef> tokenize(const QStringRef &line) const;
static bool validStructTokens(const QVector<QStringRef> &tokens);
QList<QStringView> tokenize(QStringView line) const;
static bool validStructTokens(const QList<QStringView> &tokens);
private:
LOGGER_T m_logger;
EnumInformation m_telegramIdEnum;
QVector<EnumInformation> m_enums;
QHash<QString, StructInformation> m_structs;
@@ -30,6 +30,7 @@ LogViewWidget::LogViewWidget(LogViewField* a_field, QWidget* a_widget, QWidget*
, m_Widget(a_widget)
, m_Field(a_field)
, m_Parent(a_parent)
, m_logger(getLogger("LogViewWidget"))
{
}
@@ -77,6 +77,8 @@ protected:
LogViewField *m_Field;
QWidget *m_Parent;
LOGGER_T m_logger;
};
}
@@ -41,19 +41,19 @@ QString LogViewXdrElement::getKindName() const
switch (getKind())
{
case e_KindDefine:
return QLatin1String("Define");
return QStringLiteral("Define");
case e_KindEnum:
return QLatin1String("Enum");
return QStringLiteral("Enum");
case e_KindEnumElement:
return QLatin1String("EnumElement");
return QStringLiteral("EnumElement");
case e_KindStandardType:
return QLatin1String("StandardType");
return QStringLiteral("StandardType");
case e_KindStruct:
return QLatin1String("Struct");
return QStringLiteral("Struct");
case e_KindStructElement:
return QLatin1String("StructElement");
return QStringLiteral("StructElement");
case e_KindTypedef:
return QLatin1String("Typedef");
return QStringLiteral("Typedef");
}
return QStringLiteral("Unknown (%1)").arg(getKind());
}
@@ -53,6 +53,7 @@ namespace N_LogView
protected:
QString m_Name;
E_ElementKind m_Kind;
LOGGER_T m_logger;
QString getKindName() const;
};
@@ -37,6 +37,7 @@ LogViewXdrParser::LogViewXdrParser()
, m_WordListIndex(0)
, m_ActElement(nullptr)
, m_State(e_ParseMain)
, m_logger(getLogger("LogViewXdrParser"))
{}
LogViewXdrParser::~LogViewXdrParser()
@@ -73,41 +74,41 @@ void LogViewXdrParser::parseX_File(const QString& a_fileName)
m_State = e_ParseMain;
addStandardType(QLatin1String("unsigned short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("unsigned int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("short"), 4, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("int"), 4, 4, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("u_int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("char"), 4, 2, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("unsigned char"), 4, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("unsigned long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("u_long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("u_short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("float"), 4, 4, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QLatin1String("double"), 8, 8, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QLatin1String("opaque"), 1, 1, LogViewXdrStandardType::e_Data);
addStandardType(QLatin1String("string"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QStringLiteral("unsigned short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("unsigned int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("short"), 4, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QStringLiteral("int"), 4, 4, LogViewXdrStandardType::e_Signed);
addStandardType(QStringLiteral("u_int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("char"), 4, 2, LogViewXdrStandardType::e_Character);
addStandardType(QStringLiteral("unsigned char"), 4, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("unsigned long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("u_long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("u_short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("float"), 4, 4, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QStringLiteral("double"), 8, 8, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QStringLiteral("opaque"), 1, 1, LogViewXdrStandardType::e_Data);
addStandardType(QStringLiteral("string"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("alpha"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("UInt8"), 1, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("UInt16"), 2, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("UInt24"), 3, 3, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("SInt8"), 1, 1, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("SInt16"), 2, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("SInt24"), 3, 3, LogViewXdrStandardType::e_Signed);
addStandardType(QStringLiteral("alpha"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QStringLiteral("UInt8"), 1, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("UInt16"), 2, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("UInt24"), 3, 3, LogViewXdrStandardType::e_Unsigned);
addStandardType(QStringLiteral("SInt8"), 1, 1, LogViewXdrStandardType::e_Signed);
addStandardType(QStringLiteral("SInt16"), 2, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QStringLiteral("SInt24"), 3, 3, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("UInt16LE"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt32LE"), 4, 4, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QStringLiteral("UInt16LE"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QStringLiteral("UInt32LE"), 4, 4, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt8Idx"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QLatin1String("UInt16Idx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QLatin1String("UInt16LEIdx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QStringLiteral("UInt8Idx"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QStringLiteral("UInt16Idx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QStringLiteral("UInt16LEIdx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt8IdxDiv8"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
addStandardType(QLatin1String("UInt16IdxDiv8"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
addStandardType(QStringLiteral("UInt8IdxDiv8"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
addStandardType(QStringLiteral("UInt16IdxDiv8"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
const auto DEFINE_NAME = QLatin1String("%#define");
const auto DEFINE_NAME = QStringLiteral("%#define");
m_Filename = a_fileName;
@@ -155,11 +156,11 @@ void LogViewXdrParser::parseX_File(const QString& a_fileName)
if (e_ParseMain == m_State)
{
if (cleanLine.startsWith(QLatin1String("union ")))
if (cleanLine.startsWith(QStringLiteral("union ")))
{
m_State = e_ParseUnion;
}
else if (cleanLine.startsWith(QLatin1String("struct ")))
else if (cleanLine.startsWith(QStringLiteral("struct ")))
{
m_State = e_ParseStruct;
}
@@ -182,19 +183,19 @@ void LogViewXdrParser::parseX_File(const QString& a_fileName)
{
parseDefine(m_Line.mid(DEFINE_NAME.size()));
}
else if (cleanLine.startsWith(QLatin1String("typedef ")))
else if (cleanLine.startsWith(QStringLiteral("typedef ")))
{
parseTypedef(cleanLine);
}
else if (cleanLine.startsWith(QLatin1String("enum ")))
else if (cleanLine.startsWith(QStringLiteral("enum ")))
{
parseEnum(cleanLine.mid(5));
}
else if (cleanLine.startsWith(QLatin1String("enum8 ")))
else if (cleanLine.startsWith(QStringLiteral("enum8 ")))
{
parseEnum(cleanLine.mid(6), 1);
}
else if (cleanLine.startsWith(QLatin1String("enum16 ")))
else if (cleanLine.startsWith(QStringLiteral("enum16 ")))
{
parseEnum(cleanLine.mid(7), 2);
}
@@ -213,7 +214,7 @@ void LogViewXdrParser::parseX_File(const QString& a_fileName)
}
else
{
QMessageBox::warning(nullptr, QLatin1String("Dateifehler"), QStringLiteral("Konnte die Datei <b>%1</b> nicht öffnen").arg(a_fileName));
QMessageBox::warning(nullptr, QStringLiteral("Dateifehler"), QStringLiteral("Konnte die Datei <b>%1</b> nicht öffnen").arg(a_fileName));
}
}
@@ -317,8 +318,8 @@ void LogViewXdrParser::parseDefine(const QString &a_line)
int sepPos = line.indexOf(QLatin1Char(' '));
if (sepPos >= 0)
{
const QString name = line.leftRef(sepPos).trimmed().toString();
QStringRef substitution = line.midRef(sepPos).trimmed();
const QString name = QStringView(line).left(sepPos).trimmed().toString();
QStringView substitution = QStringView(line).mid(sepPos).trimmed();
sepPos = substitution.indexOf(QLatin1Char(' '));
if (sepPos >= 0)
substitution = substitution.left(sepPos).trimmed();
@@ -342,17 +343,17 @@ void LogViewXdrParser::parseDefine(const QString &a_line)
void LogViewXdrParser::parseEnum(const QString &a_line, const uint16_t a_enumSize)
{
if (QLatin1String("};") != a_line)
if (QStringLiteral("};") != a_line)
{
switch(m_State)
{
default:
if (a_line.endsWith(QLatin1String(" {")))
if (a_line.endsWith(QStringLiteral(" {")))
{
m_State = e_ParseEnum;
const QString name = a_line.leftRef(a_line.length()-2).trimmed().toString();
const QString name = QStringView(a_line).left(a_line.length()-2).trimmed().toString();
m_ActElement = new LogViewXdrStruct(name, LogViewXdrElement::e_KindEnum, a_enumSize);
if (!addToElementMap(name, m_ActElement))
{
@@ -524,7 +525,7 @@ void LogViewXdrParser::parseUnion(const QString& a_line)
if (!isNextWord("}", false))
{
QString keyword = getNextWord();
if (keyword == QLatin1String("case"))
if (keyword == QStringLiteral("case"))
{
@@ -542,7 +543,7 @@ void LogViewXdrParser::parseUnion(const QString& a_line)
type = getNextWord("Typ");
if (type.isEmpty()) return;
}
while (type == QLatin1String("case"));
while (type == QStringLiteral("case"));
getElement(type);
@@ -565,13 +566,13 @@ void LogViewXdrParser::parseUnion(const QString& a_line)
}
}
}
else if (keyword == QLatin1String("default"))
else if (keyword == QStringLiteral("default"))
{
if (isNextWord(":"))
{
QString defaultDefinition = getNextWord();
if (defaultDefinition == QLatin1String("void"))
if (defaultDefinition == QStringLiteral("void"))
{
isNextWord(";");
@@ -617,8 +618,8 @@ bool LogViewXdrParser::parseEnumLine(const QString& a_line, QString& a_name, QSt
int sepPos = line.lastIndexOf(QLatin1Char('='));
if (-1 != sepPos)
{
a_name = line.leftRef(sepPos).trimmed().toString();
a_value = line.midRef(sepPos+1).trimmed().toString();
a_name = QStringView(line).left(sepPos).trimmed().toString();
a_value = QStringView(line).mid(sepPos+1).trimmed().toString();
return true;
}
else
@@ -864,13 +865,13 @@ bool LogViewXdrParser::isNextWord(const char *a_word, const bool a_doIncrement)
void LogViewXdrParser::fillWordList(const QString& a_line)
{
QString line = a_line;
line.replace(QLatin1Char('('), QLatin1String(" ( "));
line.replace(QLatin1Char(')'), QLatin1String(" ) "));
line.replace(QLatin1Char('{'), QLatin1String(" { "));
line.replace(QLatin1Char('}'), QLatin1String(" } "));
line.replace(QLatin1Char(':'), QLatin1String(" : "));
line.replace(QLatin1Char(';'), QLatin1String(" ; "));
m_WordList = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
line.replace(QLatin1Char('('), QStringLiteral(" ( "));
line.replace(QLatin1Char(')'), QStringLiteral(" ) "));
line.replace(QLatin1Char('{'), QStringLiteral(" { "));
line.replace(QLatin1Char('}'), QStringLiteral(" } "));
line.replace(QLatin1Char(':'), QStringLiteral(" : "));
line.replace(QLatin1Char(';'), QStringLiteral(" ; "));
m_WordList = line.split(QLatin1Char(' '), Qt::SkipEmptyParts);
m_WordListIndex = 0;
@@ -906,8 +907,8 @@ QString LogViewXdrParser::getNextType(bool& a_ok)
a_ok = true;
QString type = getNextWord("Typ");
if (type.isEmpty()) a_ok = false;
if (type == QLatin1String("unsigned") ||
type == QLatin1String("signed"))
if (type == QStringLiteral("unsigned") ||
type == QStringLiteral("signed"))
{
QString type2 = getNextWord("Typ");
if (type2.isEmpty()) a_ok = false;
@@ -951,7 +952,7 @@ bool LogViewXdrParser::parseBitfield(const QString& a_fieldText, int16_t& a_firs
a_lastBit = -1;
bool isLast = true;
int doublePointPos = a_fieldText.indexOf(QLatin1String(".."));
int doublePointPos = a_fieldText.indexOf(QStringLiteral(".."));
if (doublePointPos != -1)
{
QString bitText = a_fieldText.left(doublePointPos);
@@ -174,6 +174,7 @@ namespace N_LogView
bool addToElementMap(const QString& a_name, LogViewXdrElement* a_element);
private:
LOGGER_T m_logger;
};
}
@@ -89,8 +89,8 @@ bool LogViewXdrType::maskValue(uint32_t& a_value, const uint16_t a_size, QString
a_value = (a_value >> bitshift) & mask;
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_FirstBit, QLatin1String("<b>"));
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_LastBit+1, QLatin1String("</b>"));
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_FirstBit, QStringLiteral("<b>"));
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_LastBit+1, QStringLiteral("</b>"));
return m_IsLast;
}
return true;
@@ -0,0 +1,32 @@
# Unit tests for LogView.
# LogView itself is an executable, so it cannot be linked into a test binary.
# The non-GUI sources under test are compiled directly into the test executable
# instead. GoogleTest is resolved once in the top-level CMakeLists.txt.
set(logview_under_test
${CMAKE_CURRENT_SOURCE_DIR}/../logger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../LogViewField.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../LogViewXdrElement.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../LogViewXdrStandardType.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../LogViewTetraTelegramsParser.cpp
)
add_executable(LogViewTests
${CMAKE_CURRENT_SOURCE_DIR}/../../unittest_main.cpp
LogViewFieldTest.cpp
LogViewTetraTelegramsParserTest.cpp
${logview_under_test}
)
target_include_directories(LogViewTests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..
)
target_link_libraries(LogViewTests PRIVATE
NGLLogger
Qt6::Core
GTest::gtest
)
include(GoogleTest)
gtest_discover_tests(LogViewTests)
@@ -0,0 +1,195 @@
/**
* @file LogViewFieldTest.cpp
* @brief Unit tests for N_LogView::LogViewField.
*
* LogViewField is the tree node LogView builds from a telegram specification.
* These tests cover the name/label handling, the value list, the child tree and
* the timestamp-field detection. They deliberately avoid the accessors that
* dereference the XDR element, which needs a parsed specification file.
*/
#include <gtest/gtest.h>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include "LogViewField.hpp"
using N_LogView::LogViewField;
namespace
{
LogViewField makeField(const QString &name,
LogViewField::E_FieldKind kind = LogViewField::e_FieldKindEdit)
{
return LogViewField(name, kind, nullptr);
}
} // namespace
TEST(LogViewFieldTest, ConstructorStoresNameAndKind)
{
const LogViewField field = makeField(QStringLiteral("issi"), LogViewField::e_FieldKindBorder);
EXPECT_EQ(field.name(), QStringLiteral("issi"));
EXPECT_EQ(field.kind(), LogViewField::e_FieldKindBorder);
EXPECT_EQ(field.xdrElement(), nullptr);
}
TEST(LogViewFieldTest, SetNameReplacesTheName)
{
LogViewField field = makeField(QStringLiteral("old"));
field.setName(QStringLiteral("new"));
EXPECT_EQ(field.name(), QStringLiteral("new"));
}
TEST(LogViewFieldTest, MakeCleanCapitalisesWordsAndDropsUnderscores)
{
EXPECT_EQ(LogViewField::makeClean(QStringLiteral("utm_nordwert")),
QStringLiteral("Utm Nordwert"));
EXPECT_EQ(LogViewField::makeClean(QStringLiteral("issi")), QStringLiteral("Issi"));
}
TEST(LogViewFieldTest, MakeCleanStripsTheRecordTypeSuffix)
{
EXPECT_EQ(LogViewField::makeClean(QStringLiteral("gef_header_rt")),
QStringLiteral("Gef Header"));
}
TEST(LogViewFieldTest, MakeCleanHandlesTheEmptyString)
{
EXPECT_EQ(LogViewField::makeClean(QString()), QString());
}
TEST(LogViewFieldTest, CleanNameUsesMakeClean)
{
const LogViewField field = makeField(QStringLiteral("gps_zeit"));
EXPECT_EQ(field.cleanName(), LogViewField::makeClean(QStringLiteral("gps_zeit")));
}
TEST(LogViewFieldTest, ValueListStartsEmpty)
{
const LogViewField field = makeField(QStringLiteral("issi"));
EXPECT_EQ(field.valueListSize(), 0);
EXPECT_TRUE(field.value(0).isEmpty());
}
TEST(LogViewFieldTest, AddValueAppendsInOrder)
{
LogViewField field = makeField(QStringLiteral("issi"));
field.addValue(QStringLiteral("11"));
field.addValue(QStringLiteral("22"));
EXPECT_EQ(field.valueListSize(), 2);
EXPECT_EQ(field.value(0), QStringLiteral("11"));
EXPECT_EQ(field.value(1), QStringLiteral("22"));
}
TEST(LogViewFieldTest, ValueReturnsEmptyForAnOutOfRangeIndex)
{
LogViewField field = makeField(QStringLiteral("issi"));
field.addValue(QStringLiteral("11"));
EXPECT_TRUE(field.value(1).isEmpty());
EXPECT_TRUE(field.value(99).isEmpty());
}
TEST(LogViewFieldTest, AddValueBinaryHexExpandsToDecimalBytes)
{
LogViewField field = makeField(QStringLiteral("payload"));
field.addValueBinaryHex(QStringLiteral("00ff10"));
ASSERT_EQ(field.valueListSize(), 3);
EXPECT_EQ(field.value(0), QStringLiteral("0"));
EXPECT_EQ(field.value(1), QStringLiteral("255"));
EXPECT_EQ(field.value(2), QStringLiteral("16"));
}
TEST(LogViewFieldTest, DateTimeFieldIsDetectedCaseInsensitively)
{
EXPECT_TRUE(makeField(QStringLiteral("gps_zeit")).isDateTimeField());
EXPECT_TRUE(makeField(QStringLiteral("GPS_ZEIT")).isDateTimeField());
EXPECT_FALSE(makeField(QStringLiteral("issi")).isDateTimeField());
}
TEST(LogViewFieldTest, MSecsFieldIsDetectedCaseInsensitively)
{
EXPECT_TRUE(makeField(QStringLiteral("timestamp")).isMSecsField());
EXPECT_TRUE(makeField(QStringLiteral("EffectStart")).isMSecsField());
EXPECT_FALSE(makeField(QStringLiteral("gps_zeit")).isMSecsField());
}
TEST(LogViewFieldTest, RawValueSkipsTheTimestampConversion)
{
LogViewField field = makeField(QStringLiteral("timestamp"));
field.addValue(QStringLiteral("1500000000000"));
EXPECT_EQ(field.value(0, true), QStringLiteral("1500000000000"));
EXPECT_NE(field.value(0), QStringLiteral("1500000000000"));
}
TEST(LogViewFieldTest, ScalarPropertiesRoundTrip)
{
LogViewField field = makeField(QStringLiteral("issi"));
field.setType(QStringLiteral("uint32_t"));
field.setSize(4);
field.setIsRightAligned(true);
field.setToolTipText(QStringLiteral("individual subscriber identity"));
field.setHasContent(false);
EXPECT_EQ(field.type(), QStringLiteral("uint32_t"));
EXPECT_EQ(field.size(), 4);
EXPECT_TRUE(field.isRightAligned());
EXPECT_EQ(field.toolTipText(), QStringLiteral("individual subscriber identity"));
EXPECT_FALSE(field.hasContent());
}
TEST(LogViewFieldTest, MaxArraySizeCarriesTheDynamicFlag)
{
LogViewField field = makeField(QStringLiteral("players"));
field.setMaxArraySize(8, false);
EXPECT_EQ(field.maxArraySize(), 8);
EXPECT_FALSE(field.isDynamicArray());
field.setMaxArraySize(16, true);
EXPECT_EQ(field.maxArraySize(), 16);
EXPECT_TRUE(field.isDynamicArray());
}
TEST(LogViewFieldTest, JsonPathRoundTrips)
{
LogViewField field = makeField(QStringLiteral("issi"));
const QStringList path{QStringLiteral("header"), QStringLiteral("issi")};
field.setJsonPath(path);
EXPECT_EQ(field.jsonPath(), path);
}
TEST(LogViewFieldTest, ChildrenAreOwnedAndOrdered)
{
LogViewField parent(QStringLiteral("header"), LogViewField::e_FieldKindBorder, nullptr);
EXPECT_EQ(parent.childCount(), 0);
auto *first = new LogViewField(QStringLiteral("a"), LogViewField::e_FieldKindEdit, nullptr);
auto *second = new LogViewField(QStringLiteral("b"), LogViewField::e_FieldKindEdit, nullptr);
parent.addChild(first);
parent.addChild(second);
ASSERT_EQ(parent.childCount(), 2);
EXPECT_EQ(parent.child(0), first);
EXPECT_EQ(parent.child(1), second);
parent.removeLastChild();
EXPECT_EQ(parent.childCount(), 1);
EXPECT_EQ(parent.child(0), first);
}
@@ -0,0 +1,244 @@
/**
* @file LogViewTetraTelegramsParserTest.cpp
* @brief Unit tests for N_LogView::LogViewTetraTelegramsParser.
*
* The parser reads the C++ telegram specification header and exposes the
* structs, enums and POD types it found. It is pure logic with no GUI
* dependency, so each test feeds it a small specification written to a
* temporary file and inspects the resulting model.
*/
#include <gtest/gtest.h>
#include <QtCore/QString>
#include <QtCore/QTemporaryDir>
#include "LogViewTetraTelegramsParser.hpp"
using N_LogView::EnumInformation;
using N_LogView::LogViewTetraTelegramsParser;
using N_LogView::MemberInformation;
using N_LogView::PodInformation;
using N_LogView::StructInformation;
namespace
{
// Writes a specification snippet to a file inside dir and parses it.
bool parseSpecification(LogViewTetraTelegramsParser &parser,
const QTemporaryDir &dir,
const QString &content)
{
const QString path = dir.filePath(QStringLiteral("spec.h"));
QFile f(path);
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate))
return false;
f.write(content.toUtf8());
f.close();
return parser.parse(path);
}
const MemberInformation *findMember(const StructInformation &si, const QString &name)
{
for (const MemberInformation &mi : si.member)
{
if (mi.name == name)
return &mi;
}
return nullptr;
}
} // namespace
TEST(LogViewTetraTelegramsParserTest, BuiltinPodTypesAreKnownUpFront)
{
const LogViewTetraTelegramsParser parser;
EXPECT_TRUE(parser.isPod(QStringLiteral("bool")));
EXPECT_TRUE(parser.isPod(QStringLiteral("int32_t")));
EXPECT_FALSE(parser.isPod(QStringLiteral("NotAType")));
const PodInformation pod = parser.podFromType(QStringLiteral("int32_t"));
EXPECT_EQ(pod.byteLen, 4);
EXPECT_TRUE(pod.isIntegral);
EXPECT_TRUE(pod.isSigned);
}
TEST(LogViewTetraTelegramsParserTest, ParsingAMissingFileFails)
{
LogViewTetraTelegramsParser parser;
EXPECT_FALSE(parser.parse(QStringLiteral("/does/not/exist/spec.h")));
}
TEST(LogViewTetraTelegramsParserTest, ASimpleStructIsCollected)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"struct Header\n"
"{\n"
" int32_t equipmentNumber;\n"
" double offset;\n"
"};\n")));
ASSERT_TRUE(parser.isStruct(QStringLiteral("Header")));
const StructInformation si = parser.structFromType(QStringLiteral("Header"));
EXPECT_EQ(si.type, QStringLiteral("Header"));
EXPECT_TRUE(si.baseStruct.isEmpty());
ASSERT_EQ(si.member.size(), 2);
const MemberInformation *eqNr = findMember(si, QStringLiteral("equipmentNumber"));
ASSERT_NE(eqNr, nullptr);
EXPECT_EQ(eqNr->type, QStringLiteral("int32_t"));
EXPECT_TRUE(eqNr->isPod);
EXPECT_FALSE(eqNr->isArray);
}
TEST(LogViewTetraTelegramsParserTest, UnsignedFixedWidthTypesAreNotBuiltinPods)
{
// The built-in POD table only holds bool, int, int32_t, qint64, float and
// double. Unsigned fixed-width types are therefore not recognised as PODs.
const LogViewTetraTelegramsParser parser;
EXPECT_FALSE(parser.isPod(QStringLiteral("uint32_t")));
EXPECT_FALSE(parser.isPod(QStringLiteral("uint8_t")));
}
TEST(LogViewTetraTelegramsParserTest, BaseStructIsRecorded)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"struct Header\n"
"{\n"
" uint32_t equipmentNumber;\n"
"};\n"
"struct Position : public Header\n"
"{\n"
" int32_t easting;\n"
"};\n")));
ASSERT_TRUE(parser.isStruct(QStringLiteral("Position")));
const StructInformation si = parser.structFromType(QStringLiteral("Position"));
EXPECT_EQ(si.baseStruct, QStringLiteral("Header"));
// Base members are merged in after parsing, so the derived struct sees both.
EXPECT_NE(findMember(si, QStringLiteral("easting")), nullptr);
EXPECT_NE(findMember(si, QStringLiteral("equipmentNumber")), nullptr);
}
TEST(LogViewTetraTelegramsParserTest, EnumValuesAreNumberedImplicitlyAndExplicitly)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"enum class State\n"
"{\n"
" Unknown = 0,\n"
" Alive = 1,\n"
" Dead = 7,\n"
"};\n")));
ASSERT_TRUE(parser.isEnum(QStringLiteral("State")));
const EnumInformation ei = parser.enumFromType(QStringLiteral("State"));
ASSERT_EQ(ei.values.size(), 3);
EXPECT_EQ(ei.values.at(0).key, QStringLiteral("Unknown"));
EXPECT_EQ(ei.values.at(0).value, 0);
EXPECT_EQ(ei.values.at(1).key, QStringLiteral("Alive"));
EXPECT_EQ(ei.values.at(1).value, 1);
EXPECT_EQ(ei.values.at(2).key, QStringLiteral("Dead"));
EXPECT_EQ(ei.values.at(2).value, 7);
}
TEST(LogViewTetraTelegramsParserTest, ImplicitEnumValuesKeepTheTrailingComma)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"enum class State\n"
"{\n"
" Unknown,\n"
" Alive,\n"
"};\n")));
const EnumInformation ei = parser.enumFromType(QStringLiteral("State"));
ASSERT_EQ(ei.values.size(), 2);
// Known parser limitation: the trailing comma is only stripped from the value
// of an "Key = value," entry, never from the key of an implicitly numbered
// one. The shipped specification files always use explicit values.
EXPECT_EQ(ei.values.at(0).key, QStringLiteral("Unknown,"));
EXPECT_EQ(ei.values.at(0).value, 0);
EXPECT_EQ(ei.values.at(1).key, QStringLiteral("Alive,"));
EXPECT_EQ(ei.values.at(1).value, 1);
}
TEST(LogViewTetraTelegramsParserTest, StringAndBinaryMembersAreCategorised)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"struct Payload\n"
"{\n"
" std::string name;\n"
" std::vector<unsigned char> raw;\n"
"};\n")));
const StructInformation si = parser.structFromType(QStringLiteral("Payload"));
const MemberInformation *name = findMember(si, QStringLiteral("name"));
const MemberInformation *raw = findMember(si, QStringLiteral("raw"));
ASSERT_NE(name, nullptr);
ASSERT_NE(raw, nullptr);
EXPECT_TRUE(name->isString);
EXPECT_TRUE(raw->isBinary);
}
TEST(LogViewTetraTelegramsParserTest, VectorMembersAreMarkedAsArrays)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"struct Group\n"
"{\n"
" std::vector<uint32_t> issis;\n"
"};\n")));
const StructInformation si = parser.structFromType(QStringLiteral("Group"));
const MemberInformation *issis = findMember(si, QStringLiteral("issis"));
ASSERT_NE(issis, nullptr);
EXPECT_TRUE(issis->isArray);
}
TEST(LogViewTetraTelegramsParserTest, GetInnerTypeUnwrapsTemplateArguments)
{
EXPECT_EQ(LogViewTetraTelegramsParser::getInnerType(QStringLiteral("std::vector<uint32_t>")),
QStringLiteral("uint32_t"));
EXPECT_TRUE(LogViewTetraTelegramsParser::getInnerType(QStringLiteral("uint32_t")).isEmpty());
}
TEST(LogViewTetraTelegramsParserTest, NoTelegramsAreVisibleWithoutConstraints)
{
QTemporaryDir dir;
ASSERT_TRUE(dir.isValid());
LogViewTetraTelegramsParser parser;
ASSERT_TRUE(parseSpecification(parser, dir, QStringLiteral(
"struct Header\n"
"{\n"
" uint32_t equipmentNumber;\n"
"};\n")));
EXPECT_TRUE(parser.telegramsToCreate().isEmpty());
EXPECT_TRUE(parser.nameFromTelegramId(1).isEmpty());
}
@@ -76,3 +76,8 @@ NGL_TARGET_LINK_LIBRARIES(PrtCnv
NGL_INSTALL_TARGET(PrtCnv)
NGL_INSTALL(AAR SV FILES log4cxx_prtcnv.props DESTINATION bin)
NGL_INSTALL(AAR SV FILES PrtCnv.dat.tts DESTINATION bin)
# Unit tests (LTS_HAVE_GTEST is set by the top-level CMakeLists.txt)
if(BUILD_TESTING AND LTS_HAVE_GTEST)
add_subdirectory(unittest)
endif()
@@ -41,19 +41,19 @@ int main(int argc, char **argv)
TetraIF::usage();
}
const QString mode = args[3].toLower();
if (mode != QLatin1String("listen") &&
mode != QLatin1String("send_random") &&
mode != QLatin1String("send_file"))
if (mode != QStringLiteral("listen") &&
mode != QStringLiteral("send_random") &&
mode != QStringLiteral("send_file"))
{
ERROR_LOG(logger) << "Invalid mode " << args[3];
TetraIF::usage();
}
TetraIF t(tetra, port, issi);
if (mode == QLatin1String("listen"))
if (mode == QStringLiteral("listen"))
t.listenMode(args.mid(4));
else if (mode == QLatin1String("send_random"))
else if (mode == QStringLiteral("send_random"))
t.randomMode(args.mid(4));
else if (mode == QLatin1String("send_file"))
else if (mode == QStringLiteral("send_file"))
t.fileMode(args.mid(4));
t.start();
@@ -19,7 +19,9 @@
#include <PrtCnv/PrtCnvRadioThread.hpp>
#include <PrtCnv/PrtCnvThreadStarter.hpp>
TetraIF::TetraIF(const QHostAddress &addr, unsigned short port, unsigned short issi) : QObject()
TetraIF::TetraIF(const QHostAddress &addr, unsigned short port, unsigned short issi)
: QObject()
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
, m_addr(addr)
, m_port(port)
, m_issi(issi)
@@ -30,12 +32,11 @@ TetraIF::TetraIF(const QHostAddress &addr, unsigned short port, unsigned short i
, m_secondFragment(0)
, m_timer(nullptr)
, m_SendCounter(0)
),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger()) {
{
connect(m_socket, &QTcpSocket::connected, this, &TetraIF::onConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &TetraIF::onDisconnected);
connect(m_socket, &QTcpSocket::readyRead, this, &TetraIF::onReadyRead);
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &TetraIF::onError);
connect(m_socket, &QTcpSocket::errorOccurred, this, &TetraIF::onError);
m_outputDir = QCoreApplication::applicationDirPath();
m_outputDir += QLatin1Char('/') + QString::number(m_issi) + QLatin1Char('-');
@@ -303,7 +304,7 @@ void TetraIF::dumpData(const QByteArray &data)
const qint64 msecs = QDateTime::currentMSecsSinceEpoch();
const QString timeStr = QStringLiteral("%1.%2").arg(msecs / 1000).arg(msecs % 1000);
{
QFile f(m_outputDir + timeStr + QLatin1String(".dat"));
QFile f(m_outputDir + timeStr + QStringLiteral(".dat"));
if (!f.open(QIODevice::WriteOnly))
{
ERROR_LOG(m_logger) << "Error opening file "
@@ -406,7 +407,7 @@ QString TetraIF::getIssisAsString() const
{
QString ret;
for (unsigned short issi : std::as_const(m_issiList))
ret += QString::number(issi) + QLatin1String(", ");
ret += QString::number(issi) + QStringLiteral(", ");
return ret.left(ret.size() - 2);
}
@@ -71,7 +71,7 @@ void MainWindow::slot_analysieren()
ui->labelResult->setText(QString());
QString ISSI = ui->lineEditISSI->text();
if (ISSI.isEmpty())
ISSI = QLatin1String("1");
ISSI = QStringLiteral("1");
m_logfileList.clear();
@@ -79,8 +79,8 @@ void MainWindow::slot_analysieren()
m_files = folder.entryList();
folder.~QDir();
ui->progressBar->setValue(1);
const QString paytext = ISSI + QLatin1String("-payload");
const QString issitext = ISSI + QLatin1String("-1");
const QString paytext = ISSI + QStringLiteral("-payload");
const QString issitext = ISSI + QStringLiteral("-1");
for (int i = 0; i < m_files.count(); i++)
{
@@ -92,7 +92,7 @@ void MainWindow::slot_analysieren()
}
else
{
if (!name.contains(QLatin1String(".dat")))
if (!name.contains(QStringLiteral(".dat")))
{
m_files.removeAt(i);
i--;
@@ -119,7 +119,7 @@ void MainWindow::slot_analysieren()
readFiles();
ui->progressBar->setValue(90);
ui->progressBar->repaint();
QString ausgabetext = QLatin1String("\tANALYSIS COMPLETED - ") + QString::number(auswerten()) + QLatin1String(" missing messages");
QString ausgabetext = QStringLiteral("\tANALYSIS COMPLETED - ") + QString::number(auswerten()) + QStringLiteral(" missing messages");
ui->labelResult->setText(ausgabetext);
}
ui->progressBar->setValue(100);
@@ -181,7 +181,7 @@ void MainWindow::openLogfile(const QString &folder, int count)
{
m_logfile = folder;
m_logZeiten = folder;
m_logfile += QLatin1String("/logfile_analysis.txt");
m_logfile += QStringLiteral("/logfile_analysis.txt");
QFile file(m_logfile);
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
{
@@ -189,7 +189,7 @@ void MainWindow::openLogfile(const QString &folder, int count)
file.write(msg.toUtf8());
file.close();
}
m_logZeiten += QLatin1String("/transmission_times.csv");
m_logZeiten += QStringLiteral("/transmission_times.csv");
file.setFileName(m_logZeiten);
if (file.open(QIODevice::WriteOnly))
{
@@ -206,13 +206,13 @@ void MainWindow::writeToLogfile(const QString &issi,
const QString &bytes)
{
QString text = issi;
text += QLatin1String(": ");
text += timestamp.toString(QLatin1String("dd.MM.yyyy hh:mm:ss"));
text += QLatin1String(" - ");
text += QStringLiteral(": ");
text += timestamp.toString(QStringLiteral("dd.MM.yyyy hh:mm:ss"));
text += QStringLiteral(" - ");
text += filename;
text += QLatin1String(" -> ");
text += QStringLiteral(" -> ");
text += bytes;
text += QLatin1String(" --> ");
text += QStringLiteral(" --> ");
text += QString::number(lfdNr, 10);
text += QLatin1Char('\n');
QFile file(m_logfile);
@@ -235,13 +235,13 @@ void MainWindow::writeToLogfile(const QString &issi,
uint lfdNr)
{
QString text = issi;
text += QLatin1String(": ");
text += sendeZeit.toString(QLatin1String("hh:mm:ss"));
text += QLatin1String(" --> ");
text += timestamp.toString(QLatin1String("dd.MM.yyyy hh:mm:ss"));
text += QLatin1String(" - ");
text += QStringLiteral(": ");
text += sendeZeit.toString(QStringLiteral("hh:mm:ss"));
text += QStringLiteral(" --> ");
text += timestamp.toString(QStringLiteral("dd.MM.yyyy hh:mm:ss"));
text += QStringLiteral(" - ");
text += filename;
text += QLatin1String(" --> ");
text += QStringLiteral(" --> ");
text += QString::number(lfdNr, 10);
text += QLatin1Char('\n');
QFile file(m_logfile);
@@ -416,9 +416,9 @@ void MainWindow::writeLogZeiten(const QDateTime &beginn, const QDateTime &end, c
{
QString msg = issi;
msg += QLatin1Char(';');
msg += beginn.toString(QLatin1String("hh:mm:ss"));
msg += beginn.toString(QStringLiteral("hh:mm:ss"));
msg += QLatin1Char(';');
msg += end.toString(QLatin1String("hh:mm:ss"));
msg += end.toString(QStringLiteral("hh:mm:ss"));
msg += QLatin1Char('\n');
QFile file(m_logZeiten);
file.open(QIODevice::Append | QIODevice::Text);
@@ -53,7 +53,7 @@ static std::string threadIdToString(PrtCnvApplication::E_ThreadId id)
PrtCnvApplication::PrtCnvApplication()
: m_Config(nullptr)
, m_exerciseId(0)
, m_accessMutex(QMutex::Recursive)
, m_logger(getLogger("PrtCnvApplication"))
{}
@@ -165,7 +165,7 @@ protected:
mutable QMutex m_accessMutex;
mutable QRecursiveMutex m_accessMutex;
QString m_dbDriver;
QString m_dbHostName;
@@ -173,6 +173,8 @@ protected:
QString m_dbSchemaName;
QString m_dbUserName;
QString m_dbPassword;
LOGGER_T m_logger;
};
}
@@ -12,6 +12,8 @@
#include "PrtCnvBroadcastMgr.hpp"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <utility>
#include "PrtCnvDbThread.hpp"
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
@@ -351,6 +351,7 @@ Q_SIGNALS:
private:
NGL::INGLLogger &m_loggerBcRequest;
NGL::INGLLogger &m_logger;
};
}
@@ -23,7 +23,7 @@
#include <CoPrtCnv/CoPrtCnvTelegramConverter.hpp>
#include <CoPrtCnv/CoPrtCnvCentralTelegram.hpp>
#include <LtsUtils/dds_bitarray.h>
#include <LtsUtilsCore/dds_bitarray.h>
#include <QtCore/QTimer>
#include <QtCore/QCoreApplication>
@@ -798,7 +798,7 @@ bool PrtCnvCentralThread::handleSpecialTelegram(N_CoPrtCnv::CoPrtCnvCentralTeleg
void PrtCnvCentralThread::connectSocket()
{
const QString host = m_Config->getString(getName(), QStringLiteral("HostName"), QStringLiteral("EXCTDS01"));
if (host == QLatin1String("directConnection"))
if (host == QStringLiteral("directConnection"))
{
m_bDirectConnection = true;
connected();
@@ -43,13 +43,7 @@ PrtCnvDbThread::PrtCnvDbThread(const QString &dbDriver,
const QString &dbPassword,
PrtCnv::PrtCnvThreadStarter *a_parent)
: PrtCnvThread(a_parent, "PrtCnvDbThread")
, m_BattleFieldOpStateMutex(QMutex::Recursive)
, m_MemberListByIdMutex(QMutex::Recursive)
, m_CentralListMutex(QMutex::Recursive)
, m_OldCentralAckCounter(0)
, m_RadioListMutex(QMutex::Recursive)
, m_SqlCmdListMutex(QMutex::Recursive)
, m_BroadcastMapMutex(QMutex::Recursive)
, m_DoClean(false)
, m_DoWaitUntilSqlWritten(false)
, m_DoStorePermanent(false)
@@ -156,12 +150,12 @@ bool PrtCnvDbThread::createDatabase()
closeDb();
m_db = QSqlDatabase::addDatabase(m_dbDriver, QStringLiteral("PrtCnv"));
if (m_dbDriver == QLatin1String("QSQLITE"))
if (m_dbDriver == QStringLiteral("QSQLITE"))
{
QString path = m_Config->getString(getName(), QStringLiteral("DatabaseFileName"), QStringLiteral("telegrams.db"));
if (!QDir::isAbsolutePath(path))
{
path = QCoreApplication::applicationDirPath() + QLatin1String("/../") + path;
path = QCoreApplication::applicationDirPath() + QStringLiteral("/../") + path;
QFileInfo fi(path);
QDir().mkpath(fi.absolutePath());
}
@@ -408,7 +402,7 @@ bool PrtCnvDbThread::createDatabase()
ERROR_LOG(m_logger) << "Internal error: conversion of telegram with telId=" << radioTelegram.getTelID() << " from radio to central failed";
}
if (m_db.driverName() == QLatin1String("QSQLITE"))
if (m_db.driverName() == QStringLiteral("QSQLITE"))
{
q.exec(QStringLiteral("VACUUM;"));
q.exec(QStringLiteral("PRAGMA journal_mode=WAL;"));
@@ -213,15 +213,15 @@ namespace PrtCnv
mutable QMutex m_BattleFieldOpStateMutex;
mutable QRecursiveMutex m_BattleFieldOpStateMutex;
mutable QMutex m_MemberListByIdMutex;
mutable QRecursiveMutex m_MemberListByIdMutex;
mutable QMutex m_CentralListMutex;
mutable QRecursiveMutex m_CentralListMutex;
@@ -238,16 +238,16 @@ namespace PrtCnv
std::list<PrtCnvStoredRadioTelegram*> m_RadioList;
mutable QMutex m_RadioListMutex;
mutable QRecursiveMutex m_RadioListMutex;
std::vector<QString> m_SqlCommandList;
mutable QMutex m_SqlCmdListMutex;
mutable QRecursiveMutex m_SqlCmdListMutex;
mutable QMutex m_BroadcastMapMutex;
mutable QRecursiveMutex m_BroadcastMapMutex;
std::list<PrtCnvStoredRadioTelegram*> m_BroadcastList;
@@ -25,6 +25,7 @@ namespace PrtCnv
PrtCnvInjectionSocket::PrtCnvInjectionSocket()
: m_Socket(nullptr)
, m_Server(nullptr)
, m_logger(getLogger("PrtCnvInjectionSocket"))
{}
PrtCnvInjectionSocket::~PrtCnvInjectionSocket()
@@ -55,7 +55,8 @@ namespace PrtCnv
void disconnected(PrtCnvInjectionSocket* a_injectSocket);
protected:
LOGGER_T m_logger;
};
}
@@ -88,9 +88,7 @@ PrtCnvRadioThread::PrtCnvRadioThread(int exerciseId, PrtCnvThreadStarter *a_pare
m_ReceivedTelegrams(0),
m_ReceivedBytes(0),
m_bUseScrambling(false),
m_loggerStats(getLogger("PrtCnvRadioThread.statistic")),
m_exerciseEquipmentAssignmentMutex(QMutex::Recursive),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger()) {
m_loggerStats(getLogger("PrtCnvRadioThread.statistic")) {
m_Name = QStringLiteral("Radio");
for (int i = 0; i < AVERAGE_COUNT; ++i)
{
@@ -176,7 +174,7 @@ int32_t PrtCnvRadioThread::init()
m_DbThread->licenseMember(m_DbThread->addMember(0, m_BroadcastISSI));
QString groupString = m_Config->getString(getName(), QStringLiteral("ListenGroups"), QString());
const QVector<QStringView> groups = groupString.splitView(QLatin1Char(','), Qt::SkipEmptyParts);
const QList<QStringView> groups = QStringView(groupString).split(QLatin1Char(','), Qt::SkipEmptyParts);
for (const QStringView &sr : groups)
{
uint32_t group = sr.toUInt();
@@ -192,7 +190,7 @@ int32_t PrtCnvRadioThread::init()
m_LoginPathWithPrefix = m_Config->getString(QStringLiteral("Login"), QStringLiteral("LoginFilePathWithPrefix"), QStringLiteral("login"));
if (!QDir::isAbsolutePath(m_LoginPathWithPrefix))
m_LoginPathWithPrefix = QCoreApplication::applicationDirPath() + QLatin1String("/../") + m_LoginPathWithPrefix;
m_LoginPathWithPrefix = QCoreApplication::applicationDirPath() + QStringLiteral("/../") + m_LoginPathWithPrefix;
m_LoginPathWithPrefix = QDir::cleanPath(QDir::fromNativeSeparators(m_LoginPathWithPrefix));
QString path = m_LoginPathWithPrefix.left(m_LoginPathWithPrefix.lastIndexOf(QLatin1Char('/')));
@@ -1524,8 +1522,8 @@ void PrtCnvRadioThread::writeLoginLog(const N_CoPrtCnv::CoPrtCnvRadioTelegram *a
INFO_LOG(m_logger) << logData;
QString date = QDate::currentDate().toString(QLatin1String("yyyyMMdd"));
QString fileName = m_LoginPathWithPrefix + date + QLatin1Char('_') + QString::number(m_ExerciseId) + QLatin1String(".log");
QString date = QDate::currentDate().toString(QStringLiteral("yyyyMMdd"));
QString fileName = m_LoginPathWithPrefix + date + QLatin1Char('_') + QString::number(m_ExerciseId) + QStringLiteral(".log");
QFile file(fileName);
@@ -263,7 +263,7 @@ public:
std::unordered_map<int, std::unordered_set<int>> m_exerciseEquipmentAssignments;
std::unordered_map<int, TrainingAreaBase::TetraIcd::GroupIssiInformation> m_groupIssiInformation;
mutable QMutex m_exerciseEquipmentAssignmentMutex;
mutable QRecursiveMutex m_exerciseEquipmentAssignmentMutex;
private:
@@ -31,7 +31,6 @@ PrtCnvRadioTrafficThread::PrtCnvRadioTrafficThread(PrtCnvThreadStarter* a_parent
, m_hystLoad(5)
, m_calcTimeout(1000)
, m_cleanupTimeout(5000)
, m_mutex(QMutex::Recursive)
{}
void PrtCnvRadioTrafficThread::newTelegramArrived(unsigned int size)
@@ -72,7 +72,7 @@ protected:
QMutex m_mutex;
QRecursiveMutex m_mutex;
@@ -100,7 +100,7 @@ void PrtCnvSocketThread::createNewSocket()
connect(m_Socket, &QTcpSocket::connected, this, &PrtCnvSocketThread::connected, Qt::QueuedConnection);
connect(m_Socket, &QTcpSocket::disconnected, this, &PrtCnvSocketThread::disconnected, Qt::QueuedConnection);
connect(m_Socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &PrtCnvSocketThread::error, Qt::QueuedConnection);
connect(m_Socket, &QTcpSocket::errorOccurred, this, &PrtCnvSocketThread::error, Qt::QueuedConnection);
connect(m_Socket, &QTcpSocket::hostFound, this, &PrtCnvSocketThread::hostFound, Qt::QueuedConnection);
connect(m_Socket, &QTcpSocket::stateChanged, this, &PrtCnvSocketThread::stateChanged);
connect(m_Socket, &QTcpSocket::readyRead, this, &PrtCnvSocketThread::readyRead, Qt::QueuedConnection);
@@ -364,8 +364,8 @@ void PrtCnvSocketThread::readHostAdresses()
uint16_t port = m_Config->getInteger(getName(), QStringLiteral("Port"), 4934);
m_hostAdresses.push_back(qMakePair(host, port));
for (int i = 1; i < 10; ++i) {
const QString hostName = QLatin1String("HostName") + QString::number(i);
const QString portName = QLatin1String("Port") + QString::number(i);
const QString hostName = QStringLiteral("HostName") + QString::number(i);
const QString portName = QStringLiteral("Port") + QString::number(i);
host = m_Config->getString(getName(), hostName, QString());
port = m_Config->getInteger(getName(), portName, 0);
if (host.isEmpty() || port == 0)
@@ -36,6 +36,8 @@ protected:
Qt::HANDLE m_currentThreadId;
LOGGER_T m_logger;
public:
@@ -33,6 +33,7 @@ PrtCnvThreadStarter::PrtCnvThreadStarter(const PrtCnv::PrtCnvApplication::E_Thre
, m_Application(a_mainApp)
, m_Id(a_id)
, m_settings(new NGL::Settings(configFileName))
, m_logger(getLogger("PrtCnvThreadStarter"))
{
DEBUG_LOG(m_logger) << "Using Config file '" << configFileName << "'";
}
@@ -59,6 +59,8 @@ protected:
void run() override;
LOGGER_T m_logger;
};
}
@@ -14,8 +14,8 @@
int main(int argc, char **argv)
{
QCoreApplication::setApplicationName(QLatin1String("TTS"));
QCoreApplication::setOrganizationName(QLatin1String("RME"));
QCoreApplication::setApplicationName(QStringLiteral("TTS"));
QCoreApplication::setOrganizationName(QStringLiteral("RME"));
NGLCoreApplication app(argc, argv);
app.createLogger("tts", "log4cxx_tetratestserver.props");
@@ -26,96 +26,96 @@ int main(int argc, char **argv)
LtsCommandLineParser::LtsCommandLineParser options(LtsCommandLineParser::LtsCommandLineParser::CustomConfigFile);
options.addOption({ QStringList() << QLatin1String("p") << QLatin1String("player")
, QLatin1String("number of players to be simulated.")
, QLatin1String("Default value")
, QLatin1String("5")
options.addOption({ QStringList() << QStringLiteral("p") << QStringLiteral("player")
, QStringLiteral("number of players to be simulated.")
, QStringLiteral("Default value")
, QStringLiteral("5")
});
options.addOption({ QStringList() << QLatin1String("n") << QLatin1String("northing")
, QLatin1String("initial position UTM north.")
, QLatin1String("Default value")
, QLatin1String("77777")
options.addOption({ QStringList() << QStringLiteral("n") << QStringLiteral("northing")
, QStringLiteral("initial position UTM north.")
, QStringLiteral("Default value")
, QStringLiteral("77777")
});
options.addOption({ QStringList() << QLatin1String("e") << QLatin1String("easting")
, QLatin1String("initial position UTM east.")
, QLatin1String("Default value")
, QLatin1String("99999")
options.addOption({ QStringList() << QStringLiteral("e") << QStringLiteral("easting")
, QStringLiteral("initial position UTM east.")
, QStringLiteral("Default value")
, QStringLiteral("99999")
});
options.addOption({ QStringList() << QLatin1String("f") << QLatin1String("first-id")
, QLatin1String("first equipment ID to use.")
, QLatin1String("Default value")
, QLatin1String("1101")
options.addOption({ QStringList() << QStringLiteral("f") << QStringLiteral("first-id")
, QStringLiteral("first equipment ID to use.")
, QStringLiteral("Default value")
, QStringLiteral("1101")
});
options.addOption({ QStringList() << QLatin1String("r") << QLatin1String("pprow")
, QLatin1String("players per row.")
, QLatin1String("Default value")
, QLatin1String("25")
options.addOption({ QStringList() << QStringLiteral("r") << QStringLiteral("pprow")
, QStringLiteral("players per row.")
, QStringLiteral("Default value")
, QStringLiteral("25")
});
options.addOption({ QStringList() << QLatin1String("s") << QLatin1String("pspacing")
, QLatin1String("utm based spacing between the players.")
, QLatin1String("Default value")
, QLatin1String("100")
options.addOption({ QStringList() << QStringLiteral("s") << QStringLiteral("pspacing")
, QStringLiteral("utm based spacing between the players.")
, QStringLiteral("Default value")
, QStringLiteral("100")
});
options.addOption({ QStringList() << QLatin1String("z") << QLatin1String("issi")
, QLatin1String("DestinationIssi / HostISSI")
, QLatin1String("Default value")
, QLatin1String("2")
options.addOption({ QStringList() << QStringLiteral("z") << QStringLiteral("issi")
, QStringLiteral("DestinationIssi / HostISSI")
, QStringLiteral("Default value")
, QStringLiteral("2")
});
options.addOption({ QStringList() << QLatin1String("m") << QLatin1String("movements")
, QLatin1String("how many movements per milliseconds to make.")
, QLatin1String("Default value")
, QLatin1String("2000")
options.addOption({ QStringList() << QStringLiteral("m") << QStringLiteral("movements")
, QStringLiteral("how many movements per milliseconds to make.")
, QStringLiteral("Default value")
, QStringLiteral("2000")
});
options.addOption({ QStringList() << QLatin1String("d") << QLatin1String("death")
, QLatin1String("minimum times, after the movements timer is triggered, a dead player can revive.")
, QLatin1String("Default value")
, QLatin1String("100")
options.addOption({ QStringList() << QStringLiteral("d") << QStringLiteral("death")
, QStringLiteral("minimum times, after the movements timer is triggered, a dead player can revive.")
, QStringLiteral("Default value")
, QStringLiteral("100")
});
options.addOption({ QStringList() << QLatin1String("o") << QLatin1String("death-offset")
, QLatin1String("maximum times, after the movements timer is triggered, a dead player can revive.")
, QLatin1String("(0 -> identical to min)")
, QLatin1String("0")
options.addOption({ QStringList() << QStringLiteral("o") << QStringLiteral("death-offset")
, QStringLiteral("maximum times, after the movements timer is triggered, a dead player can revive.")
, QStringLiteral("(0 -> identical to min)")
, QStringLiteral("0")
});
options.addOption({ QStringList() << QLatin1String("t") << QLatin1String("pattern")
, QLatin1String("pattern the player has to walk [enter pattern by hand or pattern alias-name from settings file]\r\nfor more info, enter '--pattern-help'.")
, QLatin1String("Default value")
, QLatin1String("3,30,20#3,30,-20#3,-30,-20#3,-30,20")
options.addOption({ QStringList() << QStringLiteral("t") << QStringLiteral("pattern")
, QStringLiteral("pattern the player has to walk [enter pattern by hand or pattern alias-name from settings file]\r\nfor more info, enter '--pattern-help'.")
, QStringLiteral("Default value")
, QStringLiteral("3,30,20#3,30,-20#3,-30,-20#3,-30,20")
});
options.addOption({ QStringList() << QLatin1String("demand-old-broadcast-telegrams")
, QLatin1String("player demand old broadcast telegrams starting at BCI <default value>")
, QLatin1String("Default value")
, QLatin1String("0")
options.addOption({ QStringList() << QStringLiteral("demand-old-broadcast-telegrams")
, QStringLiteral("player demand old broadcast telegrams starting at BCI <default value>")
, QStringLiteral("Default value")
, QStringLiteral("0")
});
options.addOption({ QStringList() << QLatin1String("deactivate-single-mines")
, QLatin1String("the first player deactivates single mines with ids from minimum-mine-id to maximum-mine-id")
options.addOption({ QStringList() << QStringLiteral("deactivate-single-mines")
, QStringLiteral("the first player deactivates single mines with ids from minimum-mine-id to maximum-mine-id")
});
options.addOption({ QStringList() << QLatin1String("minimum-mine-id")
, QLatin1String("sets the value for minimum-mine-id used within deactivate-single-mines command")
, QLatin1String("Default value")
, QLatin1String("minimum-mine-id 2048")
options.addOption({ QStringList() << QStringLiteral("minimum-mine-id")
, QStringLiteral("sets the value for minimum-mine-id used within deactivate-single-mines command")
, QStringLiteral("Default value")
, QStringLiteral("minimum-mine-id 2048")
});
options.addOption({ QStringList() << QLatin1String("maximum-mine-id")
, QLatin1String("sets the value for maximum-mine-Id used within deactivate-single-mines command")
, QLatin1String("Default value")
, QLatin1String("maximum-mine-id 2100")
options.addOption({ QStringList() << QStringLiteral("maximum-mine-id")
, QStringLiteral("sets the value for maximum-mine-Id used within deactivate-single-mines command")
, QStringLiteral("Default value")
, QStringLiteral("maximum-mine-id 2100")
});
options.addOption({ QStringList() << QLatin1String("pattern-help")
, QLatin1String("help for the pattern interpreter.")
options.addOption({ QStringList() << QStringLiteral("pattern-help")
, QStringLiteral("help for the pattern interpreter.")
});
@@ -124,30 +124,30 @@ int main(int argc, char **argv)
options.showHelp();
return -1;
}
QSettings serverSettings(app.applicationDirPath() + QLatin1String("/") + options.iniFile(), QSettings::IniFormat);
QSettings serverSettings(app.applicationDirPath() + QStringLiteral("/") + options.iniFile(), QSettings::IniFormat);
TTSArgs ttsArgs;
ttsArgs.destIssi = options.isSet(QLatin1String("issi")) ? options.value(QLatin1String("issi")).toInt() : 2;
ttsArgs.cntPlayer = options.isSet(QLatin1String("player")) ? options.value(QLatin1String("player")).toInt() : 0;
int northPos_arg = options.isSet(QLatin1String("northing")) ? options.value(QLatin1String("northing")).toInt() : 77777;
int eastPos_arg = options.isSet(QLatin1String("easting")) ? options.value(QLatin1String("easting")).toInt() : 90000;
ttsArgs.destIssi = options.isSet(QStringLiteral("issi")) ? options.value(QStringLiteral("issi")).toInt() : 2;
ttsArgs.cntPlayer = options.isSet(QStringLiteral("player")) ? options.value(QStringLiteral("player")).toInt() : 0;
int northPos_arg = options.isSet(QStringLiteral("northing")) ? options.value(QStringLiteral("northing")).toInt() : 77777;
int eastPos_arg = options.isSet(QStringLiteral("easting")) ? options.value(QStringLiteral("easting")).toInt() : 90000;
ttsArgs.position = QPointF(eastPos_arg, northPos_arg);
ttsArgs.eqIdStart = options.isSet(QLatin1String("first-id")) ? options.value(QLatin1String("first-id")).toInt() : 1101;
ttsArgs.pprow = options.isSet(QLatin1String("pprow")) ? options.value(QLatin1String("pprow")).toInt() : 25;
ttsArgs.pspacing = options.isSet(QLatin1String("pspacing")) ? options.value(QLatin1String("pspacing")).toInt() : 100;
ttsArgs.movs_per_msec = options.isSet(QLatin1String("movements")) ? options.value(QLatin1String("movements")).toInt() : 2000;
ttsArgs.minimumDeathTicks = options.isSet(QLatin1String("death")) ? options.value(QLatin1String("death")).toInt() : 10;
ttsArgs.maximumDeathTicks = options.isSet(QLatin1String("death-offset")) ? options.value(QLatin1String("death-offset")).toInt() : 20;
ttsArgs.demandOldBraodcastTelegrams = options.isSet(QLatin1String("demand-old-broadcast-telegrams")) ? true : false;
ttsArgs.eqIdStart = options.isSet(QStringLiteral("first-id")) ? options.value(QStringLiteral("first-id")).toInt() : 1101;
ttsArgs.pprow = options.isSet(QStringLiteral("pprow")) ? options.value(QStringLiteral("pprow")).toInt() : 25;
ttsArgs.pspacing = options.isSet(QStringLiteral("pspacing")) ? options.value(QStringLiteral("pspacing")).toInt() : 100;
ttsArgs.movs_per_msec = options.isSet(QStringLiteral("movements")) ? options.value(QStringLiteral("movements")).toInt() : 2000;
ttsArgs.minimumDeathTicks = options.isSet(QStringLiteral("death")) ? options.value(QStringLiteral("death")).toInt() : 10;
ttsArgs.maximumDeathTicks = options.isSet(QStringLiteral("death-offset")) ? options.value(QStringLiteral("death-offset")).toInt() : 20;
ttsArgs.demandOldBraodcastTelegrams = options.isSet(QStringLiteral("demand-old-broadcast-telegrams")) ? true : false;
if (ttsArgs.demandOldBraodcastTelegrams)
ttsArgs.demandOldBraodcastTelegramsCounter = options.value(QLatin1String("demand-old-broadcast-telegrams")).toInt();
ttsArgs.deactivationSingleMines = options.isSet(QLatin1String("deactivate-single-mines")) ? true : false;
ttsArgs.minimumMineId = options.isSet(QLatin1String("minimum-mine-id")) ? options.value(QLatin1String("minimum-mine-id")).toInt() : 2048;
ttsArgs.maximumMineId = options.isSet(QLatin1String("maximum-mine-id")) ? options.value(QLatin1String("maximum-mine-id")).toInt() : 2100;
ttsArgs.pattern = options.isSet(QLatin1String("pattern")) ? options.value(QLatin1String("pattern")) : QLatin1String("3,30,20#3,30,-20#3,-30,-20#3,-30,20");
ttsArgs.demandOldBraodcastTelegramsCounter = options.value(QStringLiteral("demand-old-broadcast-telegrams")).toInt();
ttsArgs.deactivationSingleMines = options.isSet(QStringLiteral("deactivate-single-mines")) ? true : false;
ttsArgs.minimumMineId = options.isSet(QStringLiteral("minimum-mine-id")) ? options.value(QStringLiteral("minimum-mine-id")).toInt() : 2048;
ttsArgs.maximumMineId = options.isSet(QStringLiteral("maximum-mine-id")) ? options.value(QStringLiteral("maximum-mine-id")).toInt() : 2100;
ttsArgs.pattern = options.isSet(QStringLiteral("pattern")) ? options.value(QStringLiteral("pattern")) : QStringLiteral("3,30,20#3,30,-20#3,-30,-20#3,-30,20");
if (options.isSet(QLatin1String("pattern-help")))
if (options.isSet(QStringLiteral("pattern-help")))
{
options.showHelp();
return -1;
@@ -170,9 +170,9 @@ int main(int argc, char **argv)
TTServer *s = new TTServer(ttsArgs);
if (!s->listen(QHostAddress::Any, serverSettings.value(QLatin1String("Radio/Port"), 4200).toInt()))
if (!s->listen(QHostAddress::Any, serverSettings.value(QStringLiteral("Radio/Port"), 4200).toInt()))
{
ERROR_LOG(logger) << "Error listening on localhost:" << serverSettings.value(QLatin1String("Radio/Port"), 52010).toInt() << ": "
ERROR_LOG(logger) << "Error listening on localhost:" << serverSettings.value(QStringLiteral("Radio/Port"), 52010).toInt() << ": "
<< s->errorString();
delete s;
return -1;
@@ -7,9 +7,10 @@
#include "worker.h"
TTServer::TTServer(const TTSArgs &ttsArgs) : m_ttsArgs(ttsArgs)
.getNGLLogger("TTServer")),
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger()) {
TTServer::TTServer(const TTSArgs &ttsArgs)
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
, m_ttsArgs(ttsArgs)
{
connect(this, &TTServer::newConnection,
this, &TTServer::onNewConnection);
}
@@ -21,16 +21,15 @@ TTWorker::TTWorker(QTcpSocket *socket, const TTSArgs &ttsArgs)
, m_ttsArgs(ttsArgs)
, m_patternList(interpretPattern(ttsArgs.pattern))
, m_generalPosition(ttsArgs.position)
.getNGLLogger("TTWorker"))
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
{
qsrand(time(nullptr));
}
bool TTWorker::init()
{
connect(m_socket, &QTcpSocket::disconnected,
this, &TTWorker::deleteLater);
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
connect(m_socket, &QTcpSocket::errorOccurred,
this, &TTWorker::onSocketError);
connect(m_socket, &QTcpSocket::readyRead,
this, &TTWorker::onReadyRead);
@@ -87,7 +86,7 @@ QVector<runningPattern> TTWorker::interpretPattern(QString pattern) const
QString patternAlias = pattern;
pattern = m_ttsArgs.settings->value(QLatin1String("pattern/") + patternAlias).toString();
pattern = m_ttsArgs.settings->value(QStringLiteral("pattern/") + patternAlias).toString();
if (pattern.isEmpty())
{
@@ -7,6 +7,7 @@
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QPointF>
#include <QtCore/QRandomGenerator>
#include <QtCore/QMap>
#include <NGLLogger/INGLLogger.h>
#include <CoPrtCnv/CoPrtCnvCentralTelegram.hpp>
@@ -22,10 +23,9 @@ class QTimer;
class Player
{
private:
NGL::INGLLogger &m_logger;
void randomizeDeathTicks()
{
deathTicks = ((qrand() % (maximumDeathTicks - minimumDeathTicks + 1)) + minimumDeathTicks);
deathTicks = QRandomGenerator::global()->bounded(minimumDeathTicks, maximumDeathTicks + 1);
}
public:
@@ -125,4 +125,6 @@ private:
QVector<Player *> m_playerList;
QVector<runningPattern> m_patternList;
QPointF m_generalPosition;
NGL::INGLLogger &m_logger;
};
@@ -0,0 +1,26 @@
# Unit tests for PrtCnv.
# PrtCnvLib is built with hidden visibility and PrtCnvMember carries no export
# macro, so the classes under test are compiled into the test executable rather
# than widening the library's public ABI for the tests' sake.
# GoogleTest is resolved once in the top-level CMakeLists.txt.
add_executable(PrtCnvTests
${CMAKE_CURRENT_SOURCE_DIR}/../../unittest_main.cpp
PrtCnvMemberTest.cpp
PrtCnvStoredTelegramTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../PrtCnvMember.cpp
)
target_include_directories(PrtCnvTests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/../..
)
target_link_libraries(PrtCnvTests PRIVATE
CoPrtCnv
Qt6::Core
GTest::gtest
)
include(GoogleTest)
gtest_discover_tests(PrtCnvTests)
@@ -0,0 +1,94 @@
/**
* @file PrtCnvMemberTest.cpp
* @brief Unit tests for PrtCnv::PrtCnvMember.
*
* Covers the public state carried per member and the fragmented-telegram
* bookkeeping (collecting fragments, reporting the telegram id, clearing).
*/
#include <gtest/gtest.h>
#include <QtCore/QByteArray>
#include "PrtCnvMember.hpp"
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
#include <CoPrtCnv/tetra_telegram_ids.h>
using PrtCnv::PrtCnvMember;
using N_CoPrtCnv::CoPrtCnvRadioTelegram;
TEST(PrtCnvMemberTest, ConstructorStoresIdAndIssi)
{
const PrtCnvMember member(17, 4711);
EXPECT_EQ(member.m_Id, 17);
EXPECT_EQ(member.m_ISSI, 4711);
EXPECT_EQ(member.m_ClaimCount, 0);
EXPECT_EQ(member.m_loggedInExerciseId, 0);
EXPECT_FALSE(member.m_Licensed);
}
TEST(PrtCnvMemberTest, PublicStateIsWritable)
{
PrtCnvMember member(1, 2);
member.m_ClaimCount = 3;
member.m_loggedInExerciseId = 42;
member.m_Licensed = true;
EXPECT_EQ(member.m_ClaimCount, 3);
EXPECT_EQ(member.m_loggedInExerciseId, 42);
EXPECT_TRUE(member.m_Licensed);
}
TEST(PrtCnvMemberTest, FragmentedListStartsEmpty)
{
const PrtCnvMember member(1, 2);
EXPECT_TRUE(member.isFragmentedListEmpty());
EXPECT_TRUE(member.getUnfragmentedTelegramData().isEmpty());
}
TEST(PrtCnvMemberTest, AddingAFragmentFillsTheList)
{
PrtCnvMember member(1, 2);
const CoPrtCnvRadioTelegram fragment(GEF_GEFECHTSFELDTELEGRAMM, 8, 0);
member.addFragmentedTelegram(fragment);
EXPECT_FALSE(member.isFragmentedListEmpty());
}
TEST(PrtCnvMemberTest, ClearFragmentedListEmptiesTheList)
{
PrtCnvMember member(1, 2);
const CoPrtCnvRadioTelegram fragment(GEF_GEFECHTSFELDTELEGRAMM, 8, 0);
member.addFragmentedTelegram(fragment);
ASSERT_FALSE(member.isFragmentedListEmpty());
member.clearFragmentedList();
EXPECT_TRUE(member.isFragmentedListEmpty());
}
TEST(PrtCnvMemberTest, ClearFragmentedListIsIdempotent)
{
PrtCnvMember member(1, 2);
member.clearFragmentedList();
member.clearFragmentedList();
EXPECT_TRUE(member.isFragmentedListEmpty());
}
TEST(PrtCnvMemberTest, TelegramIdFallsBackWhenNoFirstFragmentIsPresent)
{
PrtCnvMember member(1, 2);
// A telegram built from the plain telegram-id constructor is not fragmented,
// so no entry qualifies as the first fragment of a fragmented telegram.
const CoPrtCnvRadioTelegram fragment(GEF_GEFECHTSFELDTELEGRAMM, 8, 0);
member.addFragmentedTelegram(fragment);
EXPECT_EQ(member.getFragmentedTelegramId(), GEF_BESTAETIGUNG);
}
@@ -0,0 +1,100 @@
/**
* @file PrtCnvStoredTelegramTest.cpp
* @brief Unit tests for PrtCnv::PrtCnvStoredTelegram.
*
* PrtCnvStoredTelegram is a small value holder pairing a radio telegram with
* the database bookkeeping the DB thread needs. These tests pin down its
* defaults and its copy behaviour (the telegram is shared, not cloned).
*/
#include <gtest/gtest.h>
#include <memory>
#include "PrtCnvStoredTelegram.hpp"
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
#include <CoPrtCnv/tetra_telegram_ids.h>
using PrtCnv::PrtCnvStoredTelegram;
using N_CoPrtCnv::CoPrtCnvRadioTelegram;
namespace
{
// CoPrtCnvRadioTelegram has no default constructor; the telegram-id constructor
// is the cheapest way to obtain a well-formed instance.
std::shared_ptr<CoPrtCnvRadioTelegram> makeTelegram()
{
return std::make_shared<CoPrtCnvRadioTelegram>(GEF_GEFECHTSFELDTELEGRAMM, uint16_t(8), uint16_t(0));
}
} // namespace
TEST(PrtCnvStoredTelegramTest, ConstructorStoresTelegramAndDefaults)
{
const std::shared_ptr<CoPrtCnvRadioTelegram> telegram = makeTelegram();
const PrtCnvStoredTelegram stored(telegram);
EXPECT_EQ(stored.m_RadioTelegram, telegram);
EXPECT_EQ(stored.m_Id, 0);
EXPECT_FALSE(stored.m_WriteCounterChanged);
}
TEST(PrtCnvStoredTelegramTest, CopyKeepsTheSameTelegramInstance)
{
const std::shared_ptr<CoPrtCnvRadioTelegram> telegram = makeTelegram();
PrtCnvStoredTelegram original(telegram);
original.m_Id = 123;
original.m_WriteCounterChanged = true;
const PrtCnvStoredTelegram copy(original);
EXPECT_EQ(copy.m_RadioTelegram, original.m_RadioTelegram);
EXPECT_EQ(copy.m_Id, 123);
EXPECT_TRUE(copy.m_WriteCounterChanged);
}
TEST(PrtCnvStoredTelegramTest, AssignmentCopiesEveryField)
{
const std::shared_ptr<CoPrtCnvRadioTelegram> telegram = makeTelegram();
PrtCnvStoredTelegram source(telegram);
source.m_Id = 789;
source.m_WriteCounterChanged = true;
PrtCnvStoredTelegram target(makeTelegram());
target = source;
EXPECT_EQ(target.m_RadioTelegram, telegram);
EXPECT_EQ(target.m_Id, 789);
EXPECT_TRUE(target.m_WriteCounterChanged);
}
TEST(PrtCnvStoredTelegramTest, MovingLeavesTheTargetHoldingTheTelegram)
{
const std::shared_ptr<CoPrtCnvRadioTelegram> telegram = makeTelegram();
PrtCnvStoredTelegram original(telegram);
original.m_Id = 456;
original.m_WriteCounterChanged = true;
const PrtCnvStoredTelegram moved(std::move(original));
EXPECT_EQ(moved.m_RadioTelegram, telegram);
EXPECT_EQ(moved.m_Id, 456);
EXPECT_TRUE(moved.m_WriteCounterChanged);
}
TEST(PrtCnvStoredTelegramTest, StoredTelegramKeepsTheTelegramAlive)
{
std::weak_ptr<CoPrtCnvRadioTelegram> observer;
{
PrtCnvStoredTelegram stored(makeTelegram());
observer = stored.m_RadioTelegram;
EXPECT_FALSE(observer.expired());
}
EXPECT_TRUE(observer.expired());
}
@@ -0,0 +1,27 @@
/**
* @file unittest_main.cpp
* @brief Shared entry point for the TetraIF unit test executables.
*
* GTest::gtest_main provides a main() that neither creates a QCoreApplication
* nor bootstraps the NGL root logger. The classes under test do both: they take
* a logger reference in their constructor, and NGL::NGLLoggerBootstrap throws
* NotCreatedError when the root logger has not been created yet.
*
* This mirrors tests/gtest_qt_main.cpp, minus the QApplication - none of the
* TetraIF unit tests touch widgets.
*/
#include <gtest/gtest.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QtCore/QCoreApplication>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
NGL::NGLLoggerBootstrap::createNGLRootLogger(QString(), true, QString(), /*quiet=*/true);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
@@ -1,21 +1,14 @@
#!/bin/bash
set -e
# Run CMake configuration and build inside Docker.
# Utilise l'image legatus-build:26.04 (dependances pre-installees).
# Pour la (re)construire :
# docker build -f Dockerfile.build -t legatus-build:26.04 .
# docker build -f ci/Dockerfile.ci -t legatus-build:26.04 ci
docker run --rm \
-v /home/nkana/repo/qt-migration-legatus:/workspace \
-v /home/nkana/repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/rti_license.dat:/workspace/rti_license.dat \
-v /home/nkana/repo/external/rti_connext_dds-7.7.0:/opt/rti_connext_dds-7.7.0:ro \
-w /workspace/qt6-after/qt6-migrated-legatus \
legatus-build:26.04 bash -c "
# Set RTI license, DDS path, and Qt6 path
# (deja definis dans l'image, repris ici pour rester explicite)
export RTI_LICENSE_FILE=/workspace/rti_license.dat
export DDS_PATH=/opt/rti_connext_dds-7.7.0
export CMAKE_PREFIX_PATH=/opt/Qt/6.10.2/gcc_64
# Clean and configure
rm -rf build4
@@ -1,9 +1,5 @@
#!/bin/bash
# Shell interactif dans l'image de build (dependances deja installees).
# Ne supprime PAS build4 : les artefacts deja construits restent utilisables.
#
# Si l'image n'existe pas encore :
# docker build -f Dockerfile.build -t legatus-build:26.04 .
# docker build -f ci/Dockerfile.ci -t legatus-build:26.04 ci
exec docker run --rm -it \
-v /home/nkana/repo/qt-migration-legatus:/workspace \
-v /home/nkana/repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/rti_license.dat:/workspace/rti_license.dat \
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
# Compile et lance les tests unitaires TetraIF dans l'image de build.
#
# ./docker_tetraif_tests.sh -> compile puis lance les trois suites
# ./docker_tetraif_tests.sh build -> compile seulement
# ./docker_tetraif_tests.sh run -> lance seulement (binaires deja compiles)
# ./docker_tetraif_tests.sh ctest -> lance via ctest (55 cas enregistres)
# ./docker_tetraif_tests.sh run 'PrtCnvMemberTest.*' -> sous-ensemble (filtre gtest)
#
# Prerequis : build4/ configure avec -DBUILD_RTI=ON (run ./docker_build.sh before).
MODE="${1:-all}"
FILTER="${2:-*}"
TARGETS="CoPrtCnvTests LogViewTests PrtCnvTests"
BUILD_CMD="make -j8 $TARGETS"
RUN_CMD="for t in $TARGETS; do echo \"== \$t ==\"; ./bin/\$t --gtest_filter='$FILTER'; done"
CTEST_CMD="ctest -R 'CoPrtCnv|LogView|PrtCnv' --output-on-failure"
case "$MODE" in
build) CMD="$BUILD_CMD" ;;
run) CMD="$RUN_CMD" ;;
ctest) CMD="$BUILD_CMD && $CTEST_CMD" ;;
all) CMD="$BUILD_CMD && $RUN_CMD" ;;
*) echo "usage: $0 [build|run|ctest|all] [filtre_gtest]"; exit 2 ;;
esac
docker run --rm \
-v /home/nkana/repo/qt-migration-legatus:/workspace \
-v /home/nkana/repo/qt-migration-legatus/qt6-after/qt6-migrated-legatus/rti_license.dat:/workspace/rti_license.dat \
-v /home/nkana/repo/external/rti_connext_dds-7.7.0:/opt/rti_connext_dds-7.7.0:ro \
-w /workspace/qt6-after/qt6-migrated-legatus/build4 \
legatus-build:26.04 bash -c "export QT_QPA_PLATFORM=offscreen && $CMD"