blob: c033a792a50c3e9238896255ab6c657e3880943d [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
henrike@webrtc.org143abd92012-02-08 19:39:38 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Karl Wiberg6a4d4112018-03-23 10:39:34 +010011#include "rtc_base/system/file_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
13#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000014#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000016#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000017#endif
18
Karl Wiberg6a4d4112018-03-23 10:39:34 +010019#include <utility>
20
niklase@google.com470e71d2011-07-07 08:21:25 +000021namespace webrtc {
tommia6219cc2016-06-15 10:30:14 -070022namespace {
23FILE* FileOpen(const char* file_name_utf8, bool read_only) {
24#if defined(_WIN32)
25 int len = MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, nullptr, 0);
26 std::wstring wstr(len, 0);
27 MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, &wstr[0], len);
28 FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000029#else
tommia6219cc2016-06-15 10:30:14 -070030 FILE* file = fopen(file_name_utf8, read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000031#endif
tommia6219cc2016-06-15 10:30:14 -070032 return file;
33}
34} // namespace
niklase@google.com470e71d2011-07-07 08:21:25 +000035
tommia6219cc2016-06-15 10:30:14 -070036// static
Niels Moller46647272019-01-18 12:04:43 +000037FileWrapper* FileWrapper::Create() {
38 return new FileWrapper();
phoglund@webrtc.org740be442012-12-12 12:52:15 +000039}
40
tommia6219cc2016-06-15 10:30:14 -070041// static
Niels Moller46647272019-01-18 12:04:43 +000042FileWrapper FileWrapper::Open(const char* file_name_utf8, bool read_only) {
43 return FileWrapper(FileOpen(file_name_utf8, read_only), 0);
44}
45
46FileWrapper::FileWrapper() {}
47
48FileWrapper::FileWrapper(FILE* file, size_t max_size)
49 : file_(file), max_size_in_bytes_(max_size) {}
50
51FileWrapper::~FileWrapper() {
52 CloseFileImpl();
phoglund@webrtc.org740be442012-12-12 12:52:15 +000053}
54
tommia6219cc2016-06-15 10:30:14 -070055FileWrapper::FileWrapper(FileWrapper&& other) {
56 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000057}
58
tommia6219cc2016-06-15 10:30:14 -070059FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
60 file_ = other.file_;
Niels Moller46647272019-01-18 12:04:43 +000061 max_size_in_bytes_ = other.max_size_in_bytes_;
62 position_ = other.position_;
tommia6219cc2016-06-15 10:30:14 -070063 other.file_ = nullptr;
64 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +000065}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000066
Niels Moller46647272019-01-18 12:04:43 +000067void FileWrapper::CloseFile() {
68 rtc::CritScope lock(&lock_);
69 CloseFileImpl();
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000070}
71
Niels Moller46647272019-01-18 12:04:43 +000072int FileWrapper::Rewind() {
73 rtc::CritScope lock(&lock_);
74 if (file_ != nullptr) {
75 position_ = 0;
76 return fseek(file_, 0, SEEK_SET);
77 }
78 return -1;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000079}
80
Niels Moller46647272019-01-18 12:04:43 +000081void FileWrapper::SetMaxFileSize(size_t bytes) {
82 rtc::CritScope lock(&lock_);
83 max_size_in_bytes_ = bytes;
84}
85
86int FileWrapper::Flush() {
87 rtc::CritScope lock(&lock_);
88 return FlushImpl();
89}
90
91bool FileWrapper::OpenFile(const char* file_name_utf8, bool read_only) {
92 size_t length = strlen(file_name_utf8);
93 if (length > kMaxFileNameSize - 1)
94 return false;
95
96 rtc::CritScope lock(&lock_);
97 if (file_ != nullptr)
98 return false;
99
100 file_ = FileOpen(file_name_utf8, read_only);
101 return file_ != nullptr;
102}
103
104bool FileWrapper::OpenFromFileHandle(FILE* handle) {
105 if (!handle)
106 return false;
107 rtc::CritScope lock(&lock_);
108 CloseFileImpl();
109 file_ = handle;
110 return true;
111}
112
113int FileWrapper::Read(void* buf, size_t length) {
114 rtc::CritScope lock(&lock_);
115 if (file_ == nullptr)
116 return -1;
117
118 size_t bytes_read = fread(buf, 1, length, file_);
119 return static_cast<int>(bytes_read);
tommia6219cc2016-06-15 10:30:14 -0700120}
121
122bool FileWrapper::Write(const void* buf, size_t length) {
Niels Moller46647272019-01-18 12:04:43 +0000123 if (buf == nullptr)
124 return false;
125
126 rtc::CritScope lock(&lock_);
127
128 if (file_ == nullptr)
129 return false;
130
131 // Check if it's time to stop writing.
132 if (max_size_in_bytes_ > 0 && (position_ + length) > max_size_in_bytes_)
133 return false;
134
135 size_t num_bytes = fwrite(buf, 1, length, file_);
136 position_ += num_bytes;
137
138 return num_bytes == length;
Niels Möller80b95de2019-01-17 15:23:31 +0100139}
tommia6219cc2016-06-15 10:30:14 -0700140
Niels Moller46647272019-01-18 12:04:43 +0000141void FileWrapper::CloseFileImpl() {
142 if (file_ != nullptr)
143 fclose(file_);
tommia6219cc2016-06-15 10:30:14 -0700144 file_ = nullptr;
Niels Moller46647272019-01-18 12:04:43 +0000145}
146
147int FileWrapper::FlushImpl() {
148 return (file_ != nullptr) ? fflush(file_) : -1;
tommia6219cc2016-06-15 10:30:14 -0700149}
150
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000151} // namespace webrtc