summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/rtc_event_log_output_file.cc
blob: e1d4c7c711e55d48e45aa325fc5f3ba3b44d443f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 *  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