blob: f7befc6dc5320f7dc7f6113e2000864579fdbafb [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
Niels Möller23213d92019-01-22 11:01:24 +010013#include <cerrno>
14
Ali Tofigh2ab914c2022-04-13 12:55:15 +020015#include "absl/strings/string_view.h"
16#include "rtc_base/numerics/safe_conversions.h"
17
niklase@google.com470e71d2011-07-07 08:21:25 +000018#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000019#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000020#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000021#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000022#endif
23
Karl Wiberg6a4d4112018-03-23 10:39:34 +010024#include <utility>
25
niklase@google.com470e71d2011-07-07 08:21:25 +000026namespace webrtc {
tommia6219cc2016-06-15 10:30:14 -070027namespace {
Ali Tofigh2ab914c2022-04-13 12:55:15 +020028FILE* FileOpen(absl::string_view file_name_utf8, bool read_only, int* error) {
29 RTC_CHECK_EQ(file_name_utf8.find_first_of('\0'), absl::string_view::npos)
30 << "Invalid filename, containing NUL character";
Ali Tofigh98bfd992022-07-22 22:10:49 +020031 std::string file_name(file_name_utf8);
tommia6219cc2016-06-15 10:30:14 -070032#if defined(_WIN32)
Ali Tofigh2ab914c2022-04-13 12:55:15 +020033 int len = MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, nullptr, 0);
tommia6219cc2016-06-15 10:30:14 -070034 std::wstring wstr(len, 0);
Ali Tofigh2ab914c2022-04-13 12:55:15 +020035 MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, &wstr[0], len);
tommia6219cc2016-06-15 10:30:14 -070036 FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000037#else
Ali Tofigh2ab914c2022-04-13 12:55:15 +020038 FILE* file = fopen(file_name.c_str(), read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000039#endif
Niels Möller23213d92019-01-22 11:01:24 +010040 if (!file && error) {
41 *error = errno;
42 }
tommia6219cc2016-06-15 10:30:14 -070043 return file;
44}
Niels Möller23213d92019-01-22 11:01:24 +010045
tommia6219cc2016-06-15 10:30:14 -070046} // namespace
niklase@google.com470e71d2011-07-07 08:21:25 +000047
tommia6219cc2016-06-15 10:30:14 -070048// static
Ali Tofigh2ab914c2022-04-13 12:55:15 +020049FileWrapper FileWrapper::OpenReadOnly(absl::string_view file_name_utf8) {
Niels Möller23213d92019-01-22 11:01:24 +010050 return FileWrapper(FileOpen(file_name_utf8, true, nullptr));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000051}
52
tommia6219cc2016-06-15 10:30:14 -070053// static
Ali Tofigh2ab914c2022-04-13 12:55:15 +020054FileWrapper FileWrapper::OpenWriteOnly(absl::string_view file_name_utf8,
Niels Möller23213d92019-01-22 11:01:24 +010055 int* error /*=nullptr*/) {
56 return FileWrapper(FileOpen(file_name_utf8, false, error));
57}
58
tommia6219cc2016-06-15 10:30:14 -070059FileWrapper::FileWrapper(FileWrapper&& other) {
60 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000061}
62
tommia6219cc2016-06-15 10:30:14 -070063FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
Niels Möller5a6ae022019-01-21 11:59:10 +010064 Close();
tommia6219cc2016-06-15 10:30:14 -070065 file_ = other.file_;
tommia6219cc2016-06-15 10:30:14 -070066 other.file_ = nullptr;
67 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +000068}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000069
Niels Möller7ba3b812019-08-06 09:58:56 +020070bool FileWrapper::SeekRelative(int64_t offset) {
Niels Möller5a6ae022019-01-21 11:59:10 +010071 RTC_DCHECK(file_);
Niels Möller7ba3b812019-08-06 09:58:56 +020072 return fseek(file_, rtc::checked_cast<long>(offset), SEEK_CUR) == 0;
73}
74
75bool FileWrapper::SeekTo(int64_t position) {
76 RTC_DCHECK(file_);
77 return fseek(file_, rtc::checked_cast<long>(position), SEEK_SET) == 0;
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000078}
79
Björn Tereliuscbd61562021-03-25 15:52:16 +010080long FileWrapper::FileSize() {
81 if (file_ == nullptr)
82 return -1;
83 long original_position = ftell(file_);
84 if (original_position < 0)
85 return -1;
86 int seek_error = fseek(file_, 0, SEEK_END);
87 if (seek_error)
88 return -1;
89 long file_size = ftell(file_);
90 seek_error = fseek(file_, original_position, SEEK_SET);
91 if (seek_error)
92 return -1;
93 return file_size;
94}
95
Niels Möller5a6ae022019-01-21 11:59:10 +010096bool FileWrapper::Flush() {
97 RTC_DCHECK(file_);
98 return fflush(file_) == 0;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000099}
100
Niels Möller5a6ae022019-01-21 11:59:10 +0100101size_t FileWrapper::Read(void* buf, size_t length) {
102 RTC_DCHECK(file_);
103 return fread(buf, 1, length, file_);
tommia6219cc2016-06-15 10:30:14 -0700104}
105
Niels Möller7ba3b812019-08-06 09:58:56 +0200106bool FileWrapper::ReadEof() const {
107 RTC_DCHECK(file_);
108 return feof(file_);
109}
110
tommia6219cc2016-06-15 10:30:14 -0700111bool FileWrapper::Write(const void* buf, size_t length) {
Niels Möller5a6ae022019-01-21 11:59:10 +0100112 RTC_DCHECK(file_);
113 return fwrite(buf, 1, length, file_) == length;
114}
Niels Moller46647272019-01-18 12:04:43 +0000115
Niels Möller5a6ae022019-01-21 11:59:10 +0100116bool FileWrapper::Close() {
Niels Moller46647272019-01-18 12:04:43 +0000117 if (file_ == nullptr)
Niels Möller5a6ae022019-01-21 11:59:10 +0100118 return true;
Niels Moller46647272019-01-18 12:04:43 +0000119
Niels Möller5a6ae022019-01-21 11:59:10 +0100120 bool success = fclose(file_) == 0;
tommia6219cc2016-06-15 10:30:14 -0700121 file_ = nullptr;
Niels Möller5a6ae022019-01-21 11:59:10 +0100122 return success;
tommia6219cc2016-06-15 10:30:14 -0700123}
124
Per Åhgrenb8a96302020-05-07 15:58:55 +0200125FILE* FileWrapper::Release() {
126 FILE* file = file_;
127 file_ = nullptr;
128 return file;
129}
130
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000131} // namespace webrtc