blob: 5409d74ef6d64592c2ca7d62ae617a653efcd72d [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"
Niels Möller7ba3b812019-08-06 09:58:56 +020012#include "rtc_base/numerics/safe_conversions.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000013
Niels Möller23213d92019-01-22 11:01:24 +010014#include <cerrno>
15
niklase@google.com470e71d2011-07-07 08:21:25 +000016#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000017#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000018#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000019#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000020#endif
21
Karl Wiberg6a4d4112018-03-23 10:39:34 +010022#include <utility>
23
niklase@google.com470e71d2011-07-07 08:21:25 +000024namespace webrtc {
tommia6219cc2016-06-15 10:30:14 -070025namespace {
Niels Möller23213d92019-01-22 11:01:24 +010026FILE* FileOpen(const char* file_name_utf8, bool read_only, int* error) {
tommia6219cc2016-06-15 10:30:14 -070027#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:25 +000032#else
tommia6219cc2016-06-15 10:30:14 -070033 FILE* file = fopen(file_name_utf8, read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000034#endif
Niels Möller23213d92019-01-22 11:01:24 +010035 if (!file && error) {
36 *error = errno;
37 }
tommia6219cc2016-06-15 10:30:14 -070038 return file;
39}
Niels Möller23213d92019-01-22 11:01:24 +010040
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 10:30:14 -070047} // namespace
niklase@google.com470e71d2011-07-07 08:21:25 +000048
tommia6219cc2016-06-15 10:30:14 -070049// static
Niels Möller5a6ae022019-01-21 11:59:10 +010050FileWrapper FileWrapper::OpenReadOnly(const char* file_name_utf8) {
Niels Möller23213d92019-01-22 11:01:24 +010051 return FileWrapper(FileOpen(file_name_utf8, true, nullptr));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000052}
53
tommia6219cc2016-06-15 10:30:14 -070054// static
Niels Möller23213d92019-01-22 11:01:24 +010055FileWrapper 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:15 +000069}
70
tommia6219cc2016-06-15 10:30:14 -070071FileWrapper::FileWrapper(FileWrapper&& other) {
72 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000073}
74
tommia6219cc2016-06-15 10:30:14 -070075FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
Niels Möller5a6ae022019-01-21 11:59:10 +010076 Close();
tommia6219cc2016-06-15 10:30:14 -070077 file_ = other.file_;
tommia6219cc2016-06-15 10:30:14 -070078 other.file_ = nullptr;
79 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +000080}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000081
Niels Möller7ba3b812019-08-06 09:58:56 +020082bool FileWrapper::SeekRelative(int64_t offset) {
Niels Möller5a6ae022019-01-21 11:59:10 +010083 RTC_DCHECK(file_);
Niels Möller7ba3b812019-08-06 09:58:56 +020084 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:34 +000090}
91
Niels Möller5a6ae022019-01-21 11:59:10 +010092bool FileWrapper::Flush() {
93 RTC_DCHECK(file_);
94 return fflush(file_) == 0;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000095}
96
Niels Möller5a6ae022019-01-21 11:59:10 +010097size_t FileWrapper::Read(void* buf, size_t length) {
98 RTC_DCHECK(file_);
99 return fread(buf, 1, length, file_);
tommia6219cc2016-06-15 10:30:14 -0700100}
101
Niels Möller7ba3b812019-08-06 09:58:56 +0200102bool FileWrapper::ReadEof() const {
103 RTC_DCHECK(file_);
104 return feof(file_);
105}
106
tommia6219cc2016-06-15 10:30:14 -0700107bool FileWrapper::Write(const void* buf, size_t length) {
Niels Möller5a6ae022019-01-21 11:59:10 +0100108 RTC_DCHECK(file_);
109 return fwrite(buf, 1, length, file_) == length;
110}
Niels Moller46647272019-01-18 12:04:43 +0000111
Niels Möller5a6ae022019-01-21 11:59:10 +0100112bool FileWrapper::Close() {
Niels Moller46647272019-01-18 12:04:43 +0000113 if (file_ == nullptr)
Niels Möller5a6ae022019-01-21 11:59:10 +0100114 return true;
Niels Moller46647272019-01-18 12:04:43 +0000115
Niels Möller5a6ae022019-01-21 11:59:10 +0100116 bool success = fclose(file_) == 0;
tommia6219cc2016-06-15 10:30:14 -0700117 file_ = nullptr;
Niels Möller5a6ae022019-01-21 11:59:10 +0100118 return success;
tommia6219cc2016-06-15 10:30:14 -0700119}
120
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000121} // namespace webrtc