Add ctor & print method to BufferedFile.

This commit is contained in:
Victor Zverovich 2014-08-28 11:53:05 -07:00
parent 108cd1d1a0
commit 564da25932
4 changed files with 45 additions and 2 deletions

View File

@ -70,6 +70,16 @@ fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) {
fmt::report_system_error(errno, "cannot close file");
}
fmt::BufferedFile::BufferedFile(fmt::StringRef filename, fmt::StringRef mode) {
for (;;) {
file_ = FMT_SYSTEM(fopen(filename.c_str(), mode.c_str()));
if (file_)
return;
if (errno != EINTR)
throw SystemError(errno, "cannot open file");
}
}
void fmt::BufferedFile::close() {
if (!file_)
return;

View File

@ -162,6 +162,9 @@ public:
}
#endif
// Opens a file.
BufferedFile(fmt::StringRef filename, fmt::StringRef mode);
// Closes the file.
void close();
@ -169,6 +172,11 @@ public:
FILE *get() const { return file_; }
int fileno() const;
void print(fmt::StringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
}
FMT_VARIADIC(void, print, fmt::StringRef)
};
// A file. Closed file is represented by a File object with descriptor -1.

View File

@ -50,6 +50,7 @@ int fdopen_count;
int read_count;
int write_count;
int pipe_count;
int fopen_count;
int fclose_count;
int fileno_count;
std::size_t read_nbyte;
@ -123,6 +124,11 @@ int test::pipe(int *pfds, unsigned psize, int textmode) {
}
#endif
FILE *test::fopen(const char *filename, const char *mode) {
EMULATE_EINTR(fopen, 0);
return ::fopen(filename, mode);
}
int test::fclose(FILE *stream) {
EMULATE_EINTR(fclose, EOF);
return ::fclose(stream);
@ -148,10 +154,16 @@ int test::fileno(FILE *stream) {
# define EXPECT_EQ_POSIX(expected, actual)
#endif
void write_file(fmt::StringRef filename, fmt::StringRef content) {
fmt::BufferedFile f(filename, "w");
fmt::print(f.get(), "{}", content);
}
TEST(FileTest, OpenRetry) {
write_file("test", "there must be something here");
File *f = 0;
EXPECT_RETRY(f = new File("CMakeLists.txt", File::RDONLY),
open, "cannot open file CMakeLists.txt");
EXPECT_RETRY(f = new File("test", File::RDONLY),
open, "cannot open file test");
#ifndef _WIN32
char c = 0;
f->read(&c, 1);
@ -289,6 +301,18 @@ TEST(FileTest, FdopenNoRetry) {
fdopen_count = 0;
}
TEST(BufferedFileTest, OpenRetry) {
write_file("test", "there must be something here");
BufferedFile *f = 0;
EXPECT_RETRY(f = new BufferedFile("test", "r"),
fopen, "cannot open file test");
#ifndef _WIN32
char c = 0;
fread(&c, 1, 1, f->get());
#endif
delete f;
}
TEST(BufferedFileTest, CloseNoRetryInDtor) {
File read_end, write_end;
File::pipe(read_end, write_end);

View File

@ -61,6 +61,7 @@ int pipe(int fildes[2]);
int pipe(int *pfds, unsigned psize, int textmode);
#endif
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
int fileno(FILE *stream);