Commit 4bd3e568 authored by Aravind Anbudurai's avatar Aravind Anbudurai Committed by Facebook Github Bot 6

readFile to take in fd

Summary:
I want to be able to read from an fd into an std::string and this diffs helps
with that.

Reviewed By: yfeldblum

Differential Revision: D3654709

fbshipit-source-id: d48e8001a50f90c66cbe5b4a3b536c7b0074c39d
parent 42cd3696
......@@ -112,21 +112,17 @@ ssize_t pwritevFull(int fd, iovec* iov, int count, off_t offset);
* errno will be set appropriately by the failing system primitive.
*/
template <class Container>
bool readFile(const char* file_name, Container& out,
size_t num_bytes = std::numeric_limits<size_t>::max()) {
bool readFile(
int fd,
Container& out,
size_t num_bytes = std::numeric_limits<size_t>::max()) {
static_assert(sizeof(out[0]) == 1,
"readFile: only containers with byte-sized elements accepted");
assert(file_name);
const auto fd = openNoInt(file_name, O_RDONLY);
if (fd == -1) return false;
size_t soFar = 0; // amount of bytes successfully read
SCOPE_EXIT {
assert(out.size() >= soFar); // resize better doesn't throw
DCHECK(out.size() >= soFar); // resize better doesn't throw
out.resize(soFar);
// Ignore errors when closing the file
closeNoInt(fd);
};
// Obtain file size:
......@@ -161,6 +157,29 @@ bool readFile(const char* file_name, Container& out,
return true;
}
/**
* Same as above, but takes in a file name instead of fd
*/
template <class Container>
bool readFile(
const char* file_name,
Container& out,
size_t num_bytes = std::numeric_limits<size_t>::max()) {
DCHECK(file_name);
const auto fd = openNoInt(file_name, O_RDONLY);
if (fd == -1) {
return false;
}
SCOPE_EXIT {
// Ignore errors when closing the file
closeNoInt(fd);
};
return readFile(fd, out, num_bytes);
}
/**
* Writes container to file. The container is assumed to be
* contiguous, with element size equal to 1, and offering STL-like
......
......@@ -23,6 +23,7 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <folly/File.h>
#include <folly/Range.h>
#include <folly/String.h>
......@@ -265,16 +266,9 @@ TEST_F(FileUtilTest, preadv) {
}
TEST(String, readFile) {
srand(time(nullptr));
const string tmpPrefix = to<string>("/tmp/folly-file-util-test-",
getpid(), "-", rand(), "-");
const string afile = tmpPrefix + "myfile";
const string emptyFile = tmpPrefix + "myfile2";
SCOPE_EXIT {
unlink(afile.c_str());
unlink(emptyFile.c_str());
};
const TemporaryFile afileTemp, emptyFileTemp;
auto afile = afileTemp.path();
auto emptyFile = emptyFileTemp.path();
EXPECT_TRUE(writeFile(string(), emptyFile.c_str()));
EXPECT_TRUE(writeFile(StringPiece("bar"), afile.c_str()));
......@@ -303,4 +297,45 @@ TEST(String, readFile) {
}
}
class ReadFileFd : public ::testing::Test {
protected:
void SetUp() override {
ASSERT_TRUE(writeFile(StringPiece("bar"), aFile.path().c_str()));
}
TemporaryFile aFile;
};
TEST_F(ReadFileFd, ReadZeroBytes) {
std::string contents;
EXPECT_TRUE(readFile(aFile.fd(), contents, 0));
EXPECT_EQ("", contents);
}
TEST_F(ReadFileFd, ReadPartial) {
std::string contents;
EXPECT_TRUE(readFile(aFile.fd(), contents, 2));
EXPECT_EQ("ba", contents);
}
TEST_F(ReadFileFd, ReadFull) {
std::string contents;
EXPECT_TRUE(readFile(aFile.fd(), contents));
EXPECT_EQ("bar", contents);
}
TEST_F(ReadFileFd, WriteOnlyFd) {
File f(aFile.path().string(), O_WRONLY);
std::string contents;
EXPECT_FALSE(readFile(f.fd(), contents));
PLOG(INFO);
}
TEST_F(ReadFileFd, InvalidFd) {
File f(aFile.path().string());
f.close();
std::string contents;
EXPECT_FALSE(readFile(f.fd(), contents));
PLOG(INFO);
}
}} // namespaces
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment