diff options
| author | Daniil Cherednik <[email protected]> | 2023-06-15 18:24:59 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2023-06-15 18:26:33 +0300 |
| commit | 068d4453cf9fc68c875eee73f5c637bb076f6a71 (patch) | |
| tree | da3e83fdb9488ea08faa39d8b41916744f9acad7 /library/cpp/yaml/fyamlcpp/fyamlcpp.cpp | |
| parent | 7e7de263d4acbc6eacf92b618bcb5f9049bccc9b (diff) | |
Create stable-23-2 branch
x-stable-origin-commit: 3fd4d58117c143ed9e6b21813ccd9e507d2cd4d3
Diffstat (limited to 'library/cpp/yaml/fyamlcpp/fyamlcpp.cpp')
| -rw-r--r-- | library/cpp/yaml/fyamlcpp/fyamlcpp.cpp | 142 |
1 files changed, 129 insertions, 13 deletions
diff --git a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp index b8d8b17596d..d006001b9eb 100644 --- a/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp +++ b/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp @@ -155,18 +155,6 @@ enum EEmitterCfgFlags { Default = FYECF_DEFAULT, }; -enum class ENodeStyle { - Any = FYNS_ANY, - Flow = FYNS_FLOW, - Block = FYNS_BLOCK, - Plain = FYNS_PLAIN, - SingleQuoted = FYNS_SINGLE_QUOTED, - DoubleQuoted = FYNS_DOUBLE_QUOTED, - Literal = FYNS_LITERAL, - Folded = FYNS_FOLDED, - Alias = FYNS_ALIAS, -}; - enum class ENodeWalkFlags { DontFollow = FYNWF_DONT_FOLLOW, Follow = FYNWF_FOLLOW, @@ -330,6 +318,115 @@ TString TNodeRef::Scalar() const { return TString(text, size); } +TMark TNodeRef::BeginMark() const { + ENSURE_NODE_NOT_EMPTY(Node_); + std::unique_ptr<fy_document_iterator, void(*)(fy_document_iterator*)> it( + fy_document_iterator_create(), + &fy_document_iterator_destroy); + fy_document_iterator_node_start(it.get(), Node_); + auto deleter = [&](fy_event* fye){ fy_document_iterator_event_free(it.get(), fye); }; + std::unique_ptr<fy_event, decltype(deleter)> ev( + fy_document_iterator_body_next(it.get()), + deleter); + auto* mark = fy_event_start_mark(ev.get()); + + if (!mark) { + ythrow yexception() << "can't get begin mark for a node"; + } + + return TMark{ + mark->input_pos, + mark->line, + mark->column, + }; +} + +bool IsComplexType(ENodeType type) { + return type == ENodeType::Mapping || type == ENodeType::Sequence; +} + +fy_event_type GetOpenEventType(ENodeType type) { + switch(type) { + case ENodeType::Mapping: + return FYET_MAPPING_START; + case ENodeType::Sequence: + return FYET_SEQUENCE_START; + default: + Y_FAIL("Not a brackets type"); + } +} + +fy_event_type GetCloseEventType(ENodeType type) { + switch(type) { + case ENodeType::Mapping: + return FYET_MAPPING_END; + case ENodeType::Sequence: + return FYET_SEQUENCE_END; + default: + Y_FAIL("Not a brackets type"); + } +} + +TMark TNodeRef::EndMark() const { + ENSURE_NODE_NOT_EMPTY(Node_); + std::unique_ptr<fy_document_iterator, void(*)(fy_document_iterator*)> it( + fy_document_iterator_create(), + &fy_document_iterator_destroy); + fy_document_iterator_node_start(it.get(), Node_); + + auto deleter = [&](fy_event* fye){ fy_document_iterator_event_free(it.get(), fye); }; + std::unique_ptr<fy_event, decltype(deleter)> prevEv( + nullptr, + deleter); + std::unique_ptr<fy_event, decltype(deleter)> ev( + fy_document_iterator_body_next(it.get()), + deleter); + + if (IsComplexType(Type())) { + int openBrackets = 0; + if (ev->type == GetOpenEventType(Type())) { + ++openBrackets; + } + if (ev->type == GetCloseEventType(Type())) { + --openBrackets; + } + while (ev->type != GetCloseEventType(Type()) || openBrackets != 0) { + std::unique_ptr<fy_event, decltype(deleter)> cur( + fy_document_iterator_body_next(it.get()), + deleter); + if (cur == nullptr) { + break; + } + if (cur->type == GetOpenEventType(Type())) { + ++openBrackets; + } + if (cur->type == GetCloseEventType(Type())) { + --openBrackets; + } + if (fy_event_get_node_style(cur.get()) != FYNS_BLOCK) { + prevEv.reset(ev.release()); + ev.reset(cur.release()); + } + } + } + + auto* mark = fy_event_end_mark(ev.get()); + + if (!mark && prevEv) { + mark = fy_event_end_mark(prevEv.get()); + } + + if (!mark) { + ythrow yexception() << "can't get end mark for a node"; + } + + return TMark{ + mark->input_pos, + mark->line, + mark->column, + }; +} + TMapping TNodeRef::Map() const { ENSURE_NODE_NOT_EMPTY(Node_); Y_ENSURE_EX(fy_node_is_mapping(Node_), TFyamlEx() << "Node is not Mapping: " << Path()); @@ -400,6 +497,16 @@ std::unique_ptr<char, void(*)(char*)> TNodeRef::EmitToCharArray() const { return res; } +void TNodeRef::SetStyle(ENodeStyle style) { + ENSURE_NODE_NOT_EMPTY(Node_); + fy_node_set_style(Node_, (enum fy_node_style)style); +} + +ENodeStyle TNodeRef::Style() const { + ENSURE_NODE_NOT_EMPTY(Node_); + return (ENodeStyle)fy_node_get_style(Node_); +} + void TNodeRef::SetUserData(NDetail::IBasicUserData* data) { ENSURE_NODE_NOT_EMPTY(Node_); fy_node_set_meta(Node_, data); @@ -429,6 +536,12 @@ TNodeRef TNodePairRef::Key() const { return TNodeRef(fy_node_pair_key(Pair_)); } +int TNodePairRef::Index(const TNodeRef& node) const { + ENSURE_NODE_NOT_EMPTY(node); + ENSURE_NODE_NOT_EMPTY(Pair_); + return fy_node_mapping_get_pair_index(node.Node_, Pair_); +} + void TNodePairRef::SetKey(const TNodeRef& node) { ENSURE_NODE_NOT_EMPTY(Pair_); ENSURE_NODE_NOT_EMPTY(node); @@ -542,6 +655,9 @@ void TMapping::Remove(const TNodePairRef& toRemove) { ENSURE_NODE_NOT_EMPTY(Node_); ENSURE_NODE_NOT_EMPTY(toRemove); NDetail::RethrowOnError(fy_node_mapping_remove(Node_, toRemove.Pair_), Node_); + fy_node_free(fy_node_pair_key(toRemove.Pair_)); + fy_node_free(fy_node_pair_value(toRemove.Pair_)); + free(toRemove.Pair_); } TMappingIterator TMapping::Remove(const TMappingIterator& toRemove) { @@ -819,7 +935,7 @@ std::unique_ptr<char, void(*)(char*)> TDocument::EmitToCharArray() const { std::unique_ptr<char, void(*)(char*)> res( fy_emit_document_to_string( Document_.get(), - (fy_emitter_cfg_flags)(FYECF_DEFAULT | FYECF_OUTPUT_COMMENTS)), &NDetail::FreeChar); + (fy_emitter_cfg_flags)(FYECF_DEFAULT | FYECF_MODE_PRETTY | FYECF_OUTPUT_COMMENTS)), &NDetail::FreeChar); return res; } |
