27 #include <system_error>
69 socket() noexcept =
default;
77 socket(internal_::socket&& i) noexcept;
95 internal_::socket::native_handle_t
native_handle()
const noexcept;
159 template<
typename Option>
160 auto option(
const Option& ) const noexcept {
161 return Option::get(*
this);
181 template<
typename Option,
typename... Args>
183 Option::set(*
this, std::forward<Args>(args)...);
257 void close() noexcept;
281 template<typename Buffer = std::vector<uint8_t>>
282 Buffer&
read(
size_t bytes_count, Buffer&, std::error_code&) noexcept;
288 template<typename Buffer = std::vector<uint8_t>>
289 Buffer
read(
size_t bytes_count, std::error_code&) noexcept;
305 template<typename Buffer = std::vector<uint8_t>>
306 Buffer&
read_until(uint8_t delimiter, Buffer& buf, std::error_code&,
size_t max_size = 0) noexcept;
312 template<typename Buffer = std::vector<uint8_t>>
313 Buffer
read_until(uint8_t delimiter, std::error_code&,
size_t max_size = 0) noexcept;
329 template<typename Buffer = std::vector<uint8_t>>
330 size_t write(const Buffer&, std::error_code&) noexcept;
332 #ifdef __cpp_exceptions
343 template<
typename Buffer = std::vector<u
int8_t>>
344 Buffer&
read(
size_t bytes_count, Buffer&);
346 template<
typename Buffer = std::vector<u
int8_t>>
347 Buffer
read(
size_t bytes_count);
353 template<
typename Buffer = std::vector<u
int8_t>>
354 size_t write(
const Buffer&);
360 template<
typename Buffer = std::vector<u
int8_t>>
361 Buffer&
read_until(uint8_t delimiter, Buffer& buf,
size_t max_size = 0);
367 template<
typename Buffer = std::vector<u
int8_t>>
368 Buffer
read_until(uint8_t delimiter,
size_t max_size = 0);
369 #endif // ifdef __cpp_exceptions
373 internal_::socket implementation;
379 template<
typename Buffer>
380 Buffer&
socket::read(
size_t bytes_count, Buffer& output, std::error_code& ec) noexcept {
381 static_assert(
sizeof(std::remove_pointer_t<decltype(output.data())>) ==
sizeof(uint8_t),
382 "socket::read can't be used with container with non-byte elements");
384 output.resize(bytes_count);
385 size_t total_received = 0;
388 while (total_received < bytes_count) {
389 size_t bytes_received =
390 implementation.read(output.data() + total_received, bytes_count - total_received, ec);
396 total_received += bytes_received;
403 template<
typename Buffer>
404 Buffer
socket::read(
size_t bytes_count, std::error_code& ec) noexcept {
406 return read(bytes_count, buffer, ec);
409 extern template std::vector<uint8_t>
socket::read(
size_t, std::error_code&);
410 extern template std::string
socket::read(
size_t, std::error_code&);
412 extern template std::vector<uint8_t>&
socket::read(
size_t, std::vector<uint8_t>&, std::error_code&);
413 extern template std::string&
socket::read(
size_t, std::string&, std::error_code&);
415 template<
typename Buffer>
417 static_assert(
sizeof(std::remove_pointer_t<decltype(input.data())>) ==
sizeof(uint8_t),
418 "socket::write can't be used with container with non-byte elements");
420 auto res = implementation.write(input.data(), input.size(), ec);
425 extern template size_t socket::write(
const std::vector<uint8_t>&, std::error_code&);
426 extern template size_t socket::write(
const std::string&, std::error_code&);
428 template<
typename Buffer>
429 Buffer&
socket::read_until(uint8_t delimiter, Buffer& buf, std::error_code& ec,
size_t max_size) noexcept {
433 while (read(1, view, ec), !ec) {
434 if (byte == delimiter)
break;
435 if (max_size != 0 && buf.size() == max_size)
break;
441 template<
typename Buffer>
444 read_until(delimiter, buffer, ec, max_size);
448 extern template std::vector<uint8_t>
socket::read_until(uint8_t, std::error_code&,
size_t);
451 extern template std::vector<uint8_t>&
socket::read_until(uint8_t, std::vector<uint8_t>&, std::error_code&,
size_t);
452 extern template std::string&
socket::read_until(uint8_t, std::string&, std::error_code&,
size_t);
454 #ifdef __cpp_exceptions
455 template<
typename Buffer>
456 Buffer&
socket::read(
size_t bytes_count, Buffer& output) {
458 auto res = read<Buffer>(bytes_count, output, ec);
459 if (ec)
throw std::system_error(ec);
463 template<
typename Buffer>
466 return read(bytes_count, buffer);
469 extern template std::vector<uint8_t>&
socket::read(
size_t, std::vector<uint8_t>&);
470 extern template std::string&
socket::read(
size_t, std::string&);
472 extern template std::vector<uint8_t>
socket::read(
size_t);
475 template<
typename Buffer>
478 size_t res = write<Buffer>(input, ec);
479 if (ec)
throw std::system_error(ec);
483 extern template size_t socket::write(
const std::vector<uint8_t>&);
486 template<
typename Buffer>
489 read_until<Buffer>(delimiter, buf, ec, max_size);
490 if (ec)
throw std::system_error(ec);
494 template<
typename Buffer>
497 auto res = read_until<Buffer>(delimiter, ec, max_size);
498 if (ec)
throw std::system_error(ec);
502 extern template std::vector<uint8_t>&
socket::read_until(uint8_t, std::vector<uint8_t>&,
size_t);
507 #endif // ifdef __cpp_exceptions
internal_::socket::native_handle_t native_handle() const noexcept
Get native handle/descriptor for socket.
size_t write(const Buffer &, std::error_code &) noexcept
Write contents of buffer to socket.
socket() noexcept=default
Create new socket object.
auto option(const Option &) const noexcept
Query socket option value specified by type tag Option.
~socket()
Shutdown and then close socket.
Non-owning STL-like wrapper for raw memory.
bool is_open() const
Check whether underlying socket is open.
socket & operator=(const socket &)=delete
Buffer & read(size_t bytes_count, Buffer &, std::error_code &) noexcept
Read up to bytes_count bytes from socket into buffer passed by reference.
endpoint remote_endpoint() const noexcept
Get address and port of remote end of connection.
System call interrupted by signal (POSIX-specific).
endpoint local_endpoint() const noexcept
Get address and port of local end of connection.
void set_option(const Option &, Args &&...args) noexcept
Set socket option value specified by type tag Option to value value.
Buffer & read_until(uint8_t delimiter, Buffer &buf, std::error_code &, size_t max_size=0) noexcept
Read from socket until until gives byte is found or max_size bytes read.
void close() noexcept
Close and destroy underlying socket.
This header defines set of enumerations for platform-independent error code handling.
Descriptor wrapper for TCP socket.
void clear() noexcept
Same as resize (0).
Disconnected, either forcibly or gracefully.
void connect(endpoint target, std::error_code &ec) noexcept
Initialize underlying socket and connect to remote endpoint.
void shutdown(bool read=true, bool write=true) noexcept
Shutdown reading/writing part of full-duplex connection (or both if read and write is true)...