Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RYMLParser.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Carsten D. Burgard, DESY/ATLAS, Dec 2021
5 *
6 * Copyright (c) 2022, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#include <sstream>
14#include <stdexcept>
15
16#include <ryml.hpp>
17#include <c4/yml/std/map.hpp>
18#include <c4/yml/std/string.hpp>
19#include <c4/yml/common.hpp>
20
21#include "RYMLParser.h"
22
23namespace {
24size_t count_nlines(c4::csubstr src)
25{
26 // helper function to count the lines
27 size_t n = (src.len > 0);
28 while (src.len > 0) {
29 n += (src.begins_with('\n') || src.begins_with('\r'));
30 src = src.sub(1);
31 }
32 return n;
33}
34
35c4::yml::Tree makeTree(std::istream &is)
36{
37 if (!is.good())
38 throw std::runtime_error("invalid input!");
39 std::string s(std::istreambuf_iterator<char>(is), {});
40
41 auto src = c4::to_csubstr(s.c_str());
42 size_t nlines = count_nlines(src);
43 c4::yml::Tree tree(nlines, s.size());
44 c4::yml::Parser np;
45 np.parse({}, tree.copy_to_arena(src), &tree);
46 return tree;
47}
48} // namespace
49
50// TRYMLTree Implementation
52 ryml::Tree tree;
53
54public:
55 Impl(){};
56 Impl(std::istream &is) : tree(makeTree(is))
57 {
58 // constructor parsing the RYML tree
59 }
60 inline ryml::Tree &get()
61 {
62 // getter for the RYML tree reference
63 return this->tree;
64 }
65 inline const ryml::Tree &get() const
66 {
67 // const getter for the RYML tree reference
68 return this->tree;
69 }
70};
71
72// TRYMLNode Implementation
74 c4::yml::NodeRef node;
75
76public:
77 Impl(const c4::yml::NodeRef &n)
78 : node(n){
79 // constructor taking the RYML node reference
80 };
81 inline static TRYMLTree::Node &mkNode(TRYMLTree *t, c4::yml::NodeRef node)
82 {
83 // function for creating a new node based on a RYML node reference
85 }
86 inline c4::yml::NodeRef &get()
87 {
88 // getter for the RYML node reference
89 return node;
90 }
91 inline const c4::yml::NodeRef &get() const
92 {
93 // getter for the RYML node reference
94 return node;
95 }
96};
97
98// JSONTree interface implementation
99
100void TRYMLTree::Node::writeJSON(std::ostream &os) const
101{
102 // write the tree as JSON to an ostream
103 os << c4::yml::as_json(node->get());
104}
105
106void TRYMLTree::Node::writeYML(std::ostream &os) const
107{
108 // write the tree as YML to an ostream
109 os << node->get();
110}
111
113{
114 // assign this node to be a map (JSON object)
115 node->get() |= c4::yml::MAP;
116}
117
119{
120 // assign this node to be a sequence (JSON array)
121 node->get() |= c4::yml::SEQ;
122}
123
124TRYMLTree::TRYMLTree(std::istream &is)
125 : tree(std::make_unique<Impl>(is)){
126 // constructor taking an istream (for reading)
127 };
128
130 : tree(std::make_unique<Impl>()){
131 // default constructor (for writing)
132 };
133
135{
136 // destructor. clears the cache.
137 clearcache();
138};
139
140// JSONNode interface implementation
141
142TRYMLTree::Node::Node(TRYMLTree *t, const TRYMLTree::Node::Impl &imp) : tree(t), node(std::make_unique<Impl>(imp))
143{
144 // construct a new node from scratch
145}
146
147TRYMLTree::Node::Node(const Node &other) : Node(other.tree, other.node->get())
148{
149 // copy constructor
150}
151
153{
154 // obtain the root node of a tree
155 return Node::Impl::mkNode(this, tree->get().rootref());
156}
157
159{
160 // write a string to this node
161 node->get() << s;
162 return *this;
163}
164
166{
167 // write an int to this node
168 node->get() << i;
169 return *this;
170}
171
173{
174 // write an float to this node
175 node->get() << d;
176 return *this;
177}
178
180{
181 // read a string from this node
182 node->get() >> v;
183 return *this;
184}
185
187{
188 // get a child node with the given key
189 return Impl::mkNode(tree, node->get()[c4::to_csubstr(tree->incache(k))]);
190}
191
193{
194 // get a child node with the given index
195 return Impl::mkNode(tree, node->get()[pos]);
196}
197
198const TRYMLTree::Node &TRYMLTree::Node::operator[](std::string const &k) const
199{
200 // get a child node with the given key (const version)
201 return Impl::mkNode(tree, node->get()[c4::to_csubstr(tree->incache(k))]);
202}
203
205{
206 // get a child node with the given index (const version)
207 return Impl::mkNode(tree, node->get()[pos]);
208}
209
211{
212 // return true if this node can have child nodes
213 return node->get().is_container();
214}
215
217{
218 // return true if this node is a map (JSON object)
219 return node->get().is_map();
220}
221
223{
224 // return true if this node is a sequence (JSON array)
225 return node->get().is_seq();
226}
227
228std::string TRYMLTree::Node::key() const
229{
230 // obtain the key of this node
231 std::stringstream ss;
232 ss << node->get().key();
233 return ss.str();
234}
235
236std::string TRYMLTree::Node::val() const
237{
238 ;
239 // obtain the value of this node (as a string)
240 std::stringstream ss;
241 ss << node->get().val();
242 return ss.str();
243}
244
246{
247 // append a new child to this node
248 return Impl::mkNode(tree, node->get().append_child());
249}
250
252{
253 // return true if this node has a key
254 return node->get().has_key();
255}
256
258{
259 // return true if this node has a value
260 return node->get().has_val();
261}
262
263bool TRYMLTree::Node::has_child(std::string const &s) const
264{
265 // return true if this node has a child with the given key
266 return node->get().has_child(c4::to_csubstr(s.c_str()));
267}
268
270{
271 // return the number of child nodes of this node
272 return node->get().num_children();
273}
274
276{
277 // return the child with the given index
278 return Impl::mkNode(tree, node->get().child(pos));
279}
280
282{
283 // return the child with the given index (const version)
284 return Impl::mkNode(tree, node->get().child(pos));
285}
286
287// specific functions
288
289namespace {
290void error_cb(const char *msg, size_t msg_len, c4::yml::Location /*not used*/, void * /*user_data*/)
291{
292 // error callback using std::runtime_error
293 if (msg && msg_len > 0) {
294 throw std::runtime_error(msg);
295 } else {
296 throw std::runtime_error("error handler invoked without error message");
297 }
298}
299
300bool setcallbacks()
301{
302 // set the custom callback functions
303 c4::yml::set_callbacks(c4::yml::Callbacks(c4::yml::get_callbacks().m_user_data, c4::yml::get_callbacks().m_allocate,
304 c4::yml::get_callbacks().m_free, &::error_cb));
305 return true;
306}
307bool ok = setcallbacks();
308} // namespace
309
310const char *TRYMLTree::incache(const std::string &str)
311{
312 // obtain a string from the string cache
313 _strcache.push_back(str);
314 return _strcache.back().c_str();
315}
316
318{
319 // obtain a node from the node cache
320 _nodecache.push_back(n);
321 return _nodecache.back();
322}
323
325{
326 // clear all caches
327 TRYMLTree::_strcache.clear();
328 TRYMLTree::_nodecache.clear();
329}
#define d(i)
Definition RSha256.hxx:102
const ryml::Tree & get() const
ryml::Tree & get()
Impl(std::istream &is)
ryml::Tree tree
c4::yml::NodeRef & get()
const c4::yml::NodeRef & get() const
c4::yml::NodeRef node
static TRYMLTree::Node & mkNode(TRYMLTree *t, c4::yml::NodeRef node)
Impl(const c4::yml::NodeRef &n)
virtual bool is_map() const override
virtual bool has_key() const override
virtual Node & child(size_t pos) override
virtual const Node & operator>>(std::string &v) const override
virtual void writeYML(std::ostream &) const override
virtual bool is_container() const override
virtual std::string key() const override
virtual Node & operator<<(std::string const &s) override
std::unique_ptr< Impl > node
Definition RYMLParser.h:34
virtual std::string val() const override
virtual Node & operator[](std::string const &k) override
virtual Node & append_child() override
virtual void set_seq() override
virtual bool is_seq() const override
Node(TRYMLTree *t, const Impl &other)
virtual bool has_val() const override
virtual bool has_child(std::string const &) const override
virtual void writeJSON(std::ostream &os) const override
virtual size_t num_children() const override
virtual void set_map() override
std::list< std::string > _strcache
Definition RYMLParser.h:67
void clearcache()
Node & incache(const Node &n)
Node & rootnode()
std::list< Node > _nodecache
Definition RYMLParser.h:68
const Int_t n
Definition legend1.C:16
Definition tree.py:1