summaryrefslogtreecommitdiffstats
path: root/library/cpp/yaml/fyamlcpp/fyamlcpp.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <[email protected]>2023-06-15 18:24:59 +0300
committerDaniil Cherednik <[email protected]>2023-06-15 18:26:33 +0300
commit068d4453cf9fc68c875eee73f5c637bb076f6a71 (patch)
treeda3e83fdb9488ea08faa39d8b41916744f9acad7 /library/cpp/yaml/fyamlcpp/fyamlcpp.cpp
parent7e7de263d4acbc6eacf92b618bcb5f9049bccc9b (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.cpp142
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;
}