1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // Formatting library for C++ - custom Google Test assertions
- //
- // Copyright (c) 2012 - present, Victor Zverovich
- // All rights reserved.
- //
- // For the license information refer to format.h.
- #include "gtest-extra.h"
- #if FMT_USE_FCNTL
- using fmt::file;
- output_redirect::output_redirect(FILE* f) : file_(f) {
- flush();
- int fd = FMT_POSIX(fileno(f));
- // Create a file object referring to the original file.
- original_ = file::dup(fd);
- // Create a pipe.
- file write_end;
- file::pipe(read_end_, write_end);
- // Connect the passed FILE object to the write end of the pipe.
- write_end.dup2(fd);
- }
- output_redirect::~output_redirect() noexcept {
- try {
- restore();
- } catch (const std::exception& e) {
- std::fputs(e.what(), stderr);
- }
- }
- void output_redirect::flush() {
- int result = 0;
- do {
- result = fflush(file_);
- } while (result == EOF && errno == EINTR);
- if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
- }
- void output_redirect::restore() {
- if (original_.descriptor() == -1) return; // Already restored.
- flush();
- // Restore the original file.
- original_.dup2(FMT_POSIX(fileno(file_)));
- original_.close();
- }
- std::string output_redirect::restore_and_read() {
- // Restore output.
- restore();
- // Read everything from the pipe.
- std::string content;
- if (read_end_.descriptor() == -1) return content; // Already read.
- enum { BUFFER_SIZE = 4096 };
- char buffer[BUFFER_SIZE];
- size_t count = 0;
- do {
- count = read_end_.read(buffer, BUFFER_SIZE);
- content.append(buffer, count);
- } while (count != 0);
- read_end_.close();
- return content;
- }
- std::string read(file& f, size_t count) {
- std::string buffer(count, '\0');
- size_t n = 0, offset = 0;
- do {
- n = f.read(&buffer[offset], count - offset);
- // We can't read more than size_t bytes since count has type size_t.
- offset += n;
- } while (offset < count && n != 0);
- buffer.resize(offset);
- return buffer;
- }
- #endif // FMT_USE_FCNTL
|