blob: 3e49315793f9cd3d96a57a05bc76b919564bf6fc [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"
Niels Möller7ba3b812019-08-06 07:58:5612#include "rtc_base/numerics/safe_conversions.h"
niklase@google.com470e71d2011-07-07 08:21:2513
Niels Möller23213d92019-01-22 10:01:2414#include <cerrno>
15
niklase@google.com470e71d2011-07-07 08:21:2516#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:3317#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:2518#else
andrew@webrtc.org114c7902011-12-10 02:33:3319#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:2520#endif
21
Karl Wiberg6a4d4112018-03-23 09:39:3422#include <utility>
23
niklase@google.com470e71d2011-07-07 08:21:2524namespace webrtc {
tommia6219cc2016-06-15 17:30:1425namespace {
Niels Möller23213d92019-01-22 10:01:2426FILE* FileOpen(const char* file_name_utf8, bool read_only, int* error) {
tommia6219cc2016-06-15 17:30:1427#if defined(_WIN32)
28 int len = MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, nullptr, 0);
29 std::wstring wstr(len, 0);
30 MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, &wstr[0], len);
31 FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
niklase@google.com470e71d2011-07-07 08:21:2532#else
tommia6219cc2016-06-15 17:30:1433 FILE* file = fopen(file_name_utf8, read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:2534#endif
Niels Möller23213d92019-01-22 10:01:2435 if (!file && error) {
36 *error = errno;
37 }
tommia6219cc2016-06-15 17:30:1438 return file;
39}
Niels Möller23213d92019-01-22 10:01:2440
41const char* GetCstrCheckNoEmbeddedNul(const std::string& s) {
42 const char* p = s.c_str();
43 RTC_CHECK_EQ(strlen(p), s.size())
44 << "Invalid filename, containing NUL character";
45 return p;
46}
tommia6219cc2016-06-15 17:30:1447} // namespace
niklase@google.com470e71d2011-07-07 08:21:2548
tommia6219cc2016-06-15 17:30:1449// static
Niels Möller5a6ae022019-01-21 10:59:1050FileWrapper FileWrapper::OpenReadOnly(const char* file_name_utf8) {
Niels Möller23213d92019-01-22 10:01:2451 return FileWrapper(FileOpen(file_name_utf8, true, nullptr));
phoglund@webrtc.org740be442012-12-12 12:52:1552}
53
tommia6219cc2016-06-15 17:30:1454// static
Niels Möller23213d92019-01-22 10:01:2455FileWrapper FileWrapper::OpenReadOnly(const std::string& file_name_utf8) {
56 return OpenReadOnly(GetCstrCheckNoEmbeddedNul(file_name_utf8));
57}
58
59// static
60FileWrapper FileWrapper::OpenWriteOnly(const char* file_name_utf8,
61 int* error /*=nullptr*/) {
62 return FileWrapper(FileOpen(file_name_utf8, false, error));
63}
64
65// static
66FileWrapper FileWrapper::OpenWriteOnly(const std::string& file_name_utf8,
67 int* error /*=nullptr*/) {
68 return OpenWriteOnly(GetCstrCheckNoEmbeddedNul(file_name_utf8), error);
phoglund@webrtc.org740be442012-12-12 12:52:1569}
70
tommia6219cc2016-06-15 17:30:1471FileWrapper::FileWrapper(FileWrapper&& other) {
72 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:1573}
74
tommia6219cc2016-06-15 17:30:1475FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
Niels Möller5a6ae022019-01-21 10:59:1076 Close();
tommia6219cc2016-06-15 17:30:1477 file_ = other.file_;
tommia6219cc2016-06-15 17:30:1478 other.file_ = nullptr;
79 return *this;
niklase@google.com470e71d2011-07-07 08:21:2580}
andrew@webrtc.org5ae19de2011-12-13 22:59:3381
Niels Möller7ba3b812019-08-06 07:58:5682bool FileWrapper::SeekRelative(int64_t offset) {
Niels Möller5a6ae022019-01-21 10:59:1083 RTC_DCHECK(file_);
Niels Möller7ba3b812019-08-06 07:58:5684 return fseek(file_, rtc::checked_cast<long>(offset), SEEK_CUR) == 0;
85}
86
87bool FileWrapper::SeekTo(int64_t position) {
88 RTC_DCHECK(file_);
89 return fseek(file_, rtc::checked_cast<long>(position), SEEK_SET) == 0;
henrike@webrtc.org9a6dac42012-09-27 22:20:3490}
91
Björn Tereliuscbd61562021-03-25 14:52:1692long FileWrapper::FileSize() {
93 if (file_ == nullptr)
94 return -1;
95 long original_position = ftell(file_);
96 if (original_position < 0)
97 return -1;
98 int seek_error = fseek(file_, 0, SEEK_END);
99 if (seek_error)
100 return -1;
101 long file_size = ftell(file_);
102 seek_error = fseek(file_, original_position, SEEK_SET);
103 if (seek_error)
104 return -1;
105 return file_size;
106}
107
Niels Möller5a6ae022019-01-21 10:59:10108bool FileWrapper::Flush() {
109 RTC_DCHECK(file_);
110 return fflush(file_) == 0;
kjellander@webrtc.org14665ff2015-03-04 12:58:35111}
112
Niels Möller5a6ae022019-01-21 10:59:10113size_t FileWrapper::Read(void* buf, size_t length) {
114 RTC_DCHECK(file_);
115 return fread(buf, 1, length, file_);
tommia6219cc2016-06-15 17:30:14116}
117
Niels Möller7ba3b812019-08-06 07:58:56118bool FileWrapper::ReadEof() const {
119 RTC_DCHECK(file_);
120 return feof(file_);
121}
122
tommia6219cc2016-06-15 17:30:14123bool FileWrapper::Write(const void* buf, size_t length) {
Niels Möller5a6ae022019-01-21 10:59:10124 RTC_DCHECK(file_);
125 return fwrite(buf, 1, length, file_) == length;
126}
Niels Moller46647272019-01-18 12:04:43127
Niels Möller5a6ae022019-01-21 10:59:10128bool FileWrapper::Close() {
Niels Moller46647272019-01-18 12:04:43129 if (file_ == nullptr)
Niels Möller5a6ae022019-01-21 10:59:10130 return true;
Niels Moller46647272019-01-18 12:04:43131
Niels Möller5a6ae022019-01-21 10:59:10132 bool success = fclose(file_) == 0;
tommia6219cc2016-06-15 17:30:14133 file_ = nullptr;
Niels Möller5a6ae022019-01-21 10:59:10134 return success;
tommia6219cc2016-06-15 17:30:14135}
136
Per Åhgrenb8a96302020-05-07 13:58:55137FILE* FileWrapper::Release() {
138 FILE* file = file_;
139 file_ = nullptr;
140 return file;
141}
142
pbos@webrtc.orgd900e8b2013-07-03 15:12:26143} // namespace webrtc