| /* | 
 |  *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include "api/rtc_event_log_output_file.h" | 
 |  | 
 | #include <limits> | 
 | #include <utility> | 
 |  | 
 | #include "api/rtc_event_log/rtc_event_log.h" | 
 | #include "rtc_base/checks.h" | 
 | #include "rtc_base/logging.h" | 
 |  | 
 | namespace webrtc { | 
 |  | 
 | // Together with the assumption of no single Write() would ever be called on | 
 | // an input with length greater-than-or-equal-to (max(size_t) / 2), this | 
 | // guarantees no overflow of the check for remaining file capacity in Write(). | 
 | // This does *not* apply to files with unlimited size. | 
 | const size_t RtcEventLogOutputFile::kMaxReasonableFileSize = | 
 |     std::numeric_limits<size_t>::max() / 2; | 
 |  | 
 | RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name) | 
 |     : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), | 
 |                             RtcEventLog::kUnlimitedOutput) {} | 
 |  | 
 | RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name, | 
 |                                              size_t max_size_bytes) | 
 |  | 
 |     // Unlike plain fopen, FileWrapper takes care of filename utf8 -> | 
 |     // wchar conversion on Windows. | 
 |     : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), | 
 |                             max_size_bytes) {} | 
 |  | 
 | RtcEventLogOutputFile::RtcEventLogOutputFile(FILE* file, size_t max_size_bytes) | 
 |     : RtcEventLogOutputFile(FileWrapper(file), max_size_bytes) {} | 
 |  | 
 | RtcEventLogOutputFile::RtcEventLogOutputFile(FileWrapper file, | 
 |                                              size_t max_size_bytes) | 
 |     : max_size_bytes_(max_size_bytes), file_(std::move(file)) { | 
 |   RTC_CHECK_LE(max_size_bytes_, kMaxReasonableFileSize); | 
 |   if (!file_.is_open()) { | 
 |     RTC_LOG(LS_ERROR) << "Invalid file. WebRTC event log not started."; | 
 |   } | 
 | } | 
 |  | 
 | bool RtcEventLogOutputFile::IsActive() const { | 
 |   return IsActiveInternal(); | 
 | } | 
 |  | 
 | bool RtcEventLogOutputFile::Write(absl::string_view output) { | 
 |   RTC_DCHECK(IsActiveInternal()); | 
 |   // No single write may be so big, that it would risk overflowing the | 
 |   // calculation of (written_bytes_ + output.length()). | 
 |   RTC_DCHECK_LT(output.size(), kMaxReasonableFileSize); | 
 |  | 
 |   if (max_size_bytes_ == RtcEventLog::kUnlimitedOutput || | 
 |       written_bytes_ + output.size() <= max_size_bytes_) { | 
 |     if (file_.Write(output.data(), output.size())) { | 
 |       written_bytes_ += output.size(); | 
 |       return true; | 
 |     } else { | 
 |       RTC_LOG(LS_ERROR) << "Write to WebRtcEventLog file failed."; | 
 |     } | 
 |   } else { | 
 |     RTC_LOG(LS_VERBOSE) << "Max file size reached."; | 
 |   } | 
 |  | 
 |   // Failed, for one of above reasons. Close output file. | 
 |   file_.Close(); | 
 |   return false; | 
 | } | 
 |  | 
 | // Internal non-virtual method. | 
 | bool RtcEventLogOutputFile::IsActiveInternal() const { | 
 |   return file_.is_open(); | 
 | } | 
 |  | 
 | }  // namespace webrtc |