#include namespace psemek::io { std::size_t istream::read_all(char * p, std::size_t size) { auto left = size; while (left > 0) { auto s = read(p, left); if (s == 0) throw istream_end{}; p += s; left -= s; } return size; } std::size_t ostream::write_all(char const * p, std::size_t size) { auto left = size; while (left > 0) { auto s = write(p, left); if (s == 0) throw ostream_end{}; p += s; left -= s; } return size; } std::unique_ptr std_in() { return std::make_unique(stdin); } std::unique_ptr std_out() { return std::make_unique(stdout); } std::unique_ptr std_err() { return std::make_unique(stderr); } util::blob read_full(istream && stream) { std::size_t allocated = 0; std::size_t size = 0; std::unique_ptr data; while (true) { if (!data) { allocated = 16; data.reset(new char[allocated]); } else if (size == allocated) { allocated *= 2; std::unique_ptr new_data(new char[allocated]); std::copy(data.get(), data.get() + size, new_data.get()); data = std::move(new_data); } std::size_t count = stream.read(data.get() + size, allocated - size); if (count == 0) break; size += count; } return util::blob(size, std::move(data)); } }