Include fmt 11.0.2
[openal-soft.git] / fmt-11.0.2 / test / gtest-extra.cc
blob0f9fff5ee231cf4cfd34deca6fd6baf27f628c3a
1 // Formatting library for C++ - custom Google Test assertions
2 //
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
5 //
6 // For the license information refer to format.h.
8 #include "gtest-extra.h"
10 #if FMT_USE_FCNTL
12 using fmt::file;
14 output_redirect::output_redirect(FILE* f, bool flush) : file_(f) {
15 if (flush) this->flush();
16 int fd = FMT_POSIX(fileno(f));
17 // Create a file object referring to the original file.
18 original_ = file::dup(fd);
19 // Create a pipe.
20 auto pipe = fmt::pipe();
21 read_end_ = std::move(pipe.read_end);
22 // Connect the passed FILE object to the write end of the pipe.
23 pipe.write_end.dup2(fd);
26 output_redirect::~output_redirect() noexcept {
27 try {
28 restore();
29 } catch (const std::exception& e) {
30 std::fputs(e.what(), stderr);
34 void output_redirect::flush() {
35 int result = 0;
36 do {
37 result = fflush(file_);
38 } while (result == EOF && errno == EINTR);
39 if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
42 void output_redirect::restore() {
43 if (original_.descriptor() == -1) return; // Already restored.
44 flush();
45 // Restore the original file.
46 original_.dup2(FMT_POSIX(fileno(file_)));
47 original_.close();
50 std::string output_redirect::restore_and_read() {
51 // Restore output.
52 restore();
54 // Read everything from the pipe.
55 std::string content;
56 if (read_end_.descriptor() == -1) return content; // Already read.
57 enum { BUFFER_SIZE = 4096 };
58 char buffer[BUFFER_SIZE];
59 size_t count = 0;
60 do {
61 count = read_end_.read(buffer, BUFFER_SIZE);
62 content.append(buffer, count);
63 } while (count != 0);
64 read_end_.close();
65 return content;
68 std::string read(file& f, size_t count) {
69 std::string buffer(count, '\0');
70 size_t n = 0, offset = 0;
71 do {
72 n = f.read(&buffer[offset], count - offset);
73 // We can't read more than size_t bytes since count has type size_t.
74 offset += n;
75 } while (offset < count && n != 0);
76 buffer.resize(offset);
77 return buffer;
80 #endif // FMT_USE_FCNTL