Line data Source code
1 : /*
2 : * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 : *
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 :
11 : #include "webrtc/system_wrappers/include/file_wrapper.h"
12 :
13 : #ifdef _WIN32
14 : #include <Windows.h>
15 : #else
16 : #include <stdarg.h>
17 : #include <string.h>
18 : #endif
19 :
20 : #include "webrtc/base/checks.h"
21 :
22 : namespace webrtc {
23 : namespace {
24 0 : FILE* FileOpen(const char* file_name_utf8, bool read_only) {
25 : #if defined(_WIN32)
26 : int len = MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, nullptr, 0);
27 : std::wstring wstr(len, 0);
28 : MultiByteToWideChar(CP_UTF8, 0, file_name_utf8, -1, &wstr[0], len);
29 : FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
30 : #else
31 0 : FILE* file = fopen(file_name_utf8, read_only ? "rb" : "wb");
32 : #endif
33 0 : return file;
34 : }
35 : } // namespace
36 :
37 : // static
38 0 : FileWrapper* FileWrapper::Create() {
39 0 : return new FileWrapper();
40 : }
41 :
42 : // static
43 0 : FileWrapper FileWrapper::Open(const char* file_name_utf8, bool read_only) {
44 0 : return FileWrapper(FileOpen(file_name_utf8, read_only), 0);
45 : }
46 :
47 0 : FileWrapper::FileWrapper() {}
48 :
49 0 : FileWrapper::FileWrapper(FILE* file, size_t max_size)
50 0 : : file_(file), max_size_in_bytes_(max_size) {}
51 :
52 0 : FileWrapper::~FileWrapper() {
53 0 : CloseFileImpl();
54 0 : }
55 :
56 0 : FileWrapper::FileWrapper(FileWrapper&& other) {
57 0 : operator=(std::move(other));
58 0 : }
59 :
60 0 : FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
61 0 : file_ = other.file_;
62 0 : max_size_in_bytes_ = other.max_size_in_bytes_;
63 0 : position_ = other.position_;
64 0 : other.file_ = nullptr;
65 0 : return *this;
66 : }
67 :
68 0 : void FileWrapper::CloseFile() {
69 0 : rtc::CritScope lock(&lock_);
70 0 : CloseFileImpl();
71 0 : }
72 :
73 0 : int FileWrapper::Rewind() {
74 0 : rtc::CritScope lock(&lock_);
75 0 : if (file_ != nullptr) {
76 0 : position_ = 0;
77 0 : return fseek(file_, 0, SEEK_SET);
78 : }
79 0 : return -1;
80 : }
81 :
82 0 : void FileWrapper::SetMaxFileSize(size_t bytes) {
83 0 : rtc::CritScope lock(&lock_);
84 0 : max_size_in_bytes_ = bytes;
85 0 : }
86 :
87 0 : int FileWrapper::Flush() {
88 0 : rtc::CritScope lock(&lock_);
89 0 : return FlushImpl();
90 : }
91 :
92 0 : bool FileWrapper::OpenFile(const char* file_name_utf8, bool read_only) {
93 0 : size_t length = strlen(file_name_utf8);
94 0 : if (length > kMaxFileNameSize - 1)
95 0 : return false;
96 :
97 0 : rtc::CritScope lock(&lock_);
98 0 : if (file_ != nullptr)
99 0 : return false;
100 :
101 0 : file_ = FileOpen(file_name_utf8, read_only);
102 0 : return file_ != nullptr;
103 : }
104 :
105 0 : bool FileWrapper::OpenFromFileHandle(FILE* handle) {
106 0 : if (!handle)
107 0 : return false;
108 0 : rtc::CritScope lock(&lock_);
109 0 : CloseFileImpl();
110 0 : file_ = handle;
111 0 : return true;
112 : }
113 :
114 0 : int FileWrapper::Read(void* buf, size_t length) {
115 0 : rtc::CritScope lock(&lock_);
116 0 : if (file_ == nullptr)
117 0 : return -1;
118 :
119 0 : size_t bytes_read = fread(buf, 1, length, file_);
120 0 : return static_cast<int>(bytes_read);
121 : }
122 :
123 0 : bool FileWrapper::Write(const void* buf, size_t length) {
124 0 : if (buf == nullptr)
125 0 : return false;
126 :
127 0 : rtc::CritScope lock(&lock_);
128 :
129 0 : if (file_ == nullptr)
130 0 : return false;
131 :
132 : // Check if it's time to stop writing.
133 0 : if (max_size_in_bytes_ > 0 && (position_ + length) > max_size_in_bytes_)
134 0 : return false;
135 :
136 0 : size_t num_bytes = fwrite(buf, 1, length, file_);
137 0 : position_ += num_bytes;
138 :
139 0 : return num_bytes == length;
140 : }
141 :
142 0 : void FileWrapper::CloseFileImpl() {
143 0 : if (file_ != nullptr)
144 0 : fclose(file_);
145 0 : file_ = nullptr;
146 0 : }
147 :
148 0 : int FileWrapper::FlushImpl() {
149 0 : return (file_ != nullptr) ? fflush(file_) : -1;
150 : }
151 :
152 : } // namespace webrtc
|