Reland "Trim down FileWrapper class to be merely a wrapper owning a FILE*"
This is a reland of 80b95de7651caa0cfeb684ffc200860989f667dc
Original change's description:
> Trim down FileWrapper class to be merely a wrapper owning a FILE*
>
> Bug: webrtc:6463
> Change-Id: If71e2f3a75dc1863bc805ab71de1e2d33294f805
> Reviewed-on: https://webrtc-review.googlesource.com/c/117881
> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> Reviewed-by: Alex Loiko <aleloi@webrtc.org>
> Commit-Queue: Niels Moller <nisse@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26311}
Bug: webrtc:6463
Change-Id: I12154ef65744c1b7811974a1d871e05ed3fbbc27
Reviewed-on: https://webrtc-review.googlesource.com/c/118660
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26337}
diff --git a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
index 8e04e8e..956d790 100644
--- a/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
+++ b/modules/audio_coding/audio_network_adaptor/debug_dump_writer.cc
@@ -67,14 +67,13 @@
#endif
private:
- std::unique_ptr<FileWrapper> dump_file_;
+ FileWrapper dump_file_;
};
-DebugDumpWriterImpl::DebugDumpWriterImpl(FILE* file_handle)
- : dump_file_(FileWrapper::Create()) {
+DebugDumpWriterImpl::DebugDumpWriterImpl(FILE* file_handle) {
#if WEBRTC_ENABLE_PROTOBUF
- dump_file_->OpenFromFileHandle(file_handle);
- RTC_CHECK(dump_file_->is_open());
+ dump_file_ = FileWrapper(file_handle);
+ RTC_CHECK(dump_file_.is_open());
#else
RTC_NOTREACHED();
#endif
@@ -110,7 +109,7 @@
*metrics.uplink_recoverable_packet_loss_fraction);
}
- DumpEventToFile(event, dump_file_.get());
+ DumpEventToFile(event, &dump_file_);
#endif // WEBRTC_ENABLE_PROTOBUF
}
@@ -143,7 +142,7 @@
if (config.num_channels)
dump_config->set_num_channels(*config.num_channels);
- DumpEventToFile(event, dump_file_.get());
+ DumpEventToFile(event, &dump_file_);
#endif // WEBRTC_ENABLE_PROTOBUF
}
@@ -157,7 +156,7 @@
event.set_type(Event::CONTROLLER_MANAGER_CONFIG);
event.mutable_controller_manager_config()->CopyFrom(
controller_manager_config);
- DumpEventToFile(event, dump_file_.get());
+ DumpEventToFile(event, &dump_file_);
}
#endif // WEBRTC_ENABLE_PROTOBUF
diff --git a/modules/audio_device/dummy/file_audio_device.cc b/modules/audio_device/dummy/file_audio_device.cc
index ea736e0..c5bdb3b 100644
--- a/modules/audio_device/dummy/file_audio_device.cc
+++ b/modules/audio_device/dummy/file_audio_device.cc
@@ -43,15 +43,10 @@
_recording(false),
_lastCallPlayoutMillis(0),
_lastCallRecordMillis(0),
- _outputFile(*FileWrapper::Create()),
- _inputFile(*FileWrapper::Create()),
_outputFilename(outputFilename),
_inputFilename(inputFilename) {}
-FileAudioDevice::~FileAudioDevice() {
- delete &_outputFile;
- delete &_inputFile;
-}
+FileAudioDevice::~FileAudioDevice() {}
int32_t FileAudioDevice::ActiveAudioLayer(
AudioDeviceModule::AudioLayer& audioLayer) const {
@@ -210,13 +205,15 @@
}
// PLAYOUT
- if (!_outputFilename.empty() &&
- !_outputFile.OpenFile(_outputFilename.c_str(), false)) {
- RTC_LOG(LS_ERROR) << "Failed to open playout file: " << _outputFilename;
- _playing = false;
- delete[] _playoutBuffer;
- _playoutBuffer = NULL;
- return -1;
+ if (!_outputFilename.empty()) {
+ _outputFile = FileWrapper::OpenWriteOnly(_outputFilename.c_str());
+ if (!_outputFile.is_open()) {
+ RTC_LOG(LS_ERROR) << "Failed to open playout file: " << _outputFilename;
+ _playing = false;
+ delete[] _playoutBuffer;
+ _playoutBuffer = NULL;
+ return -1;
+ }
}
_ptrThreadPlay.reset(new rtc::PlatformThread(
@@ -246,7 +243,7 @@
_playoutFramesLeft = 0;
delete[] _playoutBuffer;
_playoutBuffer = NULL;
- _outputFile.CloseFile();
+ _outputFile.Close();
RTC_LOG(LS_INFO) << "Stopped playout capture to output file: "
<< _outputFilename;
@@ -267,13 +264,16 @@
_recordingBuffer = new int8_t[_recordingBufferSizeIn10MS];
}
- if (!_inputFilename.empty() &&
- !_inputFile.OpenFile(_inputFilename.c_str(), true)) {
- RTC_LOG(LS_ERROR) << "Failed to open audio input file: " << _inputFilename;
- _recording = false;
- delete[] _recordingBuffer;
- _recordingBuffer = NULL;
- return -1;
+ if (!_inputFilename.empty()) {
+ _inputFile = FileWrapper::OpenReadOnly(_inputFilename.c_str());
+ if (!_inputFile.is_open()) {
+ RTC_LOG(LS_ERROR) << "Failed to open audio input file: "
+ << _inputFilename;
+ _recording = false;
+ delete[] _recordingBuffer;
+ _recordingBuffer = NULL;
+ return -1;
+ }
}
_ptrThreadRec.reset(new rtc::PlatformThread(
@@ -304,7 +304,7 @@
delete[] _recordingBuffer;
_recordingBuffer = NULL;
}
- _inputFile.CloseFile();
+ _inputFile.Close();
RTC_LOG(LS_INFO) << "Stopped recording from input file: " << _inputFilename;
return 0;
diff --git a/modules/audio_device/dummy/file_audio_device.h b/modules/audio_device/dummy/file_audio_device.h
index 375c6f6..85dce07 100644
--- a/modules/audio_device/dummy/file_audio_device.h
+++ b/modules/audio_device/dummy/file_audio_device.h
@@ -154,8 +154,8 @@
int64_t _lastCallPlayoutMillis;
int64_t _lastCallRecordMillis;
- FileWrapper& _outputFile;
- FileWrapper& _inputFile;
+ FileWrapper _outputFile;
+ FileWrapper _inputFile;
std::string _outputFilename;
std::string _inputFilename;
};
diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.cc b/modules/audio_processing/aec_dump/aec_dump_impl.cc
index 9020f2b..588d24d 100644
--- a/modules/audio_processing/aec_dump/aec_dump_impl.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_impl.cc
@@ -55,7 +55,7 @@
} // namespace
-AecDumpImpl::AecDumpImpl(std::unique_ptr<FileWrapper> debug_file,
+AecDumpImpl::AecDumpImpl(FileWrapper debug_file,
int64_t max_log_size_bytes,
rtc::TaskQueue* worker_queue)
: debug_file_(std::move(debug_file)),
@@ -196,7 +196,7 @@
}
std::unique_ptr<WriteToFileTask> AecDumpImpl::CreateWriteToFileTask() {
- return absl::make_unique<WriteToFileTask>(debug_file_.get(),
+ return absl::make_unique<WriteToFileTask>(&debug_file_,
&num_bytes_left_for_log_);
}
@@ -204,24 +204,20 @@
int64_t max_log_size_bytes,
rtc::TaskQueue* worker_queue) {
RTC_DCHECK(worker_queue);
- std::unique_ptr<FileWrapper> debug_file(FileWrapper::Create());
FILE* handle = rtc::FdopenPlatformFileForWriting(file);
if (!handle) {
return nullptr;
}
- if (!debug_file->OpenFromFileHandle(handle)) {
- return nullptr;
- }
- return absl::make_unique<AecDumpImpl>(std::move(debug_file),
- max_log_size_bytes, worker_queue);
+ return absl::make_unique<AecDumpImpl>(FileWrapper(handle), max_log_size_bytes,
+ worker_queue);
}
std::unique_ptr<AecDump> AecDumpFactory::Create(std::string file_name,
int64_t max_log_size_bytes,
rtc::TaskQueue* worker_queue) {
RTC_DCHECK(worker_queue);
- std::unique_ptr<FileWrapper> debug_file(FileWrapper::Create());
- if (!debug_file->OpenFile(file_name.c_str(), false)) {
+ FileWrapper debug_file = FileWrapper::OpenWriteOnly(file_name.c_str());
+ if (!debug_file.is_open()) {
return nullptr;
}
return absl::make_unique<AecDumpImpl>(std::move(debug_file),
@@ -233,11 +229,7 @@
rtc::TaskQueue* worker_queue) {
RTC_DCHECK(worker_queue);
RTC_DCHECK(handle);
- std::unique_ptr<FileWrapper> debug_file(FileWrapper::Create());
- if (!debug_file->OpenFromFileHandle(handle)) {
- return nullptr;
- }
- return absl::make_unique<AecDumpImpl>(std::move(debug_file),
- max_log_size_bytes, worker_queue);
+ return absl::make_unique<AecDumpImpl>(FileWrapper(handle), max_log_size_bytes,
+ worker_queue);
}
} // namespace webrtc
diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.h b/modules/audio_processing/aec_dump/aec_dump_impl.h
index df949ca..c247c1b 100644
--- a/modules/audio_processing/aec_dump/aec_dump_impl.h
+++ b/modules/audio_processing/aec_dump/aec_dump_impl.h
@@ -46,7 +46,7 @@
class AecDumpImpl : public AecDump {
public:
// Does member variables initialization shared across all c-tors.
- AecDumpImpl(std::unique_ptr<FileWrapper> debug_file,
+ AecDumpImpl(FileWrapper debug_file,
int64_t max_log_size_bytes,
rtc::TaskQueue* worker_queue);
@@ -73,7 +73,7 @@
private:
std::unique_ptr<WriteToFileTask> CreateWriteToFileTask();
- std::unique_ptr<FileWrapper> debug_file_;
+ FileWrapper debug_file_;
int64_t num_bytes_left_for_log_ = 0;
rtc::RaceChecker race_checker_;
rtc::TaskQueue* worker_queue_;
diff --git a/modules/audio_processing/aec_dump/write_to_file_task.cc b/modules/audio_processing/aec_dump/write_to_file_task.cc
index 8dddd47..d11f10b 100644
--- a/modules/audio_processing/aec_dump/write_to_file_task.cc
+++ b/modules/audio_processing/aec_dump/write_to_file_task.cc
@@ -39,17 +39,15 @@
}
bool WriteToFileTask::Run() {
- if (!debug_file_->is_open()) {
- return true;
- }
-
ProtoString event_string;
event_.SerializeToString(&event_string);
const size_t event_byte_size = event_.ByteSizeLong();
if (!IsRoomForNextEvent(event_byte_size)) {
- debug_file_->CloseFile();
+ // Ensure that no further events are written, even if they're smaller than
+ // the current event.
+ *num_bytes_left_for_log_ = 0;
return true;
}
diff --git a/modules/audio_processing/aec_dump/write_to_file_task.h b/modules/audio_processing/aec_dump/write_to_file_task.h
index 711afb2..4b04a45 100644
--- a/modules/audio_processing/aec_dump/write_to_file_task.h
+++ b/modules/audio_processing/aec_dump/write_to_file_task.h
@@ -48,9 +48,9 @@
bool Run() override;
- webrtc::FileWrapper* debug_file_;
+ webrtc::FileWrapper* const debug_file_;
audioproc::Event event_;
- int64_t* num_bytes_left_for_log_;
+ int64_t* const num_bytes_left_for_log_;
};
} // namespace webrtc
diff --git a/modules/audio_processing/transient/click_annotate.cc b/modules/audio_processing/transient/click_annotate.cc
index ce646b5..21641f8 100644
--- a/modules/audio_processing/transient/click_annotate.cc
+++ b/modules/audio_processing/transient/click_annotate.cc
@@ -39,16 +39,14 @@
return 0;
}
- std::unique_ptr<FileWrapper> pcm_file(FileWrapper::Create());
- pcm_file->OpenFile(argv[1], true);
- if (!pcm_file->is_open()) {
+ FileWrapper pcm_file = FileWrapper::OpenReadOnly(argv[1]);
+ if (!pcm_file.is_open()) {
printf("\nThe %s could not be opened.\n\n", argv[1]);
return -1;
}
- std::unique_ptr<FileWrapper> dat_file(FileWrapper::Create());
- dat_file->OpenFile(argv[2], false);
- if (!dat_file->is_open()) {
+ FileWrapper dat_file = FileWrapper::OpenWriteOnly(argv[2]);
+ if (!dat_file.is_open()) {
printf("\nThe %s could not be opened.\n\n", argv[2]);
return -1;
}
@@ -73,7 +71,7 @@
// Read first buffer from the PCM test file.
size_t file_samples_read = ReadInt16FromFileToFloatBuffer(
- pcm_file.get(), audio_buffer_length, audio_buffer.get());
+ &pcm_file, audio_buffer_length, audio_buffer.get());
for (int time = 0; file_samples_read > 0; time += chunk_size_ms) {
// Pad the rest of the buffer with zeros.
for (size_t i = file_samples_read; i < audio_buffer_length; ++i) {
@@ -91,19 +89,19 @@
// Read next buffer from the PCM test file.
file_samples_read = ReadInt16FromFileToFloatBuffer(
- pcm_file.get(), audio_buffer_length, audio_buffer.get());
+ &pcm_file, audio_buffer_length, audio_buffer.get());
}
size_t floats_written =
- WriteFloatBufferToFile(dat_file.get(), send_times.size(), &send_times[0]);
+ WriteFloatBufferToFile(&dat_file, send_times.size(), &send_times[0]);
if (floats_written == 0) {
printf("\nThe send times could not be written to DAT file\n\n");
return -1;
}
- pcm_file->CloseFile();
- dat_file->CloseFile();
+ pcm_file.Close();
+ dat_file.Close();
return lost_packets;
}
diff --git a/modules/audio_processing/transient/file_utils_unittest.cc b/modules/audio_processing/transient/file_utils_unittest.cc
index ced06b1..0bded02 100644
--- a/modules/audio_processing/transient/file_utils_unittest.cc
+++ b/modules/audio_processing/transient/file_utils_unittest.cc
@@ -158,22 +158,20 @@
TEST_F(TransientFileUtilsTest, MAYBE_ReadInt16BufferFromFile) {
std::string test_filename = kTestFileName;
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileName.c_str();
+ FileWrapper file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileName.c_str();
const size_t kBufferLength = 12;
std::unique_ptr<int16_t[]> buffer(new int16_t[kBufferLength]);
EXPECT_EQ(kBufferLength,
- ReadInt16BufferFromFile(file.get(), kBufferLength, buffer.get()));
+ ReadInt16BufferFromFile(&file, kBufferLength, buffer.get()));
EXPECT_EQ(22377, buffer[4]);
EXPECT_EQ(16389, buffer[7]);
EXPECT_EQ(17631, buffer[kBufferLength - 1]);
- file->Rewind();
+ file.Rewind();
// The next test is for checking the case where there are not as much data as
// needed in the file, but reads to the end, and it returns the number of
@@ -181,7 +179,7 @@
const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
buffer.reset(new int16_t[kBufferLenghtLargerThanFile]);
EXPECT_EQ(kBufferLength,
- ReadInt16BufferFromFile(file.get(), kBufferLenghtLargerThanFile,
+ ReadInt16BufferFromFile(&file, kBufferLenghtLargerThanFile,
buffer.get()));
EXPECT_EQ(11544, buffer[0]);
EXPECT_EQ(22377, buffer[4]);
@@ -198,24 +196,22 @@
TEST_F(TransientFileUtilsTest, MAYBE_ReadInt16FromFileToFloatBuffer) {
std::string test_filename = kTestFileName;
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileName.c_str();
+ FileWrapper file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileName.c_str();
const size_t kBufferLength = 12;
std::unique_ptr<float[]> buffer(new float[kBufferLength]);
- EXPECT_EQ(kBufferLength, ReadInt16FromFileToFloatBuffer(
- file.get(), kBufferLength, buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ ReadInt16FromFileToFloatBuffer(&file, kBufferLength, buffer.get()));
EXPECT_DOUBLE_EQ(11544, buffer[0]);
EXPECT_DOUBLE_EQ(22377, buffer[4]);
EXPECT_DOUBLE_EQ(16389, buffer[7]);
EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
- file->Rewind();
+ file.Rewind();
// The next test is for checking the case where there are not as much data as
// needed in the file, but reads to the end, and it returns the number of
@@ -223,8 +219,8 @@
const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
buffer.reset(new float[kBufferLenghtLargerThanFile]);
EXPECT_EQ(kBufferLength,
- ReadInt16FromFileToFloatBuffer(
- file.get(), kBufferLenghtLargerThanFile, buffer.get()));
+ ReadInt16FromFileToFloatBuffer(&file, kBufferLenghtLargerThanFile,
+ buffer.get()));
EXPECT_DOUBLE_EQ(11544, buffer[0]);
EXPECT_DOUBLE_EQ(22377, buffer[4]);
EXPECT_DOUBLE_EQ(16389, buffer[7]);
@@ -240,23 +236,21 @@
TEST_F(TransientFileUtilsTest, MAYBE_ReadInt16FromFileToDoubleBuffer) {
std::string test_filename = kTestFileName;
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileName.c_str();
+ FileWrapper file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileName.c_str();
const size_t kBufferLength = 12;
std::unique_ptr<double[]> buffer(new double[kBufferLength]);
- EXPECT_EQ(kBufferLength, ReadInt16FromFileToDoubleBuffer(
- file.get(), kBufferLength, buffer.get()));
+ EXPECT_EQ(kBufferLength, ReadInt16FromFileToDoubleBuffer(&file, kBufferLength,
+ buffer.get()));
EXPECT_DOUBLE_EQ(11544, buffer[0]);
EXPECT_DOUBLE_EQ(22377, buffer[4]);
EXPECT_DOUBLE_EQ(16389, buffer[7]);
EXPECT_DOUBLE_EQ(17631, buffer[kBufferLength - 1]);
- file->Rewind();
+ file.Rewind();
// The next test is for checking the case where there are not as much data as
// needed in the file, but reads to the end, and it returns the number of
@@ -264,8 +258,8 @@
const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
buffer.reset(new double[kBufferLenghtLargerThanFile]);
EXPECT_EQ(kBufferLength,
- ReadInt16FromFileToDoubleBuffer(
- file.get(), kBufferLenghtLargerThanFile, buffer.get()));
+ ReadInt16FromFileToDoubleBuffer(&file, kBufferLenghtLargerThanFile,
+ buffer.get()));
EXPECT_DOUBLE_EQ(11544, buffer[0]);
EXPECT_DOUBLE_EQ(22377, buffer[4]);
EXPECT_DOUBLE_EQ(16389, buffer[7]);
@@ -280,22 +274,20 @@
TEST_F(TransientFileUtilsTest, MAYBE_ReadFloatBufferFromFile) {
std::string test_filename = kTestFileNamef;
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileNamef.c_str();
+ FileWrapper file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileNamef.c_str();
const size_t kBufferLength = 3;
std::unique_ptr<float[]> buffer(new float[kBufferLength]);
EXPECT_EQ(kBufferLength,
- ReadFloatBufferFromFile(file.get(), kBufferLength, buffer.get()));
+ ReadFloatBufferFromFile(&file, kBufferLength, buffer.get()));
EXPECT_FLOAT_EQ(kPi, buffer[0]);
EXPECT_FLOAT_EQ(kE, buffer[1]);
EXPECT_FLOAT_EQ(kAvogadro, buffer[2]);
- file->Rewind();
+ file.Rewind();
// The next test is for checking the case where there are not as much data as
// needed in the file, but reads to the end, and it returns the number of
@@ -303,7 +295,7 @@
const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
buffer.reset(new float[kBufferLenghtLargerThanFile]);
EXPECT_EQ(kBufferLength,
- ReadFloatBufferFromFile(file.get(), kBufferLenghtLargerThanFile,
+ ReadFloatBufferFromFile(&file, kBufferLenghtLargerThanFile,
buffer.get()));
EXPECT_FLOAT_EQ(kPi, buffer[0]);
EXPECT_FLOAT_EQ(kE, buffer[1]);
@@ -318,22 +310,20 @@
TEST_F(TransientFileUtilsTest, MAYBE_ReadDoubleBufferFromFile) {
std::string test_filename = kTestFileName;
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileName.c_str();
+ FileWrapper file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileName.c_str();
const size_t kBufferLength = 3;
std::unique_ptr<double[]> buffer(new double[kBufferLength]);
EXPECT_EQ(kBufferLength,
- ReadDoubleBufferFromFile(file.get(), kBufferLength, buffer.get()));
+ ReadDoubleBufferFromFile(&file, kBufferLength, buffer.get()));
EXPECT_DOUBLE_EQ(kPi, buffer[0]);
EXPECT_DOUBLE_EQ(kE, buffer[1]);
EXPECT_DOUBLE_EQ(kAvogadro, buffer[2]);
- file->Rewind();
+ file.Rewind();
// The next test is for checking the case where there are not as much data as
// needed in the file, but reads to the end, and it returns the number of
@@ -341,7 +331,7 @@
const size_t kBufferLenghtLargerThanFile = kBufferLength * 2;
buffer.reset(new double[kBufferLenghtLargerThanFile]);
EXPECT_EQ(kBufferLength,
- ReadDoubleBufferFromFile(file.get(), kBufferLenghtLargerThanFile,
+ ReadDoubleBufferFromFile(&file, kBufferLenghtLargerThanFile,
buffer.get()));
EXPECT_DOUBLE_EQ(kPi, buffer[0]);
EXPECT_DOUBLE_EQ(kE, buffer[1]);
@@ -354,14 +344,12 @@
#define MAYBE_WriteInt16BufferToFile WriteInt16BufferToFile
#endif
TEST_F(TransientFileUtilsTest, MAYBE_WriteInt16BufferToFile) {
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
std::string kOutFileName =
CreateTempFilename(test::OutputPath(), "utils_test");
- file->OpenFile(kOutFileName.c_str(), false); // Write mode.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ FileWrapper file = FileWrapper::OpenWriteOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
const size_t kBufferLength = 3;
std::unique_ptr<int16_t[]> written_buffer(new int16_t[kBufferLength]);
@@ -371,17 +359,17 @@
written_buffer[1] = 2;
written_buffer[2] = 3;
- EXPECT_EQ(kBufferLength, WriteInt16BufferToFile(file.get(), kBufferLength,
- written_buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ WriteInt16BufferToFile(&file, kBufferLength, written_buffer.get()));
- file->CloseFile();
+ file.Close();
- file->OpenFile(kOutFileName.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ file = FileWrapper::OpenReadOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
- EXPECT_EQ(kBufferLength, ReadInt16BufferFromFile(file.get(), kBufferLength,
- read_buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ ReadInt16BufferFromFile(&file, kBufferLength, read_buffer.get()));
EXPECT_EQ(0, memcmp(written_buffer.get(), read_buffer.get(),
kBufferLength * sizeof(written_buffer[0])));
}
@@ -392,14 +380,12 @@
#define MAYBE_WriteFloatBufferToFile WriteFloatBufferToFile
#endif
TEST_F(TransientFileUtilsTest, MAYBE_WriteFloatBufferToFile) {
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
std::string kOutFileName =
CreateTempFilename(test::OutputPath(), "utils_test");
- file->OpenFile(kOutFileName.c_str(), false); // Write mode.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ FileWrapper file = FileWrapper::OpenWriteOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
const size_t kBufferLength = 3;
std::unique_ptr<float[]> written_buffer(new float[kBufferLength]);
@@ -409,17 +395,17 @@
written_buffer[1] = static_cast<float>(kE);
written_buffer[2] = static_cast<float>(kAvogadro);
- EXPECT_EQ(kBufferLength, WriteFloatBufferToFile(file.get(), kBufferLength,
- written_buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ WriteFloatBufferToFile(&file, kBufferLength, written_buffer.get()));
- file->CloseFile();
+ file.Close();
- file->OpenFile(kOutFileName.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ file = FileWrapper::OpenReadOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
- EXPECT_EQ(kBufferLength, ReadFloatBufferFromFile(file.get(), kBufferLength,
- read_buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ ReadFloatBufferFromFile(&file, kBufferLength, read_buffer.get()));
EXPECT_EQ(0, memcmp(written_buffer.get(), read_buffer.get(),
kBufferLength * sizeof(written_buffer[0])));
}
@@ -430,14 +416,12 @@
#define MAYBE_WriteDoubleBufferToFile WriteDoubleBufferToFile
#endif
TEST_F(TransientFileUtilsTest, MAYBE_WriteDoubleBufferToFile) {
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
-
std::string kOutFileName =
CreateTempFilename(test::OutputPath(), "utils_test");
- file->OpenFile(kOutFileName.c_str(), false); // Write mode.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ FileWrapper file = FileWrapper::OpenWriteOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
const size_t kBufferLength = 3;
std::unique_ptr<double[]> written_buffer(new double[kBufferLength]);
@@ -447,17 +431,17 @@
written_buffer[1] = kE;
written_buffer[2] = kAvogadro;
- EXPECT_EQ(kBufferLength, WriteDoubleBufferToFile(file.get(), kBufferLength,
+ EXPECT_EQ(kBufferLength, WriteDoubleBufferToFile(&file, kBufferLength,
written_buffer.get()));
- file->CloseFile();
+ file.Close();
- file->OpenFile(kOutFileName.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kOutFileName.c_str();
+ file = FileWrapper::OpenReadOnly(kOutFileName.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kOutFileName.c_str();
- EXPECT_EQ(kBufferLength, ReadDoubleBufferFromFile(file.get(), kBufferLength,
- read_buffer.get()));
+ EXPECT_EQ(kBufferLength,
+ ReadDoubleBufferFromFile(&file, kBufferLength, read_buffer.get()));
EXPECT_EQ(0, memcmp(written_buffer.get(), read_buffer.get(),
kBufferLength * sizeof(written_buffer[0])));
}
@@ -473,7 +457,7 @@
double value;
std::unique_ptr<int16_t[]> int16_buffer(new int16_t[1]);
std::unique_ptr<double[]> double_buffer(new double[1]);
- std::unique_ptr<FileWrapper> file(FileWrapper::Create());
+ FileWrapper file;
EXPECT_EQ(-1, ConvertByteArrayToDouble(NULL, &value));
EXPECT_EQ(-1, ConvertByteArrayToDouble(kPiBytes, NULL));
@@ -481,37 +465,35 @@
EXPECT_EQ(-1, ConvertDoubleToByteArray(kPi, NULL));
// Tests with file not opened.
- EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 1, int16_buffer.get()));
- EXPECT_EQ(
- 0u, ReadInt16FromFileToDoubleBuffer(file.get(), 1, double_buffer.get()));
- EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 1, double_buffer.get()));
- EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 1, int16_buffer.get()));
- EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 1, double_buffer.get()));
+ EXPECT_EQ(0u, ReadInt16BufferFromFile(&file, 1, int16_buffer.get()));
+ EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(&file, 1, double_buffer.get()));
+ EXPECT_EQ(0u, ReadDoubleBufferFromFile(&file, 1, double_buffer.get()));
+ EXPECT_EQ(0u, WriteInt16BufferToFile(&file, 1, int16_buffer.get()));
+ EXPECT_EQ(0u, WriteDoubleBufferToFile(&file, 1, double_buffer.get()));
- file->OpenFile(test_filename.c_str(), true); // Read only.
- ASSERT_TRUE(file->is_open()) << "File could not be opened:\n"
- << kTestFileName.c_str();
+ file = FileWrapper::OpenReadOnly(test_filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "File could not be opened:\n"
+ << kTestFileName.c_str();
EXPECT_EQ(0u, ReadInt16BufferFromFile(NULL, 1, int16_buffer.get()));
- EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 1, NULL));
- EXPECT_EQ(0u, ReadInt16BufferFromFile(file.get(), 0, int16_buffer.get()));
+ EXPECT_EQ(0u, ReadInt16BufferFromFile(&file, 1, NULL));
+ EXPECT_EQ(0u, ReadInt16BufferFromFile(&file, 0, int16_buffer.get()));
EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(NULL, 1, double_buffer.get()));
- EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(file.get(), 1, NULL));
- EXPECT_EQ(
- 0u, ReadInt16FromFileToDoubleBuffer(file.get(), 0, double_buffer.get()));
+ EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(&file, 1, NULL));
+ EXPECT_EQ(0u, ReadInt16FromFileToDoubleBuffer(&file, 0, double_buffer.get()));
EXPECT_EQ(0u, ReadDoubleBufferFromFile(NULL, 1, double_buffer.get()));
- EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 1, NULL));
- EXPECT_EQ(0u, ReadDoubleBufferFromFile(file.get(), 0, double_buffer.get()));
+ EXPECT_EQ(0u, ReadDoubleBufferFromFile(&file, 1, NULL));
+ EXPECT_EQ(0u, ReadDoubleBufferFromFile(&file, 0, double_buffer.get()));
EXPECT_EQ(0u, WriteInt16BufferToFile(NULL, 1, int16_buffer.get()));
- EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 1, NULL));
- EXPECT_EQ(0u, WriteInt16BufferToFile(file.get(), 0, int16_buffer.get()));
+ EXPECT_EQ(0u, WriteInt16BufferToFile(&file, 1, NULL));
+ EXPECT_EQ(0u, WriteInt16BufferToFile(&file, 0, int16_buffer.get()));
EXPECT_EQ(0u, WriteDoubleBufferToFile(NULL, 1, double_buffer.get()));
- EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 1, NULL));
- EXPECT_EQ(0u, WriteDoubleBufferToFile(file.get(), 0, double_buffer.get()));
+ EXPECT_EQ(0u, WriteDoubleBufferToFile(&file, 1, NULL));
+ EXPECT_EQ(0u, WriteDoubleBufferToFile(&file, 0, double_buffer.get()));
}
} // namespace webrtc
diff --git a/modules/audio_processing/transient/transient_detector_unittest.cc b/modules/audio_processing/transient/transient_detector_unittest.cc
index 11dd8aa..0425133 100644
--- a/modules/audio_processing/transient/transient_detector_unittest.cc
+++ b/modules/audio_processing/transient/transient_detector_unittest.cc
@@ -47,13 +47,10 @@
detect_file_name << "audio_processing/transient/detect"
<< (sample_rate_hz / 1000) << "kHz";
- std::unique_ptr<FileWrapper> detect_file(FileWrapper::Create());
+ FileWrapper detect_file = FileWrapper::OpenReadOnly(
+ test::ResourcePath(detect_file_name.str(), "dat").c_str());
- detect_file->OpenFile(
- test::ResourcePath(detect_file_name.str(), "dat").c_str(),
- true); // Read only.
-
- bool file_opened = detect_file->is_open();
+ bool file_opened = detect_file.is_open();
ASSERT_TRUE(file_opened) << "File could not be opened.\n"
<< detect_file_name.str().c_str();
@@ -62,11 +59,8 @@
audio_file_name << "audio_processing/transient/audio"
<< (sample_rate_hz / 1000) << "kHz";
- std::unique_ptr<FileWrapper> audio_file(FileWrapper::Create());
-
- audio_file->OpenFile(
- test::ResourcePath(audio_file_name.str(), "pcm").c_str(),
- true); // Read only.
+ FileWrapper audio_file = FileWrapper::OpenReadOnly(
+ test::ResourcePath(audio_file_name.str(), "pcm").c_str());
// Create detector.
TransientDetector detector(sample_rate_hz);
@@ -78,14 +72,14 @@
size_t frames_read = 0;
- while (ReadInt16FromFileToFloatBuffer(audio_file.get(), buffer_length,
+ while (ReadInt16FromFileToFloatBuffer(&audio_file, buffer_length,
buffer.get()) == buffer_length) {
++frames_read;
float detector_value =
detector.Detect(buffer.get(), buffer_length, NULL, 0);
double file_value;
- ASSERT_EQ(1u, ReadDoubleBufferFromFile(detect_file.get(), 1, &file_value))
+ ASSERT_EQ(1u, ReadDoubleBufferFromFile(&detect_file, 1, &file_value))
<< "Detect test file is malformed.\n";
// Compare results with data from the matlab test file.
@@ -93,8 +87,8 @@
<< "Frame: " << frames_read;
}
- detect_file->CloseFile();
- audio_file->CloseFile();
+ detect_file.Close();
+ audio_file.Close();
}
}
diff --git a/modules/audio_processing/transient/wpd_tree_unittest.cc b/modules/audio_processing/transient/wpd_tree_unittest.cc
index 1d6dbe8..11f75e6 100644
--- a/modules/audio_processing/transient/wpd_tree_unittest.cc
+++ b/modules/audio_processing/transient/wpd_tree_unittest.cc
@@ -80,31 +80,27 @@
kDaubechies8LowPassCoefficients, kDaubechies8CoefficientsLength,
kLevels);
// Allocate and open all matlab and out files.
- std::unique_ptr<FileWrapper> matlab_files_data[kLeaves];
- std::unique_ptr<FileWrapper> out_files_data[kLeaves];
+ FileWrapper matlab_files_data[kLeaves];
+ FileWrapper out_files_data[kLeaves];
for (int i = 0; i < kLeaves; ++i) {
// Matlab files.
- matlab_files_data[i].reset(FileWrapper::Create());
-
rtc::StringBuilder matlab_stream;
matlab_stream << "audio_processing/transient/wpd" << i;
std::string matlab_string = test::ResourcePath(matlab_stream.str(), "dat");
- matlab_files_data[i]->OpenFile(matlab_string.c_str(), true); // Read only.
+ matlab_files_data[i] = FileWrapper::OpenReadOnly(matlab_string.c_str());
- bool file_opened = matlab_files_data[i]->is_open();
+ bool file_opened = matlab_files_data[i].is_open();
ASSERT_TRUE(file_opened) << "File could not be opened.\n" << matlab_string;
// Out files.
- out_files_data[i].reset(FileWrapper::Create());
-
rtc::StringBuilder out_stream;
out_stream << test::OutputPath() << "wpd_" << i << ".out";
std::string out_string = out_stream.str();
- out_files_data[i]->OpenFile(out_string.c_str(), false); // Write mode.
+ out_files_data[i] = FileWrapper::OpenWriteOnly(out_string.c_str());
- file_opened = out_files_data[i]->is_open();
+ file_opened = out_files_data[i].is_open();
ASSERT_TRUE(file_opened) << "File could not be opened.\n" << out_string;
}
@@ -112,11 +108,9 @@
std::string test_file_name = test::ResourcePath(
"audio_processing/transient/ajm-macbook-1-spke16m", "pcm");
- std::unique_ptr<FileWrapper> test_file(FileWrapper::Create());
+ FileWrapper test_file = FileWrapper::OpenReadOnly(test_file_name.c_str());
- test_file->OpenFile(test_file_name.c_str(), true); // Read only.
-
- bool file_opened = test_file->is_open();
+ bool file_opened = test_file.is_open();
ASSERT_TRUE(file_opened) << "File could not be opened.\n" << test_file_name;
float test_buffer[kTestBufferSize];
@@ -129,8 +123,8 @@
size_t frames_read = 0;
// Read first buffer from the PCM test file.
- size_t file_samples_read = ReadInt16FromFileToFloatBuffer(
- test_file.get(), kTestBufferSize, test_buffer);
+ size_t file_samples_read =
+ ReadInt16FromFileToFloatBuffer(&test_file, kTestBufferSize, test_buffer);
while (file_samples_read > 0 && frames_read < kMaxFramesToTest) {
++frames_read;
@@ -147,7 +141,7 @@
for (int i = 0; i < kLeaves; ++i) {
// Compare data values
size_t matlab_samples_read = ReadDoubleBufferFromFile(
- matlab_files_data[i].get(), kLeavesSamples, matlab_buffer);
+ &matlab_files_data[i], kLeavesSamples, matlab_buffer);
ASSERT_EQ(kLeavesSamples, matlab_samples_read)
<< "Matlab test files are malformed.\n"
@@ -162,22 +156,21 @@
}
// Write results to out files.
- WriteFloatBufferToFile(out_files_data[i].get(), kLeavesSamples,
- node_data);
+ WriteFloatBufferToFile(&out_files_data[i], kLeavesSamples, node_data);
}
// Read next buffer from the PCM test file.
file_samples_read = ReadInt16FromFileToFloatBuffer(
- test_file.get(), kTestBufferSize, test_buffer);
+ &test_file, kTestBufferSize, test_buffer);
}
// Close all matlab and out files.
for (int i = 0; i < kLeaves; ++i) {
- matlab_files_data[i]->CloseFile();
- out_files_data[i]->CloseFile();
+ matlab_files_data[i].Close();
+ out_files_data[i].Close();
}
- test_file->CloseFile();
+ test_file.Close();
}
} // namespace webrtc
diff --git a/rtc_base/system/file_wrapper.cc b/rtc_base/system/file_wrapper.cc
index c033a79..dbea1ca 100644
--- a/rtc_base/system/file_wrapper.cc
+++ b/rtc_base/system/file_wrapper.cc
@@ -34,22 +34,13 @@
} // namespace
// static
-FileWrapper* FileWrapper::Create() {
- return new FileWrapper();
+FileWrapper FileWrapper::OpenReadOnly(const char* file_name_utf8) {
+ return FileWrapper(FileOpen(file_name_utf8, true));
}
// static
-FileWrapper FileWrapper::Open(const char* file_name_utf8, bool read_only) {
- return FileWrapper(FileOpen(file_name_utf8, read_only), 0);
-}
-
-FileWrapper::FileWrapper() {}
-
-FileWrapper::FileWrapper(FILE* file, size_t max_size)
- : file_(file), max_size_in_bytes_(max_size) {}
-
-FileWrapper::~FileWrapper() {
- CloseFileImpl();
+FileWrapper FileWrapper::OpenWriteOnly(const char* file_name_utf8) {
+ return FileWrapper(FileOpen(file_name_utf8, false));
}
FileWrapper::FileWrapper(FileWrapper&& other) {
@@ -57,95 +48,39 @@
}
FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
+ Close();
file_ = other.file_;
- max_size_in_bytes_ = other.max_size_in_bytes_;
- position_ = other.position_;
other.file_ = nullptr;
return *this;
}
-void FileWrapper::CloseFile() {
- rtc::CritScope lock(&lock_);
- CloseFileImpl();
+bool FileWrapper::Rewind() {
+ RTC_DCHECK(file_);
+ return fseek(file_, 0, SEEK_SET) == 0;
}
-int FileWrapper::Rewind() {
- rtc::CritScope lock(&lock_);
- if (file_ != nullptr) {
- position_ = 0;
- return fseek(file_, 0, SEEK_SET);
- }
- return -1;
+bool FileWrapper::Flush() {
+ RTC_DCHECK(file_);
+ return fflush(file_) == 0;
}
-void FileWrapper::SetMaxFileSize(size_t bytes) {
- rtc::CritScope lock(&lock_);
- max_size_in_bytes_ = bytes;
-}
-
-int FileWrapper::Flush() {
- rtc::CritScope lock(&lock_);
- return FlushImpl();
-}
-
-bool FileWrapper::OpenFile(const char* file_name_utf8, bool read_only) {
- size_t length = strlen(file_name_utf8);
- if (length > kMaxFileNameSize - 1)
- return false;
-
- rtc::CritScope lock(&lock_);
- if (file_ != nullptr)
- return false;
-
- file_ = FileOpen(file_name_utf8, read_only);
- return file_ != nullptr;
-}
-
-bool FileWrapper::OpenFromFileHandle(FILE* handle) {
- if (!handle)
- return false;
- rtc::CritScope lock(&lock_);
- CloseFileImpl();
- file_ = handle;
- return true;
-}
-
-int FileWrapper::Read(void* buf, size_t length) {
- rtc::CritScope lock(&lock_);
- if (file_ == nullptr)
- return -1;
-
- size_t bytes_read = fread(buf, 1, length, file_);
- return static_cast<int>(bytes_read);
+size_t FileWrapper::Read(void* buf, size_t length) {
+ RTC_DCHECK(file_);
+ return fread(buf, 1, length, file_);
}
bool FileWrapper::Write(const void* buf, size_t length) {
- if (buf == nullptr)
- return false;
+ RTC_DCHECK(file_);
+ return fwrite(buf, 1, length, file_) == length;
+}
- rtc::CritScope lock(&lock_);
-
+bool FileWrapper::Close() {
if (file_ == nullptr)
- return false;
+ return true;
- // Check if it's time to stop writing.
- if (max_size_in_bytes_ > 0 && (position_ + length) > max_size_in_bytes_)
- return false;
-
- size_t num_bytes = fwrite(buf, 1, length, file_);
- position_ += num_bytes;
-
- return num_bytes == length;
-}
-
-void FileWrapper::CloseFileImpl() {
- if (file_ != nullptr)
- fclose(file_);
+ bool success = fclose(file_) == 0;
file_ = nullptr;
-}
-
-int FileWrapper::FlushImpl() {
- return (file_ != nullptr) ? fflush(file_) : -1;
+ return success;
}
} // namespace webrtc
diff --git a/rtc_base/system/file_wrapper.h b/rtc_base/system/file_wrapper.h
index f2ed51a..d56e131 100644
--- a/rtc_base/system/file_wrapper.h
+++ b/rtc_base/system/file_wrapper.h
@@ -20,64 +20,57 @@
namespace webrtc {
-// TODO(tommi): Rename to rtc::File and move to base.
class FileWrapper final {
public:
- static const size_t kMaxFileNameSize = 1024;
+ // Opens a file, in read or write mode. Use the is_open() method on the
+ // returned object to check if the open operation was successful. The file is
+ // closed by the destructor.
+ static FileWrapper OpenReadOnly(const char* file_name_utf8);
+ static FileWrapper OpenWriteOnly(const char* file_name_utf8);
- // Factory methods.
- // TODO(tommi): Remove Create().
- static FileWrapper* Create();
- static FileWrapper Open(const char* file_name_utf8, bool read_only);
+ FileWrapper() = default;
- FileWrapper(FILE* file, size_t max_size);
- ~FileWrapper();
-
- // Support for move semantics.
- FileWrapper(FileWrapper&& other);
- FileWrapper& operator=(FileWrapper&& other);
-
- // Returns true if a file has been opened.
- bool is_open() const { return file_ != nullptr; }
-
- // Opens a file in read or write mode, decided by the read_only parameter.
- bool OpenFile(const char* file_name_utf8, bool read_only);
-
- // Initializes the wrapper from an existing handle. The wrapper
- // takes ownership of |handle| and closes it in CloseFile().
- bool OpenFromFileHandle(FILE* handle);
-
- void CloseFile();
-
- // Limits the file size to |bytes|. Writing will fail after the cap
- // is hit. Pass zero to use an unlimited size.
- // TODO(tommi): Could we move this out into a separate class?
- void SetMaxFileSize(size_t bytes);
-
- // Flush any pending writes. Note: Flushing when closing, is not required.
- int Flush();
-
- // Rewinds the file to the start.
- int Rewind();
- int Read(void* buf, size_t length);
- bool Write(const void* buf, size_t length);
-
- private:
- FileWrapper();
-
- void CloseFileImpl();
- int FlushImpl();
-
- // TODO(tommi): Remove the lock.
- rtc::CriticalSection lock_;
-
- FILE* file_ = nullptr;
- size_t position_ = 0;
- size_t max_size_in_bytes_ = 0;
+ // Takes over ownership of |file|, closing it on destruction.
+ explicit FileWrapper(FILE* file) : file_(file) {}
+ ~FileWrapper() { Close(); }
// Copying is not supported.
FileWrapper(const FileWrapper&) = delete;
FileWrapper& operator=(const FileWrapper&) = delete;
+
+ // Support for move semantics.
+ FileWrapper(FileWrapper&&);
+ FileWrapper& operator=(FileWrapper&&);
+
+ // Returns true if a file has been opened. If the file is not open, no methods
+ // but is_open and Close may be called.
+ bool is_open() const { return file_ != nullptr; }
+
+ // Closes the file, and implies Flush. Returns true on success, false if
+ // writing buffered data fails. On failure, the file is nevertheless closed.
+ // Calling Close on an already closed file does nothing and returns success.
+ bool Close();
+
+ // Write any buffered data to the underlying file. Returns true on success,
+ // false on write error. Note: Flushing when closing, is not required.
+ // TODO(nisse): Delete this method.
+ bool Flush();
+
+ // Seeks to the beginning of file. Returns true on success, false on failure,
+ // e.g., if the underlying file isn't seekable.
+ // TODO(nisse): Delete this method.
+ bool Rewind();
+
+ // Returns number of bytes read. Short count indicates EOF or error.
+ size_t Read(void* buf, size_t length);
+
+ // Returns true if all data was successfully written (or buffered), or false
+ // if there was an error. Writing buffered data can fail later, and is
+ // reported with return value from Flush or Close.
+ bool Write(const void* buf, size_t length);
+
+ private:
+ FILE* file_ = nullptr;
};
} // namespace webrtc