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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
// 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/base/source_location.h"
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include "base/check.h"
#include "base/check_op.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
namespace remoting {
struct SourceLocation::BackingStore {
std::string function_name;
std::string file_name;
};
SourceLocation::SourceLocation() = default;
SourceLocation::~SourceLocation() = default;
// The default move constructor is sufficient since the backing store remains
// unmodified except for the transfer of its ownership, so the string pointers
// will remain valid.
SourceLocation::SourceLocation(SourceLocation&&) = default;
SourceLocation::SourceLocation(const SourceLocation& other) {
operator=(other);
}
SourceLocation::SourceLocation(const base::Location& location) {
if (location.has_source_info()) {
function_name_ = location.function_name();
file_name_ = location.file_name();
line_number_ = location.line_number();
DCHECK(function_name_);
DCHECK(file_name_);
DCHECK_GT(line_number_, -1);
} else if (location.program_counter() != nullptr) {
// We don't log a warning if the location is uninitialized.
LOG(WARNING) << "Location " << location.ToString()
<< " does not have source info.";
}
}
SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
SourceLocation& SourceLocation::operator=(const SourceLocation& other) {
if (other.backing_store_) {
backing_store_ = std::make_unique<BackingStore>(*other.backing_store_);
function_name_ = backing_store_->function_name.data();
file_name_ = backing_store_->file_name.data();
} else {
function_name_ = other.function_name_;
file_name_ = other.file_name_;
}
line_number_ = other.line_number();
return *this;
}
bool SourceLocation::operator==(const SourceLocation& other) const {
if (is_null() != other.is_null()) {
return false;
}
if (is_null() && other.is_null()) {
return true;
}
return std::string_view(function_name_) == other.function_name_ &&
std::string_view(file_name_) == other.file_name_ &&
line_number_ == other.line_number_;
}
std::string SourceLocation::ToString() const {
if (is_null()) {
return "<null source info>";
}
return std::string(function_name()) + "@" + file_name() + ":" +
base::NumberToString(line_number());
}
bool SourceLocation::HasBackingStoreForTesting() const {
return backing_store_ != nullptr;
}
// static
SourceLocation SourceLocation::CreateWithBackingStoreForTesting(
std::optional<std::string_view> function_name,
std::optional<std::string_view> file_name,
int line_number) {
SourceLocation location;
location.InitializeWithBackingStore(function_name, file_name, line_number);
return location;
}
void SourceLocation::InitializeWithBackingStore(
std::optional<std::string_view> function_name,
std::optional<std::string_view> file_name,
int line_number) {
if (!function_name.has_value() || !file_name.has_value()) {
return;
}
DCHECK_GT(line_number, -1);
backing_store_ = std::make_unique<BackingStore>();
backing_store_->function_name = *function_name;
backing_store_->file_name = *file_name;
function_name_ = backing_store_->function_name.data();
file_name_ = backing_store_->file_name.data();
line_number_ = line_number;
}
} // namespace remoting
|