* @brief Injects a CSV frame, splitting per source when in multi-source mode. */
| 927 | * @brief Injects a CSV frame, splitting per source when in multi-source mode. |
| 928 | */ |
| 929 | void CSV::Player::injectFrame(const QByteArray& frame) |
| 930 | { |
| 931 | if (frame.isEmpty()) |
| 932 | return; |
| 933 | |
| 934 | if (!m_multiSource) { |
| 935 | IO::ConnectionManager::instance().processPayload(frame); |
| 936 | return; |
| 937 | } |
| 938 | |
| 939 | const QString row = QString::fromUtf8(frame).trimmed(); |
| 940 | const auto fields = DataModel::splitReplayRow(row); |
| 941 | |
| 942 | QMap<int, QStringList> sourceFields; |
| 943 | QSet<int> sourcesPresent; |
| 944 | for (auto it = m_sourceColumnsByIndex.constBegin(); it != m_sourceColumnsByIndex.constEnd(); |
| 945 | ++it) { |
| 946 | const int srcId = it.key(); |
| 947 | const auto& orderedCols = it.value(); |
| 948 | QStringList orderedCells; |
| 949 | orderedCells.reserve(orderedCols.size()); |
| 950 | for (int col : orderedCols) { |
| 951 | const QString cell = (col >= 0 && col < fields.size()) ? fields[col] : QString(); |
| 952 | orderedCells.append(cell); |
| 953 | if (!cell.isEmpty()) |
| 954 | sourcesPresent.insert(srcId); |
| 955 | } |
| 956 | sourceFields.insert(srcId, std::move(orderedCells)); |
| 957 | } |
| 958 | |
| 959 | QMap<int, QByteArray> sourcePayloads; |
| 960 | for (auto it = sourceFields.constBegin(); it != sourceFields.constEnd(); ++it) { |
| 961 | if (!sourcesPresent.contains(it.key())) |
| 962 | continue; |
| 963 | |
| 964 | sourcePayloads[it.key()] = DataModel::joinReplayRow(it.value()) + '\n'; |
| 965 | } |
| 966 | |
| 967 | if (sourcePayloads.isEmpty()) |
| 968 | return; |
| 969 | |
| 970 | IO::ConnectionManager::instance().processMultiSourcePayload(frame, sourcePayloads); |
| 971 | } |
| 972 | |
| 973 | //-------------------------------------------------------------------------------------------------- |
| 974 | // Event handling |
nothing calls this directly
no test coverage detected