tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

log_streamer.h (6304B)


      1 // Copyright 2022 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 // -----------------------------------------------------------------------------
     16 // File: log/log_streamer.h
     17 // -----------------------------------------------------------------------------
     18 //
     19 // This header declares the class `LogStreamer` and convenience functions to
     20 // construct LogStreamer objects with different associated log severity levels.
     21 
     22 #ifndef ABSL_LOG_LOG_STREAMER_H_
     23 #define ABSL_LOG_LOG_STREAMER_H_
     24 
     25 #include <ios>
     26 #include <memory>
     27 #include <ostream>
     28 #include <string>
     29 #include <utility>
     30 
     31 #include "absl/base/config.h"
     32 #include "absl/base/log_severity.h"
     33 #include "absl/log/absl_log.h"
     34 #include "absl/strings/internal/ostringstream.h"
     35 #include "absl/strings/string_view.h"
     36 #include "absl/types/optional.h"
     37 #include "absl/utility/utility.h"
     38 
     39 namespace absl {
     40 ABSL_NAMESPACE_BEGIN
     41 
     42 // LogStreamer
     43 //
     44 // Although you can stream into `LOG(INFO)`, you can't pass it into a function
     45 // that takes a `std::ostream` parameter. `LogStreamer::stream()` provides a
     46 // `std::ostream` that buffers everything that's streamed in.  The buffer's
     47 // contents are logged as if by `LOG` when the `LogStreamer` is destroyed.
     48 // If nothing is streamed in, an empty message is logged.  If the specified
     49 // severity is `absl::LogSeverity::kFatal`, the program will be terminated when
     50 // the `LogStreamer` is destroyed regardless of whether any data were streamed
     51 // in.
     52 //
     53 // Factory functions corresponding to the `absl::LogSeverity` enumerators
     54 // are provided for convenience; if the desired severity is variable, invoke the
     55 // constructor directly.
     56 //
     57 // LogStreamer is movable, but not copyable.
     58 //
     59 // Examples:
     60 //
     61 //   ShaveYakAndWriteToStream(
     62 //       yak, absl::LogInfoStreamer(__FILE__, __LINE__).stream());
     63 //
     64 //   {
     65 //     // This logs a single line containing data streamed by all three function
     66 //     // calls.
     67 //     absl::LogStreamer streamer(absl::LogSeverity::kInfo, __FILE__, __LINE__);
     68 //     ShaveYakAndWriteToStream(yak1, streamer.stream());
     69 //     streamer.stream() << " ";
     70 //     ShaveYakAndWriteToStream(yak2, streamer.stream());
     71 //     streamer.stream() << " ";
     72 //     ShaveYakAndWriteToStreamPointer(yak3, &streamer.stream());
     73 //   }
     74 class LogStreamer final {
     75 public:
     76  // LogStreamer::LogStreamer()
     77  //
     78  // Creates a LogStreamer with a given `severity` that will log a message
     79  // attributed to the given `file` and `line`.
     80  explicit LogStreamer(absl::LogSeverity severity, absl::string_view file,
     81                       int line)
     82      : severity_(severity),
     83        line_(line),
     84        file_(file),
     85        stream_(absl::in_place, &buf_) {
     86    // To match `LOG`'s defaults:
     87    stream_->setf(std::ios_base::showbase | std::ios_base::boolalpha);
     88  }
     89 
     90  // A moved-from `absl::LogStreamer` does not `LOG` when destroyed,
     91  // and a program that streams into one has undefined behavior.
     92  LogStreamer(LogStreamer&& that) noexcept
     93      : severity_(that.severity_),
     94        line_(that.line_),
     95        file_(std::move(that.file_)),
     96        buf_(std::move(that.buf_)),
     97        stream_(std::move(that.stream_)) {
     98    if (stream_.has_value()) stream_->str(&buf_);
     99    that.stream_.reset();
    100  }
    101  LogStreamer& operator=(LogStreamer&& that) {
    102    ABSL_LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_;
    103    severity_ = that.severity_;
    104    file_ = std::move(that.file_);
    105    line_ = that.line_;
    106    buf_ = std::move(that.buf_);
    107    stream_ = std::move(that.stream_);
    108    if (stream_.has_value()) stream_->str(&buf_);
    109    that.stream_.reset();
    110    return *this;
    111  }
    112 
    113  // LogStreamer::~LogStreamer()
    114  //
    115  // Logs this LogStreamer's buffered content as if by LOG.
    116  ~LogStreamer() {
    117    ABSL_LOG_IF(LEVEL(severity_), stream_.has_value()).AtLocation(file_, line_)
    118        << buf_;
    119  }
    120 
    121  // LogStreamer::stream()
    122  //
    123  // Returns the `std::ostream` to use to write into this LogStreamer' internal
    124  // buffer.
    125  std::ostream& stream() { return *stream_; }
    126 
    127 private:
    128  absl::LogSeverity severity_;
    129  int line_;
    130  std::string file_;
    131  std::string buf_;
    132  // A disengaged `stream_` indicates a moved-from `LogStreamer` that should not
    133  // `LOG` upon destruction.
    134  absl::optional<absl::strings_internal::OStringStream> stream_;
    135 };
    136 
    137 // LogInfoStreamer()
    138 //
    139 // Returns a LogStreamer that writes at level LogSeverity::kInfo.
    140 inline LogStreamer LogInfoStreamer(absl::string_view file, int line) {
    141  return absl::LogStreamer(absl::LogSeverity::kInfo, file, line);
    142 }
    143 
    144 // LogWarningStreamer()
    145 //
    146 // Returns a LogStreamer that writes at level LogSeverity::kWarning.
    147 inline LogStreamer LogWarningStreamer(absl::string_view file, int line) {
    148  return absl::LogStreamer(absl::LogSeverity::kWarning, file, line);
    149 }
    150 
    151 // LogErrorStreamer()
    152 //
    153 // Returns a LogStreamer that writes at level LogSeverity::kError.
    154 inline LogStreamer LogErrorStreamer(absl::string_view file, int line) {
    155  return absl::LogStreamer(absl::LogSeverity::kError, file, line);
    156 }
    157 
    158 // LogFatalStreamer()
    159 //
    160 // Returns a LogStreamer that writes at level LogSeverity::kFatal.
    161 //
    162 // The program will be terminated when this `LogStreamer` is destroyed,
    163 // regardless of whether any data were streamed in.
    164 inline LogStreamer LogFatalStreamer(absl::string_view file, int line) {
    165  return absl::LogStreamer(absl::LogSeverity::kFatal, file, line);
    166 }
    167 
    168 // LogDebugFatalStreamer()
    169 //
    170 // Returns a LogStreamer that writes at level LogSeverity::kLogDebugFatal.
    171 //
    172 // In debug mode, the program will be terminated when this `LogStreamer` is
    173 // destroyed, regardless of whether any data were streamed in.
    174 inline LogStreamer LogDebugFatalStreamer(absl::string_view file, int line) {
    175  return absl::LogStreamer(absl::kLogDebugFatal, file, line);
    176 }
    177 
    178 ABSL_NAMESPACE_END
    179 }  // namespace absl
    180 
    181 #endif  // ABSL_LOG_LOG_STREAMER_H_