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 86 87 88
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/base/loggable.h"
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/location.h"
#include "base/types/expected.h"
namespace remoting {
class Loggable::Inner {
public:
Inner(base::Location from_here, std::string message)
: from_here(std::move(from_here)), message(std::move(message)) {}
Inner(const Inner&) = default;
Inner(Inner&&) = default;
Inner& operator=(const Inner&) = default;
Inner& operator=(Inner&&) = default;
base::Location from_here;
std::string message;
std::vector<std::pair<base::Location, std::string>> context;
};
Loggable::Loggable() = default;
Loggable::Loggable(base::Location from_here, std::string message)
: inner_(
std::make_unique<Inner>(std::move(from_here), std::move(message))) {}
Loggable::Loggable(const Loggable& other)
: inner_(std::make_unique<Inner>(*other.inner_)) {}
Loggable::Loggable(Loggable&&) = default;
Loggable& Loggable::operator=(const Loggable& other) {
if (this != &other) {
inner_ = std::make_unique<Inner>(*other.inner_);
}
return *this;
}
Loggable& Loggable::operator=(Loggable&&) = default;
Loggable::~Loggable() = default;
void Loggable::AddContext(base::Location from_here, std::string context) {
CHECK(inner_);
inner_->context.emplace_back(std::move(from_here), std::move(context));
}
base::unexpected<Loggable> Loggable::UnexpectedWithContext(
base::Location from_here,
std::string context) && {
AddContext(std::move(from_here), std::move(context));
return base::unexpected(std::move(*this));
}
std::string Loggable::ToString() const {
std::ostringstream str;
str << *this;
return str.str();
}
std::ostream& operator<<(std::ostream& ostream, const Loggable& loggable) {
CHECK(loggable.inner_);
ostream << "[" << loggable.inner_->from_here.file_name() << ":"
<< loggable.inner_->from_here.line_number() << "] "
<< loggable.inner_->message;
for (auto& [location, context] : loggable.inner_->context) {
ostream << std::endl
<< "... [" << location.file_name() << ":" << location.line_number()
<< "] " << context;
}
return ostream;
}
} // namespace remoting
|