rtc_event_log_output_file.cc (3195B)
1 /* 2 * Copyright (c) 2017 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 "api/rtc_event_log_output_file.h" 12 13 #include <cstddef> 14 #include <cstdio> 15 #include <limits> 16 #include <string> 17 #include <utility> 18 19 #include "absl/strings/string_view.h" 20 #include "api/rtc_event_log/rtc_event_log.h" 21 #include "rtc_base/checks.h" 22 #include "rtc_base/logging.h" 23 #include "rtc_base/system/file_wrapper.h" 24 25 namespace webrtc { 26 27 // Together with the assumption of no single Write() would ever be called on 28 // an input with length greater-than-or-equal-to (max(size_t) / 2), this 29 // guarantees no overflow of the check for remaining file capacity in Write(). 30 // This does *not* apply to files with unlimited size. 31 const size_t RtcEventLogOutputFile::kMaxReasonableFileSize = 32 std::numeric_limits<size_t>::max() / 2; 33 34 RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name) 35 : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), 36 RtcEventLog::kUnlimitedOutput) {} 37 38 RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name, 39 size_t max_size_bytes) 40 41 // Unlike plain fopen, FileWrapper takes care of filename utf8 -> 42 // wchar conversion on Windows. 43 : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), 44 max_size_bytes) {} 45 46 RtcEventLogOutputFile::RtcEventLogOutputFile(FILE* file, size_t max_size_bytes) 47 : RtcEventLogOutputFile(FileWrapper(file), max_size_bytes) {} 48 49 RtcEventLogOutputFile::RtcEventLogOutputFile(FileWrapper file, 50 size_t max_size_bytes) 51 : max_size_bytes_(max_size_bytes), file_(std::move(file)) { 52 RTC_CHECK_LE(max_size_bytes_, kMaxReasonableFileSize); 53 if (!file_.is_open()) { 54 RTC_LOG(LS_ERROR) << "Invalid file. WebRTC event log not started."; 55 } 56 } 57 58 bool RtcEventLogOutputFile::IsActive() const { 59 return IsActiveInternal(); 60 } 61 62 bool RtcEventLogOutputFile::Write(absl::string_view output) { 63 RTC_DCHECK(IsActiveInternal()); 64 // No single write may be so big, that it would risk overflowing the 65 // calculation of (written_bytes_ + output.length()). 66 RTC_DCHECK_LT(output.size(), kMaxReasonableFileSize); 67 68 if (max_size_bytes_ == RtcEventLog::kUnlimitedOutput || 69 written_bytes_ + output.size() <= max_size_bytes_) { 70 if (file_.Write(output.data(), output.size())) { 71 written_bytes_ += output.size(); 72 return true; 73 } else { 74 RTC_LOG(LS_ERROR) << "Write to WebRtcEventLog file failed."; 75 } 76 } else { 77 RTC_LOG(LS_VERBOSE) << "Max file size reached."; 78 } 79 80 // Failed, for one of above reasons. Close output file. 81 file_.Close(); 82 return false; 83 } 84 85 // Internal non-virtual method. 86 bool RtcEventLogOutputFile::IsActiveInternal() const { 87 return file_.is_open(); 88 } 89 90 } // namespace webrtc