blob: 9d99cefaac2673a85735312cd78dd997d781a39b [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
niklase@google.com470e71d2011-07-07 08:21:25 +000015#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000016#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000017#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000018#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000019#endif
20
Karl Wiberg6a4d4112018-03-23 10:39:34 +010021#include <utility>
22
niklase@google.com470e71d2011-07-07 08:21:25 +000023namespace webrtc {
tommia6219cc2016-06-15 10:30:14 -070024namespace {
Niels Möller23213d92019-01-22 11:01:24 +010025FILE* FileOpen(const char* file_name_utf8, bool read_only, int* error) {
tommia6219cc2016-06-15 10:30:14 -070026#if defined(_WIN32)
27 int len = MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, nullptr, 0);
28 std::wstring wstr(len, 0);
29 MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, &wstr[0], len);
30 FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000031#else
tommia6219cc2016-06-15 10:30:14 -070032 FILE* file = fopen(file_name_utf8, read_only ? "rb" : "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +000033#endif
Niels Möller23213d92019-01-22 11:01:24 +010034 if (!file && error) {
35 *error = errno;
36 }
tommia6219cc2016-06-15 10:30:14 -070037 return file;
38}
Niels Möller23213d92019-01-22 11:01:24 +010039
40const char* GetCstrCheckNoEmbeddedNul(const std::string& s) {
41 const char* p = s.c_str();
42 RTC_CHECK_EQ(strlen(p), s.size())
43 << "Invalid filename, containing NUL character";
44 return p;
45}
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
Niels Möller5a6ae022019-01-21 11:59:10 +010049FileWrapper FileWrapper::OpenReadOnly(const char* 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
Niels Möller23213d92019-01-22 11:01:24 +010054FileWrapper FileWrapper::OpenReadOnly(const std::string& file_name_utf8) {
55 return OpenReadOnly(GetCstrCheckNoEmbeddedNul(file_name_utf8));
56}
57
58// static
59FileWrapper FileWrapper::OpenWriteOnly(const char* file_name_utf8,
60 int* error /*=nullptr*/) {
61 return FileWrapper(FileOpen(file_name_utf8, false, error));
62}
63
64// static
65FileWrapper FileWrapper::OpenWriteOnly(const std::string& file_name_utf8,
66 int* error /*=nullptr*/) {
67 return OpenWriteOnly(GetCstrCheckNoEmbeddedNul(file_name_utf8), error);
phoglund@webrtc.org740be442012-12-12 12:52:15 +000068}
69
tommia6219cc2016-06-15 10:30:14 -070070FileWrapper::FileWrapper(FileWrapper&& other) {
71 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000072}
73
tommia6219cc2016-06-15 10:30:14 -070074FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
Niels Möller5a6ae022019-01-21 11:59:10 +010075 Close();
tommia6219cc2016-06-15 10:30:14 -070076 file_ = other.file_;
tommia6219cc2016-06-15 10:30:14 -070077 other.file_ = nullptr;
78 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000080
Niels Möller5a6ae022019-01-21 11:59:10 +010081bool FileWrapper::Rewind() {
82 RTC_DCHECK(file_);
83 return fseek(file_, 0, SEEK_SET) == 0;
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000084}
85
Niels Möller5a6ae022019-01-21 11:59:10 +010086bool FileWrapper::Flush() {
87 RTC_DCHECK(file_);
88 return fflush(file_) == 0;
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000089}
90
Niels Möller5a6ae022019-01-21 11:59:10 +010091size_t FileWrapper::Read(void* buf, size_t length) {
92 RTC_DCHECK(file_);
93 return fread(buf, 1, length, file_);
tommia6219cc2016-06-15 10:30:14 -070094}
95
96bool FileWrapper::Write(const void* buf, size_t length) {
Niels Möller5a6ae022019-01-21 11:59:10 +010097 RTC_DCHECK(file_);
98 return fwrite(buf, 1, length, file_) == length;
99}
Niels Moller46647272019-01-18 12:04:43 +0000100
Niels Möller5a6ae022019-01-21 11:59:10 +0100101bool FileWrapper::Close() {
Niels Moller46647272019-01-18 12:04:43 +0000102 if (file_ == nullptr)
Niels Möller5a6ae022019-01-21 11:59:10 +0100103 return true;
Niels Moller46647272019-01-18 12:04:43 +0000104
Niels Möller5a6ae022019-01-21 11:59:10 +0100105 bool success = fclose(file_) == 0;
tommia6219cc2016-06-15 10:30:14 -0700106 file_ = nullptr;
Niels Möller5a6ae022019-01-21 11:59:10 +0100107 return success;
tommia6219cc2016-06-15 10:30:14 -0700108}
109
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000110} // namespace webrtc