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); ...@@ -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. * errno will be set appropriately by the failing system primitive.
*/ */
template <class Container> template <class Container>
bool readFile(const char* file_name, Container& out, bool readFile(
size_t num_bytes = std::numeric_limits<size_t>::max()) { int fd,
Container& out,
size_t num_bytes = std::numeric_limits<size_t>::max()) {
static_assert(sizeof(out[0]) == 1, static_assert(sizeof(out[0]) == 1,
"readFile: only containers with byte-sized elements accepted"); "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 size_t soFar = 0; // amount of bytes successfully read
SCOPE_EXIT { SCOPE_EXIT {
assert(out.size() >= soFar); // resize better doesn't throw DCHECK(out.size() >= soFar); // resize better doesn't throw
out.resize(soFar); out.resize(soFar);
// Ignore errors when closing the file
closeNoInt(fd);
}; };
// Obtain file size: // Obtain file size:
...@@ -161,6 +157,29 @@ bool readFile(const char* file_name, Container& out, ...@@ -161,6 +157,29 @@ bool readFile(const char* file_name, Container& out,
return true; 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 * Writes container to file. The container is assumed to be
* contiguous, with element size equal to 1, and offering STL-like * contiguous, with element size equal to 1, and offering STL-like
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <glog/logging.h> #include <glog/logging.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <folly/File.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/String.h> #include <folly/String.h>
...@@ -265,16 +266,9 @@ TEST_F(FileUtilTest, preadv) { ...@@ -265,16 +266,9 @@ TEST_F(FileUtilTest, preadv) {
} }
TEST(String, readFile) { TEST(String, readFile) {
srand(time(nullptr)); const TemporaryFile afileTemp, emptyFileTemp;
const string tmpPrefix = to<string>("/tmp/folly-file-util-test-", auto afile = afileTemp.path();
getpid(), "-", rand(), "-"); auto emptyFile = emptyFileTemp.path();
const string afile = tmpPrefix + "myfile";
const string emptyFile = tmpPrefix + "myfile2";
SCOPE_EXIT {
unlink(afile.c_str());
unlink(emptyFile.c_str());
};
EXPECT_TRUE(writeFile(string(), emptyFile.c_str())); EXPECT_TRUE(writeFile(string(), emptyFile.c_str()));
EXPECT_TRUE(writeFile(StringPiece("bar"), afile.c_str())); EXPECT_TRUE(writeFile(StringPiece("bar"), afile.c_str()));
...@@ -303,4 +297,45 @@ TEST(String, readFile) { ...@@ -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 }} // 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