* @brief Frame parser dry-run: drives extraction + decoder + parser against caller bytes. */
| 5913 | * @brief Frame parser dry-run: drives extraction + decoder + parser against caller bytes. |
| 5914 | */ |
| 5915 | API::CommandResponse API::Handlers::ProjectHandler::frameParserDryRun(const QString& id, |
| 5916 | const QJsonObject& params) |
| 5917 | { |
| 5918 | if (!params.contains(QStringLiteral("code"))) |
| 5919 | return CommandResponse::makeError( |
| 5920 | id, ErrorCode::MissingParam, QStringLiteral("Missing required parameter: code")); |
| 5921 | |
| 5922 | if (!params.contains(QStringLiteral("language"))) |
| 5923 | return CommandResponse::makeError( |
| 5924 | id, ErrorCode::MissingParam, QStringLiteral("Missing required parameter: language")); |
| 5925 | |
| 5926 | if (!params.contains(QStringLiteral("inputBytes")) |
| 5927 | && !params.contains(QStringLiteral("inputBytesHex"))) |
| 5928 | return CommandResponse::makeError( |
| 5929 | id, |
| 5930 | ErrorCode::MissingParam, |
| 5931 | QStringLiteral("Missing required parameter: inputBytesHex (preferred, binary-safe) or " |
| 5932 | "inputBytes (UTF-8 text).")); |
| 5933 | |
| 5934 | const auto bytes = dryRunInputBytes(params); |
| 5935 | if (bytes.isEmpty()) |
| 5936 | return CommandResponse::makeError( |
| 5937 | id, |
| 5938 | ErrorCode::InvalidParam, |
| 5939 | QStringLiteral("inputBytes / inputBytesHex were provided but decoded to zero bytes. " |
| 5940 | "Pass the raw stream in exactly one of them: inputBytesHex as hex digits " |
| 5941 | "(e.g. '61 2C 62') or inputBytes as UTF-8 text. Empty strings count as " |
| 5942 | "absent.")); |
| 5943 | |
| 5944 | const auto code = params.value(QStringLiteral("code")).toString(); |
| 5945 | const auto language = params.value(QStringLiteral("language")).toInt(); |
| 5946 | |
| 5947 | DataModel::PipelineSpec spec; |
| 5948 | spec.operationMode = static_cast<SerialStudio::OperationMode>( |
| 5949 | params.value(QStringLiteral("operationMode")).toInt(int(SerialStudio::ProjectFile))); |
| 5950 | spec.frameDetection = static_cast<SerialStudio::FrameDetection>( |
| 5951 | params.value(Keys::FrameDetection).toInt(int(SerialStudio::EndDelimiterOnly))); |
| 5952 | spec.decoderMethod = static_cast<SerialStudio::DecoderMethod>( |
| 5953 | params.value(Keys::DecoderMethod).toInt(int(SerialStudio::PlainText))); |
| 5954 | spec.checksumAlgorithm = params.value(Keys::ChecksumAlgorithm).toString(); |
| 5955 | |
| 5956 | const bool hexDelims = params.value(Keys::HexadecimalDelimiters).toBool(false); |
| 5957 | const auto start = dryRunDelimiter(params, QString(Keys::FrameStart), hexDelims); |
| 5958 | const auto end = dryRunDelimiter(params, QString(Keys::FrameEnd), hexDelims); |
| 5959 | if (!start.isEmpty()) |
| 5960 | spec.startSequences.append(start); |
| 5961 | |
| 5962 | if (!end.isEmpty()) |
| 5963 | spec.finishSequences.append(end); |
| 5964 | |
| 5965 | if (spec.operationMode == SerialStudio::QuickPlot && spec.finishSequences.isEmpty()) { |
| 5966 | spec.finishSequences = {QByteArray("\n"), QByteArray("\r\n"), QByteArray("\r")}; |
| 5967 | spec.frameDetection = SerialStudio::EndDelimiterOnly; |
| 5968 | } |
| 5969 | |
| 5970 | const auto run = DataModel::runFrameParserPipelineWithCode(bytes, spec, code, language); |
| 5971 | if (!run.stageError.isEmpty()) { |
| 5972 | QString message = run.stageError; |
nothing calls this directly
no test coverage detected