blob: c2122f20aa6021b772f92c0a92acdaf3a675eea3 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/feedback/utils/inspect_node_manager.h"
#include <algorithm>
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/split_string.h"
namespace feedback {
namespace {
// The ASCII bell character (0x07) will be used to replace all backslashes.
constexpr uint8_t kBackslashReplacement = 0x07;
void ReplaceCharInString(char to_replace, char replace_with, std::string* str) {
for (size_t i = 0; i < str->size(); ++i) {
if ((*str)[i] == to_replace) {
(*str)[i] = replace_with;
}
}
}
} // namespace
using fxl::kSplitWantNonEmpty;
using fxl::kTrimWhitespace;
using fxl::SplitStringCopy;
using inspect::Node;
bool InspectNodeManager::ManagedNodeBase::HasChild(const std::string& child) const {
return children_.find(child) != children_.end();
}
InspectNodeManager::ManagedNode& InspectNodeManager::ManagedNodeBase::GetChild(
const std::string& child) {
if (!HasChild(child)) {
children_.emplace(child, ManagedNode(GetNode().CreateChild(child)));
}
return children_.at(child);
}
bool InspectNodeManager::ManagedNodeBase::RemoveChild(const std::string& child) {
return children_.erase(child) != 0;
}
Node& InspectNodeManager::Get(const std::string& path) {
ManagedNodeBase* node = &root_;
const auto split_path = SplitAndDesanitize(path);
for (auto child : split_path) {
// Create the child if it doesn't exist, then get the child.
node = &node->GetChild(child);
}
return node->GetNode();
}
bool InspectNodeManager::Remove(const std::string& path) {
ManagedNodeBase* node = &root_;
const auto split_path = SplitAndDesanitize(path);
// Find the parent node.
for (size_t i = 0; i < split_path.size() - 1; ++i) {
// Return early if a node in the path doesn't exist.
if (!node->HasChild(split_path[i])) {
return false;
}
node = &node->GetChild(split_path[i]);
}
return node->RemoveChild(split_path.back());
}
std::string InspectNodeManager::SanitizeString(std::string str) {
ReplaceCharInString('/', kBackslashReplacement, &str);
return str;
}
std::vector<std::string> InspectNodeManager::SplitAndDesanitize(const std::string& path) {
std::vector<std::string> split_path =
SplitStringCopy(path, "/", kTrimWhitespace, kSplitWantNonEmpty);
for (auto& part : split_path) {
ReplaceCharInString(kBackslashReplacement, '/', &part);
}
return split_path;
}
} // namespace feedback