blob: 72f5f259dbdf689a03584bbcd7515b11b9ab5038 [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
13#ifdef _WIN32
andrew@webrtc.org114c7902011-12-10 02:33:33 +000014#include <Windows.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015#else
andrew@webrtc.org114c7902011-12-10 02:33:33 +000016#include <stdarg.h>
17#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000018#endif
19
Karl Wiberg6a4d4112018-03-23 10:39:34 +010020#include <utility>
21
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/checks.h"
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000023
niklase@google.com470e71d2011-07-07 08:21:25 +000024namespace webrtc {
tommia6219cc2016-06-15 10:30:14 -070025namespace {
26FILE* FileOpen(const char* file_name_utf8, bool read_only) {
27#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
tommia6219cc2016-06-15 10:30:14 -070035 return file;
36}
37} // namespace
niklase@google.com470e71d2011-07-07 08:21:25 +000038
tommia6219cc2016-06-15 10:30:14 -070039// static
40FileWrapper* FileWrapper::Create() {
41 return new FileWrapper();
phoglund@webrtc.org740be442012-12-12 12:52:15 +000042}
43
tommia6219cc2016-06-15 10:30:14 -070044// static
45FileWrapper FileWrapper::Open(const char* file_name_utf8, bool read_only) {
46 return FileWrapper(FileOpen(file_name_utf8, read_only), 0);
henrikg@webrtc.org863b5362013-12-06 16:05:17 +000047}
48
tommia6219cc2016-06-15 10:30:14 -070049FileWrapper::FileWrapper() {}
andrew@webrtc.org114c7902011-12-10 02:33:33 +000050
tommia6219cc2016-06-15 10:30:14 -070051FileWrapper::FileWrapper(FILE* file, size_t max_size)
52 : file_(file), max_size_in_bytes_(max_size) {}
53
54FileWrapper::~FileWrapper() {
55 CloseFileImpl();
phoglund@webrtc.org740be442012-12-12 12:52:15 +000056}
57
tommia6219cc2016-06-15 10:30:14 -070058FileWrapper::FileWrapper(FileWrapper&& other) {
59 operator=(std::move(other));
phoglund@webrtc.org740be442012-12-12 12:52:15 +000060}
61
tommia6219cc2016-06-15 10:30:14 -070062FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
63 file_ = other.file_;
64 max_size_in_bytes_ = other.max_size_in_bytes_;
65 position_ = other.position_;
66 other.file_ = nullptr;
67 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +000068}
andrew@webrtc.org5ae19de2011-12-13 22:59:33 +000069
tommia6219cc2016-06-15 10:30:14 -070070void FileWrapper::CloseFile() {
71 rtc::CritScope lock(&lock_);
72 CloseFileImpl();
henrike@webrtc.org9a6dac42012-09-27 22:20:34 +000073}
74
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000075int FileWrapper::Rewind() {
tommia6219cc2016-06-15 10:30:14 -070076 rtc::CritScope lock(&lock_);
77 if (file_ != nullptr) {
78 position_ = 0;
79 return fseek(file_, 0, SEEK_SET);
80 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000081 return -1;
82}
83
tommia6219cc2016-06-15 10:30:14 -070084void FileWrapper::SetMaxFileSize(size_t bytes) {
85 rtc::CritScope lock(&lock_);
86 max_size_in_bytes_ = bytes;
87}
88
89int FileWrapper::Flush() {
90 rtc::CritScope lock(&lock_);
91 return FlushImpl();
92}
93
94bool FileWrapper::OpenFile(const char* file_name_utf8, bool read_only) {
95 size_t length = strlen(file_name_utf8);
96 if (length > kMaxFileNameSize - 1)
97 return false;
98
99 rtc::CritScope lock(&lock_);
100 if (file_ != nullptr)
101 return false;
102
103 file_ = FileOpen(file_name_utf8, read_only);
104 return file_ != nullptr;
105}
106
107bool FileWrapper::OpenFromFileHandle(FILE* handle) {
108 if (!handle)
109 return false;
110 rtc::CritScope lock(&lock_);
111 CloseFileImpl();
112 file_ = handle;
113 return true;
114}
115
116int FileWrapper::Read(void* buf, size_t length) {
117 rtc::CritScope lock(&lock_);
118 if (file_ == nullptr)
119 return -1;
120
121 size_t bytes_read = fread(buf, 1, length, file_);
122 return static_cast<int>(bytes_read);
123}
124
125bool FileWrapper::Write(const void* buf, size_t length) {
126 if (buf == nullptr)
127 return false;
128
129 rtc::CritScope lock(&lock_);
130
131 if (file_ == nullptr)
132 return false;
133
134 // Check if it's time to stop writing.
135 if (max_size_in_bytes_ > 0 && (position_ + length) > max_size_in_bytes_)
136 return false;
137
138 size_t num_bytes = fwrite(buf, 1, length, file_);
139 position_ += num_bytes;
140
141 return num_bytes == length;
142}
143
144void FileWrapper::CloseFileImpl() {
145 if (file_ != nullptr)
146 fclose(file_);
147 file_ = nullptr;
148}
149
150int FileWrapper::FlushImpl() {
151 return (file_ != nullptr) ? fflush(file_) : -1;
152}
153
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000154} // namespace webrtc