Files
rippled/src/libxrpl/beast/utility/beast_PropertyStream.cpp
Pratik Mankawde f4555c80fe fix: revert all unrelated upstream develop changes from phase-7 PR
Reverts 259 files that carried unrelated upstream changes through the
phase-6 merge: enum class removals (cppcoreguidelines-use-enum-class),
scoped_lock→lock_guard conversions (modernize-use-scoped-lock),
nodestore Backend API changes (void const* key), .clang-tidy config,
test infrastructure deletions, and miscellaneous develop changes.

These changes belong on develop, not in the telemetry PR chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 16:59:24 +01:00

569 lines
10 KiB
C++

#include <xrpl/beast/core/List.h>
#include <xrpl/beast/utility/PropertyStream.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <algorithm>
#include <iostream>
#include <mutex>
#include <string>
#include <utility>
namespace beast {
//------------------------------------------------------------------------------
//
// Item
//
//------------------------------------------------------------------------------
PropertyStream::Item::Item(Source* source) : m_source(source)
{
}
PropertyStream::Source&
PropertyStream::Item::source() const
{
return *m_source;
}
PropertyStream::Source*
PropertyStream::Item::operator->() const
{
return &source();
}
PropertyStream::Source&
PropertyStream::Item::operator*() const
{
return source();
}
//------------------------------------------------------------------------------
//
// Proxy
//
//------------------------------------------------------------------------------
PropertyStream::Proxy::Proxy(Map const& map, std::string key) : m_map(&map), m_key(std::move(key))
{
}
PropertyStream::Proxy::Proxy(Proxy const& other) : m_map(other.m_map), m_key(other.m_key)
{
}
PropertyStream::Proxy::~Proxy()
{
std::string const s(m_ostream.str());
if (!s.empty())
m_map->add(m_key, s);
}
std::ostream&
PropertyStream::Proxy::operator<<(std::ostream& manip(std::ostream&)) const
{
return m_ostream << manip;
}
//------------------------------------------------------------------------------
//
// Map
//
//------------------------------------------------------------------------------
PropertyStream::Map::Map(PropertyStream& stream) : m_stream(stream)
{
}
PropertyStream::Map::Map(Set& parent) : m_stream(parent.stream())
{
m_stream.map_begin();
}
PropertyStream::Map::Map(std::string const& key, Map& map) : m_stream(map.stream())
{
m_stream.map_begin(key);
}
PropertyStream::Map::Map(std::string const& key, PropertyStream& stream) : m_stream(stream)
{
m_stream.map_begin(key);
}
PropertyStream::Map::~Map()
{
m_stream.map_end();
}
PropertyStream&
PropertyStream::Map::stream()
{
return m_stream;
}
PropertyStream const&
PropertyStream::Map::stream() const
{
return m_stream;
}
PropertyStream::Proxy
PropertyStream::Map::operator[](std::string const& key)
{
return Proxy(*this, key);
}
//------------------------------------------------------------------------------
//
// Set
//
//------------------------------------------------------------------------------
PropertyStream::Set::Set(std::string const& key, Map& map) : m_stream(map.stream())
{
m_stream.array_begin(key);
}
PropertyStream::Set::Set(std::string const& key, PropertyStream& stream) : m_stream(stream)
{
m_stream.array_begin(key);
}
PropertyStream::Set::~Set()
{
m_stream.array_end();
}
PropertyStream&
PropertyStream::Set::stream()
{
return m_stream;
}
PropertyStream const&
PropertyStream::Set::stream() const
{
return m_stream;
}
//------------------------------------------------------------------------------
//
// Source
//
//------------------------------------------------------------------------------
PropertyStream::Source::Source(std::string name) : m_name(std::move(name)), item_(this)
{
}
PropertyStream::Source::~Source()
{
std::scoped_lock const _(lock_);
if (parent_ != nullptr)
parent_->remove(*this);
removeAll();
}
std::string const&
PropertyStream::Source::name() const
{
return m_name;
}
void
PropertyStream::Source::add(Source& source)
{
std::scoped_lock const lock(lock_, source.lock_);
XRPL_ASSERT(
source.parent_ == nullptr, "beast::PropertyStream::Source::add : null source parent");
children_.push_back(source.item_);
source.parent_ = this;
}
void
PropertyStream::Source::remove(Source& child)
{
std::scoped_lock const lock(lock_, child.lock_);
XRPL_ASSERT(
child.parent_ == this, "beast::PropertyStream::Source::remove : child parent match");
children_.erase(children_.iterator_to(child.item_));
child.parent_ = nullptr;
}
void
PropertyStream::Source::removeAll()
{
std::scoped_lock const _(lock_);
for (auto iter = children_.begin(); iter != children_.end();)
{
std::scoped_lock const _cl((*iter)->lock_);
remove(*(*iter));
}
}
//------------------------------------------------------------------------------
void
PropertyStream::Source::write_one(PropertyStream& stream)
{
Map map(m_name, stream);
onWrite(map);
}
void
PropertyStream::Source::write(PropertyStream& stream)
{
Map map(m_name, stream);
onWrite(map);
std::scoped_lock const _(lock_);
for (auto& child : children_)
child.source().write(stream);
}
void
PropertyStream::Source::write(PropertyStream& stream, std::string const& path)
{
std::pair<Source*, bool> result(find(path));
if (result.first == nullptr)
return;
if (result.second)
{
result.first->write(stream);
}
else
{
result.first->write_one(stream);
}
}
std::pair<PropertyStream::Source*, bool>
PropertyStream::Source::find(std::string path)
{
bool const deep(peel_trailing_slashstar(&path));
bool const rooted(peel_leading_slash(&path));
Source* source(this);
if (!path.empty())
{
if (!rooted)
{
std::string const name(peel_name(&path));
source = find_one_deep(name);
if (source == nullptr)
return std::make_pair(nullptr, deep);
}
source = source->find_path(path);
}
return std::make_pair(source, deep);
}
bool
PropertyStream::Source::peel_leading_slash(std::string* path)
{
if (!path->empty() && path->front() == '/')
{
*path = std::string(path->begin() + 1, path->end());
return true;
}
return false;
}
bool
PropertyStream::Source::peel_trailing_slashstar(std::string* path)
{
bool found(false);
if (path->empty())
return false;
if (path->back() == '*')
{
found = true;
path->pop_back();
}
if (!path->empty() && path->back() == '/')
path->pop_back();
return found;
}
std::string
PropertyStream::Source::peel_name(std::string* path)
{
if (path->empty())
return "";
std::string::const_iterator const first = (*path).begin();
std::string::const_iterator const last = (*path).end();
std::string::const_iterator const pos = std::find(first, last, '/');
std::string s(first, pos);
if (pos != last)
{
*path = std::string(pos + 1, last);
}
else
{
*path = std::string();
}
return s;
}
// Recursive search through the whole tree until name is found
PropertyStream::Source*
PropertyStream::Source::find_one_deep(std::string const& name)
{
Source* found = find_one(name); // NOLINT(misc-const-correctness)
if (found != nullptr)
return found;
std::scoped_lock const _(lock_);
for (auto& s : children_)
{
found = s.source().find_one_deep(name);
if (found != nullptr)
return found;
}
return nullptr;
}
PropertyStream::Source*
PropertyStream::Source::find_path(std::string path)
{
if (path.empty())
return this;
Source* source(this);
do
{
std::string const name(peel_name(&path));
if (name.empty())
break;
source = source->find_one(name);
} while (source != nullptr);
return source;
}
// This function only looks at immediate children
// If no immediate children match, then return nullptr
PropertyStream::Source*
PropertyStream::Source::find_one(std::string const& name)
{
std::scoped_lock const _(lock_);
for (auto& s : children_)
{
if (s.source().m_name == name)
return &s.source();
}
return nullptr;
}
void
PropertyStream::Source::onWrite(Map&)
{
}
//------------------------------------------------------------------------------
//
// PropertyStream
//
//------------------------------------------------------------------------------
void
PropertyStream::add(std::string const& key, bool value)
{
if (value)
{
add(key, "true");
}
else
{
add(key, "false");
}
}
void
PropertyStream::add(std::string const& key, char value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, signed char value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned char value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, short value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned short value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, int value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned int value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, long value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned long value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, long long value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, unsigned long long value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, float value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, double value)
{
lexical_add(key, value);
}
void
PropertyStream::add(std::string const& key, long double value)
{
lexical_add(key, value);
}
void
PropertyStream::add(bool value)
{
if (value)
{
add("true");
}
else
{
add("false");
}
}
void
PropertyStream::add(char value)
{
lexical_add(value);
}
void
PropertyStream::add(signed char value)
{
lexical_add(value);
}
void
PropertyStream::add(unsigned char value)
{
lexical_add(value);
}
void
PropertyStream::add(short value)
{
lexical_add(value);
}
void
PropertyStream::add(unsigned short value)
{
lexical_add(value);
}
void
PropertyStream::add(int value)
{
lexical_add(value);
}
void
PropertyStream::add(unsigned int value)
{
lexical_add(value);
}
void
PropertyStream::add(long value)
{
lexical_add(value);
}
void
PropertyStream::add(unsigned long value)
{
lexical_add(value);
}
void
PropertyStream::add(long long value)
{
lexical_add(value);
}
void
PropertyStream::add(unsigned long long value)
{
lexical_add(value);
}
void
PropertyStream::add(float value)
{
lexical_add(value);
}
void
PropertyStream::add(double value)
{
lexical_add(value);
}
void
PropertyStream::add(long double value)
{
lexical_add(value);
}
} // namespace beast