Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/Progmasoft/Runner/Protocol.cpp
blob: 2bb2ff993bc2a35709ff5d7f90967fbd59c687fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright (c) 2026 Progmasoft.
// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0
#include "Protocol.hpp"

namespace Progmasoft::Catch3::Runner
{
    std::optional<std::string>
    LineReader::Next()
    {
        while (true)
        {
            const auto end = buffer_.find('\n', scanned_);
            if (end != std::string::npos)
            {
                std::string line = buffer_.substr(0, end);
                buffer_.erase(0, end + 1);
                scanned_ = 0;
                if (!line.empty() && line.back() == '\r')
                {
                    line.pop_back();
                }
                return line;
            }
            scanned_ = buffer_.size();
            if (ended_)
            {
                if (buffer_.empty())
                {
                    return std::nullopt;
                }
                // A last line without its end still counts.
                std::string line = std::move(buffer_);
                buffer_.clear();
                scanned_ = 0;
                return line;
            }
            char chunk[8192];
            const auto count = pipe_.Read(chunk, sizeof(chunk));
            if (count <= 0)
            {
                ended_ = true;
                continue;
            }
            buffer_.append(chunk, static_cast<std::size_t>(count));
        }
    }

    Status
    MessageWriter::Send(const JsonValue &message)
    {
        std::string line = message.ToString();
        line.push_back('\n');
        const std::lock_guard lock{mutex_};
        return pipe_.Write(line);
    }

    JsonValue
    Message(std::string_view kind)
    {
        JsonValue message = JsonValue::Object();
        message.Set("t", kind);
        return message;
    }
} // namespace Progmasoft::Catch3::Runner