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_in_place({}, 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 return *this;
117}
118
120{
121 // assign this node to be a sequence (JSON array)
122 node->get() |= c4::yml::SEQ;
123 return *this;
124}
125
127{
128 throw std::logic_error("Function not yet implemented");
129}
130
131TRYMLTree::TRYMLTree(std::istream &is)
132 : tree(std::make_unique<Impl>(is)){
133 // constructor taking an istream (for reading)
134 };
135
137 : tree(std::make_unique<Impl>()){
138 // default constructor (for writing)
139 };
140
142{
143 // destructor. clears the cache.
144 clearcache();
145};
146
147// JSONNode interface implementation
148
149TRYMLTree::Node::Node(TRYMLTree *t, const TRYMLTree::Node::Impl &imp) : tree(t), node(std::make_unique<Impl>(imp))
150{
151 // construct a new node from scratch
152}
153
154TRYMLTree::Node::Node(const Node &other) : Node(other.tree, other.node->get())
155{
156 // copy constructor
157}
158
160{
161 // obtain the root node of a tree
162 return Node::Impl::mkNode(this, tree->get().rootref());
163}
164
166{
167 // write a string to this node
168 node->get() << s;
169 return *this;
170}
171
173{
174 // write an int to this node
175 node->get() << i;
176 return *this;
177}
178
180{
181 // write a double to this node
182 node->get() << d;
183 return *this;
184}
185
187{
188 // write a bool to this node
189 node->get() << b;
190 return *this;
191}
192
194{
195 // read a string from this node
196 node->get() >> v;
197 return *this;
198}
199
201{
202 // get a child node with the given key
203 return Impl::mkNode(tree, node->get()[c4::to_csubstr(tree->incache(k))]);
204}
205
206const TRYMLTree::Node &TRYMLTree::Node::operator[](std::string const &k) const
207{
208 // get a child node with the given key (const version)
209 return Impl::mkNode(tree, node->get()[c4::to_csubstr(tree->incache(k))]);
210}
211
213{
214 // return true if this node can have child nodes
215 return node->get().is_container();
216}
217
219{
220 // return true if this node is a map (JSON object)
221 return node->get().is_map();
222}
223
225{
226 // return true if this node is a sequence (JSON array)
227 return node->get().is_seq();
228}
229
230std::string TRYMLTree::Node::key() const
231{
232 // obtain the key of this node
233 std::stringstream ss;
234 ss << node->get().key();
235 return ss.str();
236}
237
238std::string TRYMLTree::Node::val() const
239{
240 ;
241 // obtain the value of this node (as a string)
242 std::stringstream ss;
243 ss << node->get().val();
244 return ss.str();
245}
246
248{
249 // append a new child to this node
250 return Impl::mkNode(tree, node->get().append_child());
251}
252
254{
255 // return true if this node has a key
256 return node->get().has_key();
257}
258
260{
261 // return true if this node has a value
262 return node->get().has_val();
263}
264
265bool TRYMLTree::Node::has_child(std::string const &s) const
266{
267 // return true if this node has a child with the given key
268 return node->get().has_child(c4::to_csubstr(s.c_str()));
269}
270
272{
273 // return the number of child nodes of this node
274 return node->get().num_children();
275}
276
278{
279 // return the child with the given index
280 return Impl::mkNode(tree, node->get().child(pos));
281}
282
284{
285 // return the child with the given index (const version)
286 return Impl::mkNode(tree, node->get().child(pos));
287}
288
289// specific functions
290
291namespace {
292void error_cb(const char *msg, size_t msg_len, c4::yml::Location /*not used*/, void * /*user_data*/)
293{
294 // error callback using std::runtime_error
295 if (msg && msg_len > 0) {
296 throw std::runtime_error(msg);
297 } else {
298 throw std::runtime_error("error handler invoked without error message");
299 }
300}
301
302bool setcallbacks()
303{
304 // set the custom callback functions
305 c4::yml::set_callbacks(c4::yml::Callbacks(c4::yml::get_callbacks().m_user_data, c4::yml::get_callbacks().m_allocate,
306 c4::yml::get_callbacks().m_free, &::error_cb));
307 return true;
308}
309bool ok = setcallbacks();
310} // namespace
311
312const char *TRYMLTree::incache(const std::string &str)
313{
314 // obtain a string from the string cache
315 _strcache.push_back(str);
316 return _strcache.back().c_str();
317}
318
320{
321 // obtain a node from the node cache
322 _nodecache.push_back(n);
323 return _nodecache.back();
324}
325
327{
328 // clear all caches
330 TRYMLTree::_nodecache.clear();
331}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
JSONNode & get(std::string const &key)
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)
bool is_map() const override
bool has_key() const override
Node & child(size_t pos) override
const Node & operator>>(std::string &v) const override
void writeYML(std::ostream &) const override
bool is_container() const override
void clear() override
std::string key() const override
Node & set_map() override
Node & operator<<(std::string const &s) override
std::unique_ptr< Impl > node
Definition RYMLParser.h:35
std::string val() const override
Node & operator[](std::string const &k) override
Node & append_child() override
bool is_seq() const override
Node(TRYMLTree *t, const Impl &other)
bool has_val() const override
bool has_child(std::string const &) const override
void writeJSON(std::ostream &os) const override
size_t num_children() const override
Node & set_seq() override
std::unique_ptr< Impl > tree
Definition RYMLParser.h:27
std::list< std::string > _strcache
Definition RYMLParser.h:68
~TRYMLTree() override
void clearcache()
Node & incache(const Node &n)
Node & rootnode() override
std::list< Node > _nodecache
Definition RYMLParser.h:69
const Int_t n
Definition legend1.C:16