aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yaml/fyamlcpp/fyamlcpp.h
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2023-05-05 11:09:01 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2023-05-05 11:09:01 +0300
commitb5a989b16cafa8a3b3bc076f1097a0eda6f48c06 (patch)
tree4da744117a5aab37758921fa43b95a3068e5aec1 /library/cpp/yaml/fyamlcpp/fyamlcpp.h
parentfc1cffcfa7f0497a1f97b384a24bcbf23362f3be (diff)
downloadydb-b5a989b16cafa8a3b3bc076f1097a0eda6f48c06.tar.gz
Ydb stable 23-1-2623.1.26
x-stable-origin-commit: 22184a7e157553d447f17a2dffc4ea2d32dfd74d
Diffstat (limited to 'library/cpp/yaml/fyamlcpp/fyamlcpp.h')
-rw-r--r--library/cpp/yaml/fyamlcpp/fyamlcpp.h636
1 files changed, 636 insertions, 0 deletions
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.h b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
new file mode 100644
index 0000000000..bcf9362d73
--- /dev/null
+++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.h
@@ -0,0 +1,636 @@
+#pragma once
+
+#include <util/generic/yexception.h>
+#include <util/system/compiler.h>
+#include <util/system/yassert.h>
+#include <util/stream/str.h>
+#include <util/generic/hash_set.h>
+
+#include <memory>
+#include <optional>
+
+struct fy_parser;
+struct fy_node;
+struct fy_document;
+struct fy_diag;
+struct fy_document_iterator;
+struct fy_node_pair;
+
+namespace NFyaml {
+
+struct TStringPtrHashT {
+ size_t operator()(const TSimpleSharedPtr<TString>& str) const {
+ return (size_t)str.Get();
+ }
+};
+
+struct TFyamlEx : public yexception {};
+
+enum class ENodeType {
+ Scalar,
+ Sequence,
+ Mapping,
+};
+
+namespace NDetail {
+
+class IBasicUserData {
+public:
+ virtual ~IBasicUserData() = default;
+};
+
+template <class T>
+class TUserDataHolder : public IBasicUserData {
+public:
+ TUserDataHolder(IBasicUserData* next, T* data)
+ : Next_(next)
+ , Data_(data)
+ {}
+
+private:
+ std::unique_ptr<IBasicUserData> Next_ = nullptr;
+ std::unique_ptr<T> Data_ = nullptr;
+};
+
+void RethrowError(fy_diag* diag);
+
+void RethrowOnError(bool isError, fy_node* node);
+
+void RethrowOnError(bool isError, fy_node_pair* pair);
+
+void RethrowOnError(bool isError, fy_diag* diag);
+
+void FreeChar(char* mem);
+
+} // namespace NDetail
+
+class TNodeRef;
+class TDocumentIterator;
+class TDocument;
+class TNode;
+class TMappingIterator;
+class TReverseMappingIterator;
+class TMapping;
+class TSequenceIterator;
+class TReverseSequenceIterator;
+class TSequence;
+class TJsonEmitter;
+class TParser;
+struct TMark;
+
+class TDocumentIterator {
+ friend class TDocument;
+public:
+ TDocumentIterator(fy_document_iterator* iterator = nullptr);
+
+protected:
+ std::unique_ptr<fy_document_iterator, void(*)(fy_document_iterator*)> Iterator_;
+};
+
+class TNodeRef {
+ friend class TDocument;
+ friend class TDocumentNodeIterator;
+ friend class TNode;
+ friend class TMapping;
+ friend class TMappingIterator;
+ friend class TReverseMappingIterator;
+ friend class TNodePairRef;
+ friend class TSequence;
+ friend class TSequenceIterator;
+ friend class TReverseSequenceIterator;
+ friend class TJsonEmitter;
+
+ TNodeRef(fy_node* node)
+ : Node_(node)
+ {}
+
+public:
+ TNodeRef() {};
+
+ TNodeRef(const TNodeRef& other) { Node_ = other.Node_; }
+
+ TNodeRef& operator=(const TNodeRef& other) { Node_ = other.Node_; return *this; }
+
+ TNodeRef& operator=(fy_node* node) { Node_ = node; return *this; }
+
+ bool operator==(const TNodeRef& other) const { return Node_ == other.Node_; }
+
+ explicit operator bool() const { return Node_ != nullptr; }
+
+ TString Path() const;
+
+ ENodeType Type() const;
+
+ TNode Copy() const;
+
+ TNode Copy(TDocument& to) const;
+
+ bool IsAlias() const;
+
+ TNodeRef ResolveAlias() const;
+
+ TNode CreateReference() const;
+
+ TSequence Sequence() const;
+
+ TMapping Map() const;
+
+ TString Scalar() const;
+
+ void Insert(const TNodeRef& node);
+
+ bool Empty() const { return Node_ == nullptr; }
+
+ std::optional<TString> Tag() const;
+
+ void SetTag(const TString& tag);
+
+ bool RemoveTag();
+
+ bool HasAnchor() const;
+
+ void SetAnchor(const TString& anchor);
+
+ bool DeepEqual(const TNodeRef& other);
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+protected:
+ fy_node* Node_ = nullptr;
+
+ void SetUserData(NDetail::IBasicUserData* data);
+ NDetail::IBasicUserData* UserData() const;
+ void ClearUserData();
+};
+
+class TNode {
+ friend class TDocument;
+ friend class TDocumentNodeIterator;
+ friend class TNodeRef;
+ friend class TSequence;
+
+ TNode& operator=(fy_node* node);
+public:
+ TNode(fy_node* node = nullptr);
+
+ bool operator==(const TNode& other) const { return Node_ == other.Node_; }
+
+ explicit operator bool() { return Node_ != nullptr; }
+
+ TNodeRef Ref() { return TNodeRef(Node_.get()); }
+
+private:
+ std::shared_ptr<fy_node> Node_;
+};
+
+class TNodePairRef {
+ friend class TMappingIterator;
+ friend class TReverseMappingIterator;
+ friend class TMapping;
+public:
+ TNodePairRef(fy_node_pair* pair = nullptr)
+ : Pair_(pair)
+ {}
+
+ bool operator==(const TNodePairRef& other) const { return Pair_ == other.Pair_; }
+
+ explicit operator bool() const { return Pair_ != nullptr; }
+
+ TNodeRef Key() const;
+
+ void SetKey(const TNodeRef& node);
+
+ TNodeRef Value() const;
+
+ void SetValue(const TNodeRef& node);
+
+private:
+ fy_node_pair* Pair_ = nullptr;
+};
+
+class TMappingIterator {
+ friend class TMapping;
+public:
+ TMappingIterator(const TNodeRef& node, bool end = false);
+
+ TMappingIterator(const TMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ }
+
+ TMappingIterator& operator=(const TMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ return *this;
+ }
+
+ TMappingIterator& operator++();
+
+ const TNodePairRef* operator->() const { return &NodePair_; }
+
+ TMappingIterator operator++(int) {
+ TMappingIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TMappingIterator other) const { return Node_ == other.Node_ && NodePair_ == other.NodePair_; }
+
+ const TNodePairRef& operator*() const { return NodePair_; }
+
+private:
+ TNodeRef Node_;
+ TNodePairRef NodePair_;
+};
+
+class TReverseMappingIterator {
+ friend class TMapping;
+public:
+ TReverseMappingIterator(const TNodeRef& node, bool end = false);
+
+ TReverseMappingIterator(const TReverseMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ }
+
+ TReverseMappingIterator& operator=(const TReverseMappingIterator& other) {
+ Node_ = other.Node_;
+ NodePair_ = other.NodePair_;
+ return *this;
+ }
+
+ TReverseMappingIterator& operator++();
+
+ const TNodePairRef* operator->() const { return &NodePair_; }
+
+ TReverseMappingIterator operator++(int) {
+ TReverseMappingIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TReverseMappingIterator other) const { return Node_ == other.Node_ && NodePair_ == other.NodePair_; }
+
+ bool operator!=(TReverseMappingIterator other) const { return !(*this == other); }
+
+ const TNodePairRef& operator*() const { return NodePair_; }
+
+private:
+ TNodeRef Node_;
+ TNodePairRef NodePair_;
+};
+
+class TMapping : public TNodeRef {
+public:
+ explicit TMapping(const TNodeRef& node)
+ : TNodeRef(node)
+ {
+ Y_VERIFY_DEBUG(Type() == ENodeType::Mapping);
+ }
+
+ TMappingIterator begin() const {
+ return TMappingIterator(Node_);
+ }
+
+ TMappingIterator end() const {
+ return TMappingIterator(Node_, true);
+ }
+
+ TReverseMappingIterator rbegin() const {
+ return TReverseMappingIterator(Node_);
+ }
+
+ TReverseMappingIterator rend() const {
+ return TReverseMappingIterator(Node_, true);
+ }
+
+ size_t size() const;
+
+ size_t empty() const;
+
+ TNodePairRef at(int index) const;
+
+ TNodePairRef operator[](int index) const;
+
+ TNodeRef at(const TString& index) const;
+
+ TNodePairRef pair_at(const TString& index) const;
+
+ TNodePairRef pair_at_opt(const TString& index) const;
+
+ TNodeRef operator[](const TString& index) const;
+
+ TNodeRef operator[](const char* str) const;
+
+ void Append(const TNodeRef& key, const TNodeRef& value);
+
+ void Prepend(const TNodeRef& key, const TNodeRef& value);
+
+ void Remove(const TNodePairRef& toRemove);
+
+ TMappingIterator Remove(const TMappingIterator& toRemove);
+
+ void Remove(const TNodeRef& key);
+};
+
+class TSequenceIterator {
+ friend class TSequence;
+public:
+ TSequenceIterator(const TNodeRef& node, bool end = false);
+
+ TSequenceIterator(const TSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ }
+
+ TSequenceIterator& operator=(const TSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ return *this;
+ }
+
+ TSequenceIterator& operator++();
+
+ const TNodeRef* operator->() const {
+ return &IterNode_;
+ }
+
+ TSequenceIterator operator++(int) {
+ TSequenceIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TSequenceIterator other) const { return Node_ == other.Node_ && Iter_ == other.Iter_; }
+
+ bool operator!=(TSequenceIterator other) const { return !(*this == other); }
+
+ const TNodeRef& operator*() const { return IterNode_; }
+
+ void InsertBefore(const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& node);
+
+private:
+ TNodeRef Node_;
+ TNodeRef IterNode_;
+ void* Iter_ = nullptr;
+};
+
+class TReverseSequenceIterator {
+ friend class TSequence;
+public:
+ TReverseSequenceIterator(const TNodeRef& node, bool end = false);
+
+ TReverseSequenceIterator(const TReverseSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ }
+
+ TReverseSequenceIterator& operator=(const TReverseSequenceIterator& other) {
+ Node_ = other.Node_;
+ IterNode_ = other.IterNode_;
+ Iter_ = other.Iter_;
+ return *this;
+ }
+
+ TReverseSequenceIterator& operator++();
+
+ const TNodeRef* operator->() const {
+ return &IterNode_;
+ }
+
+ TReverseSequenceIterator operator++(int) {
+ TReverseSequenceIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TReverseSequenceIterator other) const { return Node_ == other.Node_ && Iter_ == other.Iter_; }
+
+ bool operator!=(TReverseSequenceIterator other) const { return !(*this == other); }
+
+ const TNodeRef& operator*() const { return IterNode_; }
+
+ void InsertBefore(const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& node);
+
+private:
+ TNodeRef Node_;
+ TNodeRef IterNode_;
+ void* Iter_ = nullptr;
+};
+
+class TSequence : public TNodeRef {
+public:
+ explicit TSequence(const TNodeRef& node)
+ : TNodeRef(node)
+ {
+ Y_VERIFY_DEBUG(Type() == ENodeType::Sequence);
+ }
+
+ TSequenceIterator begin() const {
+ return TSequenceIterator(Node_);
+ }
+
+ TSequenceIterator end() const {
+ return TSequenceIterator(Node_, true);
+ }
+
+ TReverseSequenceIterator rbegin() const {
+ return TReverseSequenceIterator(Node_);
+ }
+
+ TReverseSequenceIterator rend() const {
+ return TReverseSequenceIterator(Node_, true);
+ }
+
+ size_t size() const;
+
+ size_t empty() const;
+
+ TNodeRef at(int index) const;
+
+ TNodeRef operator[](int index) const;
+
+ void Append(const TNodeRef& node);
+
+ void Prepend(const TNodeRef& node);
+
+ void InsertBefore(const TNodeRef& mark, const TNodeRef& node);
+
+ void InsertAfter(const TNodeRef& mark, const TNodeRef& node);
+
+ TNode Remove(const TNodeRef& toRemove);
+
+ TSequenceIterator Remove(const TSequenceIterator& toRemove);
+
+ TReverseSequenceIterator Remove(const TReverseSequenceIterator& toRemove);
+};
+
+class TDocumentNodeIterator
+ : public TDocumentIterator
+{
+public:
+ TDocumentNodeIterator(TNodeRef&& node);
+
+ TDocumentNodeIterator(const TDocumentNodeIterator& other)
+ : TDocumentIterator(other.Iterator_.get())
+ , Node_(other.Node_)
+ {}
+
+ TDocumentNodeIterator& operator=(const TDocumentNodeIterator& other) {
+ Iterator_.reset(other.Iterator_.get());
+ Node_ = other.Node_;
+ return *this;
+ }
+
+ TDocumentNodeIterator& operator++();
+
+ TNodeRef* operator->() {
+ return &Node_;
+ }
+
+ TDocumentNodeIterator operator++(int) {
+ TDocumentNodeIterator retval = *this;
+ ++(*this);
+ return retval;
+ }
+
+ bool operator==(TDocumentNodeIterator other) const { return Node_ == other.Node_; }
+
+ bool operator!=(TDocumentNodeIterator other) const { return !(*this == other); }
+
+ TNodeRef& operator*() { return Node_; }
+
+private:
+ TNodeRef Node_;
+};
+
+class TDocument {
+ friend class TNode;
+ friend class TNodeRef;
+ friend class TJsonEmitter;
+ friend class TParser;
+ friend class TMapping;
+
+ TDocument(TString str, fy_document* doc = nullptr, fy_diag* diag = nullptr);
+ TDocument(fy_document* doc = nullptr, fy_diag* diag = nullptr);
+
+public:
+ TDocument(TDocument&& other)
+ : Document_(std::move(other.Document_))
+ , Diag_(std::move(other.Diag_))
+ {}
+
+ static TDocument Parse(TString cstr);
+
+ TDocument Clone() const;
+
+ template <class... Args>
+ size_t Scanf(const char* fmt, Args&& ...args) {
+ Y_VERIFY_DEBUG(Document_);
+ return fy_document_scanf(Document_.get(), fmt, std::forward<Args>(args)...);
+ }
+
+ void InsertAt(const char* path, const TNodeRef& node);
+
+ template <class... Args>
+ TNodeRef Buildf(const char* fmt, Args&& ...args) {
+ Y_VERIFY_DEBUG(Document_);
+ return fy_node_buildf(Document_.get(), fmt, std::forward<Args>(args)...);
+ }
+
+ TNodeRef Buildf(const char* content);
+
+ void Resolve();
+
+ bool HasDirectives();
+
+ bool HasExplicitDocumentStart();
+
+ bool HasExplicitDocumentEnd();
+
+ void SetParent(const TDocument& doc);
+
+ TNodeRef Root();
+
+ void SetRoot(const TNodeRef& node);
+
+ TDocumentNodeIterator begin() {
+ auto it = TDocumentNodeIterator(Root());
+ ++it;
+ return it;
+ }
+
+ TDocumentNodeIterator end() {
+ return TDocumentNodeIterator(TNodeRef(nullptr));
+ }
+
+ TNodeRef CreateAlias(const TString& name);
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+ TMark BeginMark() const;
+
+ TMark EndMark() const;
+
+private:
+ std::unique_ptr<fy_document, void(*)(fy_document*)> Document_;
+ std::unique_ptr<fy_diag, void(*)(fy_diag*)> Diag_;
+
+ static void DestroyUserData(fy_node *fyn, void *meta, void *user) {
+ Y_UNUSED(fyn);
+ Y_UNUSED(user);
+ if (meta) {
+ auto* data = reinterpret_cast<NDetail::IBasicUserData*>(meta);
+ delete data;
+ }
+ }
+
+ static void DestroyDocumentStrings(fy_document *fyd, void *user) {
+ Y_UNUSED(fyd);
+ if (user) {
+ auto* data = reinterpret_cast<THashSet<TSimpleSharedPtr<TString>, TStringPtrHashT>*>(user);
+ delete data;
+ }
+ }
+
+ bool RegisterUserDataCleanup();
+ void UnregisterUserDataCleanup();
+};
+
+class TJsonEmitter {
+public:
+ TJsonEmitter(TDocument& doc) : Node_(doc.Root()) {}
+ TJsonEmitter(const TNodeRef& node) : Node_(node) {}
+
+ std::unique_ptr<char, void(*)(char*)> EmitToCharArray() const;
+
+private:
+ const TNodeRef Node_;
+};
+
+class TParser {
+ TParser(TString rawStream, fy_parser* doc, fy_diag* diag);
+public:
+ static TParser Create(TString str);
+
+ std::optional<TDocument> NextDocument();
+private:
+ TString RawDocumentStream_;
+ std::unique_ptr<fy_parser, void(*)(fy_parser*)> Parser_;
+ std::unique_ptr<fy_diag, void(*)(fy_diag*)> Diag_;
+};
+
+struct TMark {
+ size_t InputPos;
+ int Line;
+ int Column;
+};
+
+} // namesapce NFyaml