blob: af34d0e4115fa38f427c9e263fedca02bb668f22 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:251/*
henrike@webrtc.org143abd92012-02-08 19:39:382 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:253 *
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 09:39:3411#include "rtc_base/system/file_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:2512
Harald Alvestrandecc38d82023-10-24 09:04:3113#include <stddef.h>
14
Niels Möller23213d92019-01-22 10:01:2415#include <cerrno>
Harald Alvestrandecc38d82023-10-24 09:04:3116#include <cstdint>
17#include <string>
Niels Möller23213d92019-01-22 10:01:2418
Ali Tofigh2ab914c2022-04-13 10:55:1519#include "absl/strings/string_view.h"
Harald Alvestrandecc38d82023-10-24 09:04:3120#include "rtc_base/checks.h"
Ali Tofigh2ab914c2022-04-13 10:55:1521#include "rtc_base/numerics/safe_conversions.h"
22
niklase@google.com470e71d2011-07-07 08:21:2523#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:3324#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:2525#else
niklase@google.com470e71d2011-07-07 08:21:2526#endif
27
Karl Wiberg6a4d4112018-03-23 09:39:3428#include <utility>
29
niklase@google.com470e71d2011-07-07 08:21:2530namespace webrtc {
tommia6219cc2016-06-15 17:30:1431namespace {
Ali Tofigh2ab914c2022-04-13 10:55:1532FILE* FileOpen(absl::string_view file_name_utf8, bool read_only, int* error) {
33 RTC_CHECK_EQ(file_name_utf8.find_first_of('\0'), absl::string_view::npos)
34 << "Invalid filename, containing NUL character";
Ali Tofigh98bfd992022-07-22 20:10:4935 std::string file_name(file_name_utf8);
tommia6219cc2016-06-15 17:30:1436#if defined(_WIN32)
Ali Tofigh2ab914c2022-04-13 10:55:1537 int len = MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, nullptr, 0);
tommia6219cc2016-06-15 17:30:1438 std::wstring wstr(len, 0);
Ali Tofigh2ab914c2022-04-13 10:55:1539 MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, &wstr[0], len);
tommia6219cc2016-06-15 17:30:1440 FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
niklase@google.com470e71d2011-07-07 08:21:2541#else
Ali Tofigh2ab914c2022-04-13 10:55:1542 FILE* file = fopen(file_name.c_str(), read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:2543#endif
Niels Möller23213d92019-01-22 10:01:2444 if (!file && error) {
45 *error = errno;
46 }
tommia6219cc2016-06-15 17:30:1447 return file;
48}
Niels Möller23213d92019-01-22 10:01:2449
tommia6219cc2016-06-15 17:30:1450} // namespace
niklase@google.com470e71d2011-07-07 08:21:2551
tommia6219cc2016-06-15 17:30:1452// static
Ali Tofigh2ab914c2022-04-13 10:55:1553FileWrapper FileWrapper::OpenReadOnly(absl::string_view file_name_utf8) {
Niels Möller23213d92019-01-22 10:01:2454 return FileWrapper(FileOpen(file_name_utf8, true, nullptr));
phoglund@webrtc.org740be442012-12-12 12:52:1555}
56
tommia6219cc2016-06-15 17:30:1457// static
Ali Tofigh2ab914c2022-04-13 10:55:1558FileWrapper FileWrapper::OpenWriteOnly(absl::string_view file_name_utf8,
Niels Möller23213d92019-01-22 10:01:2459 int* error /*=nullptr*/) {
60 return FileWrapper(FileOpen(file_name_utf8, false, error));
61}
62
tommia6219cc2016-06-15 17:30:1463FileWrapper::FileWrapper(FileWrapper&& other) {
64 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:1565}
66
tommia6219cc2016-06-15 17:30:1467FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
Niels Möller5a6ae022019-01-21 10:59:1068 Close();
tommia6219cc2016-06-15 17:30:1469 file_ = other.file_;
tommia6219cc2016-06-15 17:30:1470 other.file_ = nullptr;
71 return *this;
niklase@google.com470e71d2011-07-07 08:21:2572}
andrew@webrtc.org5ae19de2011-12-13 22:59:3373
Niels Möller7ba3b812019-08-06 07:58:5674bool FileWrapper::SeekRelative(int64_t offset) {
Niels Möller5a6ae022019-01-21 10:59:1075 RTC_DCHECK(file_);
Niels Möller7ba3b812019-08-06 07:58:5676 return fseek(file_, rtc::checked_cast<long>(offset), SEEK_CUR) == 0;
77}
78
79bool FileWrapper::SeekTo(int64_t position) {
80 RTC_DCHECK(file_);
81 return fseek(file_, rtc::checked_cast<long>(position), SEEK_SET) == 0;
henrike@webrtc.org9a6dac42012-09-27 22:20:3482}
83
Björn Tereliuscbd61562021-03-25 14:52:1684long FileWrapper::FileSize() {
85 if (file_ == nullptr)
86 return -1;
87 long original_position = ftell(file_);
88 if (original_position < 0)
89 return -1;
90 int seek_error = fseek(file_, 0, SEEK_END);
91 if (seek_error)
92 return -1;
93 long file_size = ftell(file_);
94 seek_error = fseek(file_, original_position, SEEK_SET);
95 if (seek_error)
96 return -1;
97 return file_size;
98}
99
Niels Möller5a6ae022019-01-21 10:59:10100bool FileWrapper::Flush() {
101 RTC_DCHECK(file_);
102 return fflush(file_) == 0;
kjellander@webrtc.org14665ff2015-03-04 12:58:35103}
104
Niels Möller5a6ae022019-01-21 10:59:10105size_t FileWrapper::Read(void* buf, size_t length) {
106 RTC_DCHECK(file_);
107 return fread(buf, 1, length, file_);
tommia6219cc2016-06-15 17:30:14108}
109
Niels Möller7ba3b812019-08-06 07:58:56110bool FileWrapper::ReadEof() const {
111 RTC_DCHECK(file_);
112 return feof(file_);
113}
114
tommia6219cc2016-06-15 17:30:14115bool FileWrapper::Write(const void* buf, size_t length) {
Niels Möller5a6ae022019-01-21 10:59:10116 RTC_DCHECK(file_);
117 return fwrite(buf, 1, length, file_) == length;
118}
Niels Moller46647272019-01-18 12:04:43119
Niels Möller5a6ae022019-01-21 10:59:10120bool FileWrapper::Close() {
Niels Moller46647272019-01-18 12:04:43121 if (file_ == nullptr)
Niels Möller5a6ae022019-01-21 10:59:10122 return true;
Niels Moller46647272019-01-18 12:04:43123
Niels Möller5a6ae022019-01-21 10:59:10124 bool success = fclose(file_) == 0;
tommia6219cc2016-06-15 17:30:14125 file_ = nullptr;
Niels Möller5a6ae022019-01-21 10:59:10126 return success;
tommia6219cc2016-06-15 17:30:14127}
128
Per Åhgrenb8a96302020-05-07 13:58:55129FILE* FileWrapper::Release() {
130 FILE* file = file_;
131 file_ = nullptr;
132 return file;
133}
134
pbos@webrtc.orgd900e8b2013-07-03 15:12:26135} // namespace webrtc