I/O Utilities
Introduction
xpp::io::read_all and xpp::io::copy are template utility functions that work on any type with read(void*, size_t) → Promise<ssize_t> and write(const void*, size_t) → Promise<ssize_t> — duck-typed, no traits or inheritance required. Both use an 8KB buffer (matching Rust's DEFAULT_BUF_SIZE).
C++20: coroutine loops with stack buffers. C++11 + XPP_FIBER: fiber .await() loops. C++11 without fiber: struct+move fallback with xpp::Shared heap buffer.
Example — .await()
#include <xpp/io/utils.h>
xpp::EventLoop loop;
xpp::WaitScope scope(loop);
// Copy from TcpStream to File
auto stream = xpp::net::TcpStream::connect("127.0.0.1:9090").await().unwrap();
auto file = xpp::fs::File::create("output.bin").await();
xpp::io::copy(stream, file).await();
Example — co_await (C++20)
auto stream = co_await xpp::net::TcpStream::connect("127.0.0.1:9090");
auto file = co_await xpp::fs::File::create("output.bin");
co_await xpp::io::copy(stream, file);
API Reference
read_all
template <class R>
Promise<std::vector<uint8_t>> read_all(R &reader);
Reads the entire byte stream into a vector. Stops when read returns ≤ 0 (EOF or error). Uses an 8KB buffer.
The reader must have read(void*, size_t) → Promise<ssize_t>. Compatible with TcpStream, fs::File (cursor mode), and any user-defined type matching the signature.
copy
template <class R, class W>
Promise<void> copy(R &reader, W &writer);
Pipes all content from reader to writer. Uses an 8KB buffer.
The reader must have read(void*, size_t) → Promise<ssize_t>. The writer must have write(const void*, size_t) → Promise<ssize_t>.
Usage Examples
Read entire response — .await()
auto stream = xpp::net::TcpStream::connect("example.com:80").await();
stream.write("GET / HTTP/1.0\r\n\r\n", 18).await();
auto data = xpp::io::read_all(stream).await();
printf("%.*s\n", (int)data.size(), data.data());
Read entire response — co_await (C++20)
xpp::Promise<void> fetch() {
auto stream = co_await xpp::net::TcpStream::connect("example.com:80");
co_await stream.write("GET / HTTP/1.0\r\n\r\n", 18);
auto data = co_await xpp::io::read_all(stream);
printf("%.*s\n", (int)data.size(), data.data());
}
Copy from TcpStream to File — .await()
auto stream = xpp::net::TcpStream::connect("example.com:80").await();
stream.write("GET / HTTP/1.0\r\n\r\n", 18).await();
auto file = xpp::fs::File::create("response.txt").await();
xpp::io::copy(stream, file).await();
Copy from TcpStream to File — co_await (C++20)
xpp::Promise<void> download() {
auto stream = co_await xpp::net::TcpStream::connect("example.com:80");
co_await stream.write("GET / HTTP/1.0\r\n\r\n", 18);
auto file = co_await xpp::fs::File::create("response.txt");
co_await xpp::io::copy(stream, file);
}
Read from File cursor — .await()
auto file = xpp::fs::File::open("data.txt").await();
char buf[16];
ssize_t n = file.read(buf, sizeof(buf)).await(); // cursor advance
auto rest = xpp::io::read_all(file).await(); // cursor to EOF
Read from File cursor — co_await (C++20)
xpp::Promise<void> process() {
auto file = co_await xpp::fs::File::open("data.txt");
char buf[16];
ssize_t n = co_await file.read(buf, sizeof(buf));
auto rest = co_await xpp::io::read_all(file);
}