From a095a6169e71d804401f55eb828f0e3c9bb572e5 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 31 Dec 2019 02:08:57 +0300 Subject: [PATCH] Better read_file implementation. GitOrigin-RevId: 63c1911f53747a3d714e7a0265e9c354b5a70d3a --- tdutils/td/utils/Slice.h | 8 ++++++ tdutils/td/utils/filesystem.cpp | 48 ++++++++++++++++++--------------- tdutils/td/utils/filesystem.h | 2 +- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/tdutils/td/utils/Slice.h b/tdutils/td/utils/Slice.h index ae8da1b7a..3e350494d 100644 --- a/tdutils/td/utils/Slice.h +++ b/tdutils/td/utils/Slice.h @@ -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 diff --git a/tdutils/td/utils/filesystem.cpp b/tdutils/td/utils/filesystem.cpp index c49c41261..888afb147 100644 --- a/tdutils/td/utils/filesystem.cpp +++ b/tdutils/td/utils/filesystem.cpp @@ -18,8 +18,23 @@ namespace td { -// TODO remove copypaste -Result read_file(CSlice path, int64 size, int64 offset) { +namespace { + +template +T create_empty(size_t size); + +template <> +string create_empty(size_t size) { + return string(size, '\0'); +} + +template <> +BufferSlice create_empty(size_t size) { + return BufferSlice{size}; +} + +template +Result 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 read_file(CSlice path, int64 size, int64 offset) { return Status::Error("Failed to read file: invalid offset"); } size -= offset; - BufferSlice content{narrow_cast(size)}; + auto content = create_empty(narrow_cast(size)); TRY_RESULT(got_size, from_file.pread(as_slice(content), offset)); if (got_size != static_cast(size)) { return Status::Error("Failed to read file"); @@ -40,25 +55,14 @@ Result read_file(CSlice path, int64 size, int64 offset) { return std::move(content); } -Result 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), '\0'); - TRY_RESULT(got_size, from_file.pread(content, offset)); - if (got_size != static_cast(size)) { - return Status::Error("Failed to read file"); - } - from_file.close(); - return std::move(content); +} // namespace + +Result read_file(CSlice path, int64 size, int64 offset) { + return read_file_impl(path, size, offset); +} + +Result read_file_str(CSlice path, int64 size, int64 offset) { + return read_file_impl(path, size, offset); } // Very straightforward function. Don't expect much of it. diff --git a/tdutils/td/utils/filesystem.h b/tdutils/td/utils/filesystem.h index afe420e5c..88be700af 100644 --- a/tdutils/td/utils/filesystem.h +++ b/tdutils/td/utils/filesystem.h @@ -13,7 +13,7 @@ namespace td { Result read_file(CSlice path, int64 size = -1, int64 offset = 0); -Result read_file_str(CSlice path, int64 size = -1, int64 offset = 0); +Result 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;