diff options
author | innokentii <innokentii@yandex-team.com> | 2023-03-06 16:30:25 +0300 |
---|---|---|
committer | innokentii <innokentii@yandex-team.com> | 2023-03-06 16:30:25 +0300 |
commit | ea8e336dc456c44b848619e120a8f3643c6125af (patch) | |
tree | bafaf363369c9975b2d105fc4470c5a4aaa43eb8 /library/cpp/yaml/fyamlcpp | |
parent | 26a0ed381c2ffa857909e82395c762a6b08e76c2 (diff) | |
download | ydb-ea8e336dc456c44b848619e120a8f3643c6125af.tar.gz |
Add yaml config utils
add yaml_config utils
Diffstat (limited to 'library/cpp/yaml/fyamlcpp')
-rw-r--r-- | library/cpp/yaml/fyamlcpp/fyamlcpp.cpp | 53 | ||||
-rw-r--r-- | library/cpp/yaml/fyamlcpp/fyamlcpp.h | 20 |
2 files changed, 61 insertions, 12 deletions
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp index fc804128e4..9ab1465dfe 100644 --- a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp +++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp @@ -2,11 +2,23 @@ #include <contrib/libs/libfyaml/include/libfyaml.h> +#include <util/digest/murmur.h> + namespace NFyaml { #define ENSURE_NODE_NOT_EMPTY(NODE) Y_ENSURE_EX(NODE, TFyamlEx() << "Expected non-empty Node") #define ENSURE_DOCUMENT_NOT_EMPTY(NODE) Y_ENSURE_EX(NODE, TFyamlEx() << "Expected non-empty Document") +const char* zstr = ""; + +struct TStringHashT { + size_t operator()(const TString& str) const { + auto* ptr = str.empty() ? zstr : &str[0]; + return MurmurHash<size_t>(reinterpret_cast<char*>(&ptr), sizeof(ptr)); + } +}; + + enum class EErrorType { Debug = FYET_DEBUG, Info = FYET_INFO, @@ -280,8 +292,12 @@ TNode TNodeRef::Copy() const { return TNode(fy_node_copy(fy_node_document(Node_), Node_)); } -TNode TNodeRef::Copy(const TDocument& to) const { +TNode TNodeRef::Copy(TDocument& to) const { ENSURE_NODE_NOT_EMPTY(Node_); + auto* fromDoc = fy_node_document(Node_); + auto& fromUserdata = *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(fromDoc)); + auto& toUserdata = *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(to.Document_.get())); + toUserdata.insert(fromUserdata.begin(), fromUserdata.end()); return TNode(fy_node_copy(to.Document_.get(), Node_)); } @@ -694,6 +710,16 @@ TDocumentNodeIterator& TDocumentNodeIterator::operator++() { return *this; } +TDocument::TDocument(TString str, fy_document* doc, fy_diag* diag) + : Document_(doc, fy_document_destroy) + , Diag_(diag, fy_diag_destroy) +{ + auto* userdata = new THashSet<TString, TStringHashT>({str}); + fy_document_set_userdata(doc, userdata); + fy_document_register_on_destroy(doc, &DestroyDocumentStrings); + RegisterUserDataCleanup(); +} + TDocument::TDocument(fy_document* doc, fy_diag* diag) : Document_(doc, fy_document_destroy) , Diag_(diag, fy_diag_destroy) @@ -701,7 +727,9 @@ TDocument::TDocument(fy_document* doc, fy_diag* diag) RegisterUserDataCleanup(); } -TDocument TDocument::Parse(const char* cstr) { + +TDocument TDocument::Parse(TString str) { + auto* cstr = str.empty() ? zstr : &str[0]; fy_diag_cfg dcfg; fy_diag_cfg_default(&dcfg); std::unique_ptr<fy_diag, void(*)(fy_diag*)> diag(fy_diag_create(&dcfg), fy_diag_destroy); @@ -721,12 +749,19 @@ TDocument TDocument::Parse(const char* cstr) { ythrow yexception() << err->file << ":" << err->line << ":" << err->column << " " << err->msg; } } - return TDocument(doc, diag.release()); + return TDocument(std::move(str), doc, diag.release()); } TDocument TDocument::Clone() const { ENSURE_DOCUMENT_NOT_EMPTY(Document_); fy_document* doc = fy_document_clone(Document_.get()); + fy_document_set_userdata( + doc, + new THashSet<TString, TStringHashT>( + *reinterpret_cast<THashSet<TString, TStringHashT>*>(fy_document_get_userdata(Document_.get())) + ) + ); + fy_document_register_on_destroy(doc, &DestroyDocumentStrings); return TDocument(doc, fy_document_get_diag(doc)); } @@ -836,13 +871,15 @@ std::unique_ptr<char, void(*)(char*)> TJsonEmitter::EmitToCharArray() const { return res; } -TParser::TParser(fy_parser* parser, fy_diag* diag) - : Parser_(parser, fy_parser_destroy) +TParser::TParser(TString rawStream, fy_parser* parser, fy_diag* diag) + : RawDocumentStream_(std::move(rawStream)) + , Parser_(parser, fy_parser_destroy) , Diag_(diag, fy_diag_destroy) {} -TParser TParser::Create(const char* stream) +TParser TParser::Create(TString str) { + auto* stream = str.empty() ? zstr : &str[0]; fy_diag_cfg dcfg; fy_diag_cfg_default(&dcfg); std::unique_ptr<fy_diag, void(*)(fy_diag*)> diag(fy_diag_create(&dcfg), fy_diag_destroy); @@ -865,7 +902,7 @@ TParser TParser::Create(const char* stream) fy_parser_set_string(parser, stream, -1); - return TParser(parser, diag.release()); + return TParser(std::move(str), parser, diag.release()); } std::optional<TDocument> TParser::NextDocument() { @@ -874,7 +911,7 @@ std::optional<TDocument> TParser::NextDocument() { return std::nullopt; } - return TDocument(doc, fy_document_get_diag(doc)); + return TDocument(RawDocumentStream_, doc, fy_document_get_diag(doc)); } namespace NDetail { diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.h b/library/cpp/yaml/fyamlcpp/fyamlcpp.h index 5b645a557c..c1ec03d25f 100644 --- a/library/cpp/yaml/fyamlcpp/fyamlcpp.h +++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.h @@ -4,6 +4,7 @@ #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> @@ -116,7 +117,7 @@ public: TNode Copy() const; - TNode Copy(const TDocument& to) const; + TNode Copy(TDocument& to) const; bool IsAlias() const; @@ -509,7 +510,9 @@ class TDocument { 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: @@ -518,7 +521,7 @@ public: , Diag_(std::move(other.Diag_)) {} - static TDocument Parse(const char* cstr); + static TDocument Parse(TString cstr); TDocument Clone() const; @@ -583,6 +586,14 @@ private: } } + static void DestroyDocumentStrings(fy_document *fyd, void *user) { + Y_UNUSED(fyd); + if (user) { + auto* data = reinterpret_cast<THashSet<TString>*>(user); + delete data; + } + } + bool RegisterUserDataCleanup(); void UnregisterUserDataCleanup(); }; @@ -599,12 +610,13 @@ private: }; class TParser { - TParser(fy_parser* doc, fy_diag* diag); + TParser(TString rawStream, fy_parser* doc, fy_diag* diag); public: - static TParser Create(const char* cstr); + 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_; }; |