• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Razakhel / RaZ / 20884103479

10 Jan 2026 08:39PM UTC coverage: 74.411% (+0.05%) from 74.364%
20884103479

push

github

Razakhel
[Network/TcpClient] Added a function receiving a minimum number of bytes

- Reading functions now use a dynamic buffer, automatically resized if necessary

- Updated license year

20 of 23 new or added lines in 4 files covered. (86.96%)

8552 of 11493 relevant lines covered (74.41%)

1720.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/RaZ/Network/TcpClient.cpp
1
#include "RaZ/Network/TcpClient.hpp"
2
#include "RaZ/Utils/Logger.hpp"
3

4
#include "asio/connect.hpp"
5
#include "asio/ip/tcp.hpp"
6
#include "asio/read.hpp"
7
#include "asio/streambuf.hpp"
8
#include "asio/write.hpp"
9

10
namespace Raz {
11

12
struct TcpClient::Impl {
13
  Impl() : socket(context), resolver(context) {}
12✔
14

15
  std::string read(const auto& readFunc, bool flush) {
5✔
16
    if (flush)
5✔
NEW
17
      buffer.consume(buffer.size());
×
18

19
    asio::error_code error;
5✔
20
    const std::size_t byteCount = readFunc(socket, buffer, error);
5✔
21

22
    if (error)
5✔
23
      throw std::runtime_error(std::format("[TcpClient] Failed to receive data: {}", error.message()));
2✔
24

25
    std::string result(static_cast<const char*>(buffer.data().data()), byteCount);
3✔
26
    buffer.consume(byteCount);
3✔
27

28
    return result;
6✔
NEW
29
  }
×
30

31
  asio::io_context context;
32
  asio::ip::tcp::socket socket;
33
  asio::ip::tcp::resolver resolver;
34
  asio::streambuf buffer;
35
};
36

37
TcpClient::TcpClient() : m_impl{ std::make_unique<Impl>() } {}
4✔
38

39
bool TcpClient::isConnected() const {
9✔
40
  return m_impl->socket.is_open();
9✔
41
}
42

43
void TcpClient::connect(const std::string& host, unsigned short port) {
4✔
44
  Logger::debug("[TcpClient] Connecting to {}:{}...", host, port);
4✔
45

46
  asio::error_code error;
4✔
47
  asio::connect(m_impl->socket, m_impl->resolver.resolve(host, std::to_string(port)), error);
4✔
48

49
  if (error)
4✔
50
    throw std::invalid_argument(std::format("[TcpClient] Failed to connect to {}:{}: {}", host, port, error.message()));
1✔
51

52
  Logger::debug("[TcpClient] Connected");
3✔
53
}
3✔
54

55
void TcpClient::send(const std::string& data) {
4✔
56
  Logger::debug("[TcpClient] Sending '{}'...", data);
4✔
57

58
  asio::error_code error;
4✔
59
  asio::write(m_impl->socket, asio::buffer(data), error);
4✔
60

61
  if (error)
4✔
62
    throw std::runtime_error(std::format("[TcpClient] Failed to send data: {}", error.message()));
1✔
63
}
3✔
64

65
std::size_t TcpClient::recoverAvailableByteCount() {
2✔
66
  asio::detail::io_control::bytes_readable command(true);
2✔
67
  m_impl->socket.io_control(command);
2✔
68
  return command.get();
2✔
69
}
70

71
std::string TcpClient::receiveAtLeast(std::size_t minByteCount, bool flush) {
5✔
72
  return m_impl->read([minByteCount] (asio::ip::tcp::socket& socket, asio::streambuf& buffer, asio::error_code& error) {
3✔
73
    // The buffer can already hold data received previously that will be returned; if necessary, reading only what is missing
74
    if (buffer.size() < minByteCount)
5✔
75
      asio::read(socket, buffer, asio::transfer_at_least(minByteCount - buffer.size()), error);
5✔
76

77
    return buffer.size();
5✔
78
  }, flush);
8✔
79
}
80

81
void TcpClient::disconnect() {
4✔
82
  if (!isConnected())
4✔
83
    return;
1✔
84

85
  Logger::debug("[TcpClient] Closing...");
3✔
86
  m_impl->socket.shutdown(asio::socket_base::shutdown_both);
3✔
87
  m_impl->socket.close();
3✔
88
  Logger::debug("[TcpClient] Closed");
6✔
89
}
90

91
TcpClient::~TcpClient() = default;
4✔
92

93
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc