Combine InputFile and OutputFile into a single class.

PiperOrigin-RevId: 426172033
This commit is contained in:
jfcarroll
2022-02-03 09:57:50 -08:00
committed by Copybara-Service
parent fa02d255e3
commit 9abc9a59b9
14 changed files with 115 additions and 109 deletions
+1
View File
@@ -69,6 +69,7 @@ cc_library(
"//internal/platform/implementation/ios:__subpackages__",
],
deps = [
"//base",
"//internal/platform:base",
"//internal/platform:types",
"//internal/platform:util",
+1
View File
@@ -90,6 +90,7 @@ cc_library(
],
deps = [
":message_lite",
"//base",
"//connections:core_types",
"//connections/implementation/mediums",
"//connections/implementation/mediums:utils",
@@ -103,13 +103,13 @@ std::unique_ptr<AtomicBoolean> ImplementationPlatform::CreateAtomicBoolean(
std::unique_ptr<InputFile> ImplementationPlatform::CreateInputFile(
PayloadId payload_id, std::int64_t total_size) {
return absl::make_unique<shared::InputFile>(GetPayloadPath(payload_id),
total_size);
return shared::IOFile::CreateInputFile(GetPayloadPath(payload_id),
total_size);
}
std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
PayloadId payload_id) {
return absl::make_unique<shared::OutputFile>(GetPayloadPath(payload_id));
return shared::IOFile::CreateOutputFile(GetPayloadPath(payload_id));
}
std::unique_ptr<LogMessage> ImplementationPlatform::CreateLogMessage(
@@ -88,12 +88,12 @@ std::unique_ptr<InputFile> ImplementationPlatform::CreateInputFile(PayloadId pay
if (url != nil) {
return absl::make_unique<ios::InputFile>(url);
} else {
return absl::make_unique<shared::InputFile>(GetPayloadPath(payload_id), total_size);
return shared::IOFile::CreateInputFile(GetPayloadPath(payload_id), total_size);
}
}
std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(PayloadId payload_id) {
return absl::make_unique<shared::OutputFile>(GetPayloadPath(payload_id));
return shared::IOFile::CreateOutputFile(GetPayloadPath(payload_id));
}
std::unique_ptr<LogMessage> ImplementationPlatform::CreateLogMessage(
@@ -51,6 +51,7 @@ cc_library(
deps = [
"//internal/platform:base",
"//internal/platform/implementation:types",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/strings",
],
)
+23 -18
View File
@@ -17,6 +17,7 @@
#include <cstddef>
#include <memory>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "internal/platform/exception.h"
@@ -25,11 +26,27 @@ namespace nearby {
namespace shared {
// InputFile
std::unique_ptr<IOFile> IOFile::CreateInputFile(const absl::string_view path,
size_t size) {
return absl::WrapUnique(new IOFile(path, size));
}
InputFile::InputFile(const std::string& path, std::int64_t size)
: file_(path, std::ios::binary), path_(path), total_size_(size) {}
IOFile::IOFile(const absl::string_view path, size_t size)
: file_(std::string(path.data(), path.size()),
std::ios::binary | std::ios::in),
path_(path),
total_size_(size) {}
ExceptionOr<ByteArray> InputFile::Read(std::int64_t size) {
std::unique_ptr<IOFile> IOFile::CreateOutputFile(const absl::string_view path) {
return std::unique_ptr<IOFile>(new IOFile(path));
}
IOFile::IOFile(const absl::string_view path)
: file_(std::string(path.data(), path.size()),
std::ios::binary | std::ios::out | std::ios::trunc),
total_size_(0) {}
ExceptionOr<ByteArray> IOFile::Read(std::int64_t size) {
if (!file_.is_open()) {
return ExceptionOr<ByteArray>{Exception::kIo};
}
@@ -53,19 +70,14 @@ ExceptionOr<ByteArray> InputFile::Read(std::int64_t size) {
return ExceptionOr<ByteArray>(ByteArray(read_bytes.get(), num_bytes_read));
}
Exception InputFile::Close() {
Exception IOFile::Close() {
if (file_.is_open()) {
file_.close();
}
return {Exception::kSuccess};
}
// OutputFile
OutputFile::OutputFile(absl::string_view path)
: file_(std::string(path), std::ios::binary) {}
Exception OutputFile::Write(const ByteArray& data) {
Exception IOFile::Write(const ByteArray& data) {
if (!file_.is_open()) {
return {Exception::kIo};
}
@@ -79,18 +91,11 @@ Exception OutputFile::Write(const ByteArray& data) {
return {file_.good() ? Exception::kSuccess : Exception::kIo};
}
Exception OutputFile::Flush() {
Exception IOFile::Flush() {
file_.flush();
return {file_.good() ? Exception::kSuccess : Exception::kIo};
}
Exception OutputFile::Close() {
if (file_.is_open()) {
file_.close();
}
return {Exception::kSuccess};
}
} // namespace shared
} // namespace nearby
} // namespace location
+12 -21
View File
@@ -27,37 +27,28 @@ namespace location {
namespace nearby {
namespace shared {
class InputFile final : public api::InputFile {
class IOFile final : public api::InputFile, public api::OutputFile {
public:
explicit InputFile(const std::string& path, std::int64_t size);
~InputFile() override = default;
InputFile(InputFile&&) = default;
InputFile& operator=(InputFile&&) = default;
static std::unique_ptr<IOFile> CreateInputFile(const absl::string_view path,
size_t size);
static std::unique_ptr<IOFile> CreateOutputFile(const absl::string_view path);
ExceptionOr<ByteArray> Read(std::int64_t size) override;
std::string GetFilePath() const override { return path_; }
std::string GetFilePath() const override {
return std::string(path_.data(), path_.size());
}
std::int64_t GetTotalSize() const override { return total_size_; }
Exception Close() override;
private:
std::ifstream file_;
std::string path_;
std::int64_t total_size_;
};
class OutputFile final : public api::OutputFile {
public:
explicit OutputFile(absl::string_view path);
~OutputFile() override = default;
OutputFile(OutputFile&&) = default;
OutputFile& operator=(OutputFile&&) = default;
Exception Write(const ByteArray& data) override;
Exception Flush() override;
Exception Close() override;
private:
std::ofstream file_;
explicit IOFile(const absl::string_view path, size_t size);
explicit IOFile(const absl::string_view path);
std::fstream file_;
absl::string_view path_;
std::int64_t total_size_;
};
} // namespace shared
@@ -64,83 +64,84 @@ class FileTest : public ::testing::Test {
size_t size_ = 0;
};
TEST_F(FileTest, InputFile_NonExistentPath) {
InputFile input_file("/not/a/valid/path.txt", GetSize());
ExceptionOr<ByteArray> read_result = input_file.Read(kMaxSize);
TEST_F(FileTest, IOFile_NonExistentPathInput) {
auto io_file =
shared::IOFile::CreateInputFile("/not/a/valid/path.txt", GetSize());
ExceptionOr<ByteArray> read_result = io_file->Read(kMaxSize);
EXPECT_FALSE(read_result.ok());
EXPECT_TRUE(read_result.GetException().Raised(Exception::kIo));
}
TEST_F(FileTest, InputFile_GetFilePath) {
InputFile input_file(path_, GetSize());
EXPECT_EQ(input_file.GetFilePath(), path_);
TEST_F(FileTest, IOFile_GetFilePath) {
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
EXPECT_EQ(io_file->GetFilePath(), path_);
}
TEST_F(FileTest, InputFile_EmptyFileEOF) {
InputFile input_file(path_, GetSize());
AssertEmpty(input_file.Read(kMaxSize));
TEST_F(FileTest, IOFile_EmptyFileEOF) {
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
AssertEmpty(io_file->Read(kMaxSize));
}
TEST_F(FileTest, InputFile_ReadWorks) {
TEST_F(FileTest, IOFile_ReadWorks) {
WriteToFile("abc");
InputFile input_file(path_, GetSize());
input_file.Read(kMaxSize);
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
io_file->Read(kMaxSize);
SUCCEED();
}
TEST_F(FileTest, InputFile_ReadUntilEOF) {
TEST_F(FileTest, IOFile_ReadUntilEOF) {
WriteToFile("abc");
InputFile input_file(path_, GetSize());
AssertEquals(input_file.Read(kMaxSize), "abc");
AssertEmpty(input_file.Read(kMaxSize));
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
AssertEquals(io_file->Read(kMaxSize), "abc");
AssertEmpty(io_file->Read(kMaxSize));
}
TEST_F(FileTest, InputFile_ReadWithSize) {
TEST_F(FileTest, IOFile_ReadWithSize) {
WriteToFile("abc");
InputFile input_file(path_, GetSize());
AssertEquals(input_file.Read(2), "ab");
AssertEquals(input_file.Read(1), "c");
AssertEmpty(input_file.Read(kMaxSize));
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
AssertEquals(io_file->Read(2), "ab");
AssertEquals(io_file->Read(1), "c");
AssertEmpty(io_file->Read(kMaxSize));
}
TEST_F(FileTest, InputFile_GetTotalSize) {
TEST_F(FileTest, IOFile_GetTotalSize) {
WriteToFile("abc");
InputFile input_file(path_, GetSize());
EXPECT_EQ(input_file.GetTotalSize(), 3);
AssertEquals(input_file.Read(1), "a");
EXPECT_EQ(input_file.GetTotalSize(), 3);
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
EXPECT_EQ(io_file->GetTotalSize(), 3);
AssertEquals(io_file->Read(1), "a");
EXPECT_EQ(io_file->GetTotalSize(), 3);
}
TEST_F(FileTest, InputFile_Close) {
TEST_F(FileTest, IOFile_CloseInput) {
WriteToFile("abc");
InputFile input_file(path_, GetSize());
input_file.Close();
ExceptionOr<ByteArray> read_result = input_file.Read(kMaxSize);
auto io_file = shared::IOFile::CreateInputFile(path_, GetSize());
io_file->Close();
ExceptionOr<ByteArray> read_result = io_file->Read(kMaxSize);
EXPECT_FALSE(read_result.ok());
EXPECT_TRUE(read_result.GetException().Raised(Exception::kIo));
}
TEST_F(FileTest, OutputFile_NonExistentPath) {
OutputFile output_file("/not/a/valid/path.txt");
TEST_F(FileTest, IOFile_NonExistentPathOutput) {
auto io_file = shared::IOFile::CreateOutputFile("/not/a/valid/path.txt");
ByteArray bytes("a", 1);
EXPECT_TRUE(output_file.Write(bytes).Raised(Exception::kIo));
EXPECT_TRUE(io_file->Write(bytes).Raised(Exception::kIo));
}
TEST_F(FileTest, OutputFile_Write) {
OutputFile output_file(path_);
TEST_F(FileTest, IOFile_Write) {
auto io_file_output = shared::IOFile::CreateOutputFile(path_);
ByteArray bytes1("a");
ByteArray bytes2("bc");
EXPECT_EQ(output_file.Write(bytes1), Exception{Exception::kSuccess});
EXPECT_EQ(output_file.Write(bytes2), Exception{Exception::kSuccess});
InputFile input_file(path_, GetSize());
AssertEquals(input_file.Read(kMaxSize), "abc");
EXPECT_EQ(io_file_output->Write(bytes1), Exception{Exception::kSuccess});
EXPECT_EQ(io_file_output->Write(bytes2), Exception{Exception::kSuccess});
auto io_file_input = shared::IOFile::CreateInputFile(path_, GetSize());
AssertEquals(io_file_input->Read(kMaxSize), "abc");
}
TEST_F(FileTest, OutputFile_Close) {
OutputFile output_file(path_);
output_file.Close();
TEST_F(FileTest, IOFile_CloseOutput) {
auto io_file = shared::IOFile::CreateOutputFile(path_);
io_file->Close();
ByteArray bytes("a");
EXPECT_EQ(output_file.Write(bytes), Exception{Exception::kIo});
EXPECT_EQ(io_file->Write(bytes), Exception{Exception::kIo});
}
} // namespace shared
@@ -382,8 +382,8 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
winrt::Windows::Foundation::AsyncStatus status) {
EnterCriticalSection(&critical_section_);
std::unique_ptr<BluetoothDevice> bluetoothDeviceP =
std::make_unique<BluetoothDevice>(bluetoothDevice.get());
auto bluetoothDeviceP =
absl::WrapUnique(new BluetoothDevice(bluetoothDevice.get()));
discovered_devices_by_id_[deviceInfo.Id()] =
std::move(bluetoothDeviceP);
@@ -50,7 +50,7 @@ class ConditionVariableTests : public testing::Test {
}
void PostEvent() {
std::lock_guard<std::mutex> guard(mutex_actual_.GetWindowsMutex());
absl::MutexLock::MutexLock(&mutex_actual_.GetMutex());
condition_variable_actual_.Notify();
}
@@ -56,6 +56,9 @@ class ABSL_LOCKABLE Mutex : public api::Mutex {
}
}
absl::Mutex& GetMutex() { return mutex_; }
std::recursive_mutex& GetRecursiveMutex() { return recursive_mutex_; }
private:
friend class ConditionVariable;
absl::Mutex mutex_;
@@ -14,7 +14,7 @@
#include "internal/platform/implementation/windows/mutex.h"
#include <future> // NOLINT
#include <future> // NOLINT
#include "gtest/gtest.h"
@@ -24,18 +24,17 @@ class MutexTests : public testing::Test {
public:
MutexTest(location::nearby::windows::Mutex& mutex) : mutex_(mutex) {}
std::future<bool> WaitForLock() { // NOLINT
return std::async(
std::launch::async,
// for this lambda you need C++14
[this]() mutable {
std::unique_lock<std::mutex> lck(mutex_.GetWindowsMutex());
return true;
});
std::future<bool> WaitForLock() { // NOLINT
return std::async(std::launch::async,
// for this lambda you need C++14
[this]() mutable {
absl::MutexLock::MutexLock(&mutex_.GetMutex());
return true;
});
}
void PostEvent() {
std::lock_guard<std::mutex> guard(mutex_.GetWindowsMutex());
absl::MutexLock::MutexLock(&mutex_.GetMutex());
mutex_.Unlock();
}
@@ -50,7 +49,7 @@ TEST_F(MutexTests, SuccessfulRecursiveCreation) {
location::nearby::windows::Mutex::Mode::kRecursive);
// Act
std::recursive_mutex& actual = mutex.GetWindowsRecursiveMutex();
std::recursive_mutex& actual = mutex.GetRecursiveMutex();
// Assert
ASSERT_TRUE(actual.native_handle() != nullptr);
@@ -62,10 +61,10 @@ TEST_F(MutexTests, SuccessfulCreation) {
location::nearby::windows::Mutex::Mode::kRegular);
// Act
std::mutex& actual = mutex.GetWindowsMutex();
absl::Mutex& actual = mutex.GetMutex();
// Assert
ASSERT_TRUE(actual.native_handle() != nullptr);
ASSERT_TRUE(&actual != nullptr);
}
TEST_F(MutexTests, SuccessfulSignal) {
@@ -98,13 +98,13 @@ ImplementationPlatform::CreateConditionVariable(Mutex* mutex) {
std::unique_ptr<InputFile> ImplementationPlatform::CreateInputFile(
PayloadId payload_id, std::int64_t total_size) {
return absl::make_unique<shared::InputFile>(GetPayloadPath(payload_id),
total_size);
return shared::IOFile::CreateInputFile(GetPayloadPath(payload_id),
total_size);
}
std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
PayloadId payload_id) {
return absl::make_unique<shared::OutputFile>(GetPayloadPath(payload_id));
return shared::IOFile::CreateOutputFile(GetPayloadPath(payload_id));
}
// TODO(b/184975123): replace with real implementation.
@@ -48,10 +48,14 @@ std::string GetPayloadPath(location::nearby::PayloadId payload_id) {
// is no longer needed by calling CoTaskMemFree, whether
// SHGetKnownFolderPath succeeds or not.
char* fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char));
wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char));
size_t bufferSize;
wcstombs_s(&bufferSize, NULL, 0, basePath, 0);
char* fullpathUTF8 = new char[bufferSize + 1];
memset(fullpathUTF8, 0, bufferSize);
wcstombs_s(&bufferSize, fullpathUTF8, bufferSize, basePath, bufferSize - 1);
std::string fullPath = std::string(fullpathUTF8);
auto retval = absl::StrCat(fullPath += "/", payload_id);
auto retval = absl::StrCat(fullPath += "\\", payload_id);
delete[] fullpathUTF8;
return retval;
}
} // namespace test_utils