Better read_file implementation.

GitOrigin-RevId: 63c1911f53747a3d714e7a0265e9c354b5a70d3a
This commit is contained in:
levlam 2019-12-31 02:08:57 +03:00
parent c3e7958020
commit a095a6169e
3 changed files with 35 additions and 23 deletions

View File

@ -308,4 +308,12 @@ inline MutableSlice as_slice(MutableSlice slice) {
return slice;
}
inline Slice as_slice(const string &str) {
return str;
}
inline MutableSlice as_slice(string &str) {
return str;
}
} // namespace td

View File

@ -18,8 +18,23 @@
namespace td {
// TODO remove copypaste
Result<BufferSlice> read_file(CSlice path, int64 size, int64 offset) {
namespace {
template <class T>
T create_empty(size_t size);
template <>
string create_empty<string>(size_t size) {
return string(size, '\0');
}
template <>
BufferSlice create_empty<BufferSlice>(size_t size) {
return BufferSlice{size};
}
template <class T>
Result<T> read_file_impl(CSlice path, int64 size, int64 offset) {
TRY_RESULT(from_file, FileFd::open(path, FileFd::Read));
if (size == -1) {
size = from_file.get_size();
@ -31,7 +46,7 @@ Result<BufferSlice> read_file(CSlice path, int64 size, int64 offset) {
return Status::Error("Failed to read file: invalid offset");
}
size -= offset;
BufferSlice content{narrow_cast<size_t>(size)};
auto content = create_empty<T>(narrow_cast<size_t>(size));
TRY_RESULT(got_size, from_file.pread(as_slice(content), offset));
if (got_size != static_cast<size_t>(size)) {
return Status::Error("Failed to read file");
@ -40,25 +55,14 @@ Result<BufferSlice> read_file(CSlice path, int64 size, int64 offset) {
return std::move(content);
}
Result<std::string> read_file_str(CSlice path, int64 size, int64 offset) {
TRY_RESULT(from_file, FileFd::open(path, FileFd::Read));
if (size == -1) {
size = from_file.get_size();
}
if (size < 0) {
return Status::Error("Failed to read file: invalid size");
}
if (offset < 0 || offset > size) {
return Status::Error("Failed to read file: invalid offset");
}
size -= offset;
std::string content(narrow_cast<size_t>(size), '\0');
TRY_RESULT(got_size, from_file.pread(content, offset));
if (got_size != static_cast<size_t>(size)) {
return Status::Error("Failed to read file");
}
from_file.close();
return std::move(content);
} // namespace
Result<BufferSlice> read_file(CSlice path, int64 size, int64 offset) {
return read_file_impl<BufferSlice>(path, size, offset);
}
Result<string> read_file_str(CSlice path, int64 size, int64 offset) {
return read_file_impl<string>(path, size, offset);
}
// Very straightforward function. Don't expect much of it.

View File

@ -13,7 +13,7 @@
namespace td {
Result<BufferSlice> read_file(CSlice path, int64 size = -1, int64 offset = 0);
Result<std::string> read_file_str(CSlice path, int64 size = -1, int64 offset = 0);
Result<string> read_file_str(CSlice path, int64 size = -1, int64 offset = 0);
Status copy_file(CSlice from, CSlice to, int64 size = -1) TD_WARN_UNUSED_RESULT;