• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "rtc_base/system/file_wrapper.h"
12 
13 #include <cerrno>
14 
15 #include "absl/strings/string_view.h"
16 #include "rtc_base/numerics/safe_conversions.h"
17 
18 #ifdef _WIN32
19 #include <Windows.h>
20 #else
21 #include <string.h>
22 #endif
23 
24 #include <utility>
25 
26 namespace webrtc {
27 namespace {
FileOpen(absl::string_view file_name_utf8,bool read_only,int * error)28 FILE* FileOpen(absl::string_view file_name_utf8, bool read_only, int* error) {
29   RTC_CHECK_EQ(file_name_utf8.find_first_of('\0'), absl::string_view::npos)
30       << "Invalid filename, containing NUL character";
31   std::string file_name(file_name_utf8);
32 #if defined(_WIN32)
33   int len = MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, nullptr, 0);
34   std::wstring wstr(len, 0);
35   MultiByteToWideChar(CP_UTF8, 0, file_name.c_str(), -1, &wstr[0], len);
36   FILE* file = _wfopen(wstr.c_str(), read_only ? L"rb" : L"wb");
37 #else
38   FILE* file = fopen(file_name.c_str(), read_only ? "rb" : "wb");
39 #endif
40   if (!file && error) {
41     *error = errno;
42   }
43   return file;
44 }
45 
46 }  // namespace
47 
48 // static
OpenReadOnly(absl::string_view file_name_utf8)49 FileWrapper FileWrapper::OpenReadOnly(absl::string_view file_name_utf8) {
50   return FileWrapper(FileOpen(file_name_utf8, true, nullptr));
51 }
52 
53 // static
OpenWriteOnly(absl::string_view file_name_utf8,int * error)54 FileWrapper FileWrapper::OpenWriteOnly(absl::string_view file_name_utf8,
55                                        int* error /*=nullptr*/) {
56   return FileWrapper(FileOpen(file_name_utf8, false, error));
57 }
58 
FileWrapper(FileWrapper && other)59 FileWrapper::FileWrapper(FileWrapper&& other) {
60   operator=(std::move(other));
61 }
62 
operator =(FileWrapper && other)63 FileWrapper& FileWrapper::operator=(FileWrapper&& other) {
64   Close();
65   file_ = other.file_;
66   other.file_ = nullptr;
67   return *this;
68 }
69 
SeekRelative(int64_t offset)70 bool FileWrapper::SeekRelative(int64_t offset) {
71   RTC_DCHECK(file_);
72   return fseek(file_, rtc::checked_cast<long>(offset), SEEK_CUR) == 0;
73 }
74 
SeekTo(int64_t position)75 bool FileWrapper::SeekTo(int64_t position) {
76   RTC_DCHECK(file_);
77   return fseek(file_, rtc::checked_cast<long>(position), SEEK_SET) == 0;
78 }
79 
FileSize()80 long FileWrapper::FileSize() {
81   if (file_ == nullptr)
82     return -1;
83   long original_position = ftell(file_);
84   if (original_position < 0)
85     return -1;
86   int seek_error = fseek(file_, 0, SEEK_END);
87   if (seek_error)
88     return -1;
89   long file_size = ftell(file_);
90   seek_error = fseek(file_, original_position, SEEK_SET);
91   if (seek_error)
92     return -1;
93   return file_size;
94 }
95 
Flush()96 bool FileWrapper::Flush() {
97   RTC_DCHECK(file_);
98   return fflush(file_) == 0;
99 }
100 
Read(void * buf,size_t length)101 size_t FileWrapper::Read(void* buf, size_t length) {
102   RTC_DCHECK(file_);
103   return fread(buf, 1, length, file_);
104 }
105 
ReadEof() const106 bool FileWrapper::ReadEof() const {
107   RTC_DCHECK(file_);
108   return feof(file_);
109 }
110 
Write(const void * buf,size_t length)111 bool FileWrapper::Write(const void* buf, size_t length) {
112   RTC_DCHECK(file_);
113   return fwrite(buf, 1, length, file_) == length;
114 }
115 
Close()116 bool FileWrapper::Close() {
117   if (file_ == nullptr)
118     return true;
119 
120   bool success = fclose(file_) == 0;
121   file_ = nullptr;
122   return success;
123 }
124 
Release()125 FILE* FileWrapper::Release() {
126   FILE* file = file_;
127   file_ = nullptr;
128   return file;
129 }
130 
131 }  // namespace webrtc
132