libcamera v0.5.1
Supporting cameras in Linux since 2019
Loading...
Searching...
No Matches
yaml_parser.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2022, Google Inc.
4 *
5 * libcamera YAML parsing helper
6 */
7
8#pragma once
9
10#include <iterator>
11#include <map>
12#include <optional>
13#include <stdint.h>
14#include <string>
15#include <string_view>
16#include <vector>
17
19
20#include <libcamera/geometry.h>
21
22namespace libcamera {
23
24class File;
25class YamlParserContext;
26
27class YamlObject
28{
29private:
30 struct Value {
31 Value(std::string &&k, std::unique_ptr<YamlObject> &&v)
32 : key(std::move(k)), value(std::move(v))
33 {
34 }
35 std::string key;
36 std::unique_ptr<YamlObject> value;
37 };
38
39 using Container = std::vector<Value>;
40 using ListContainer = std::vector<std::unique_ptr<YamlObject>>;
41
42public:
43#ifndef __DOXYGEN__
44 template<typename Derived>
45 class Iterator
46 {
47 public:
48 using difference_type = std::ptrdiff_t;
49 using iterator_category = std::forward_iterator_tag;
50
51 Iterator(typename Container::const_iterator it)
52 : it_(it)
53 {
54 }
55
56 Derived &operator++()
57 {
58 ++it_;
59 return *static_cast<Derived *>(this);
60 }
61
62 Derived operator++(int)
63 {
64 Derived it = *static_cast<Derived *>(this);
65 it_++;
66 return it;
67 }
68
69 friend bool operator==(const Iterator &a, const Iterator &b)
70 {
71 return a.it_ == b.it_;
72 }
73
74 friend bool operator!=(const Iterator &a, const Iterator &b)
75 {
76 return a.it_ != b.it_;
77 }
78
79 protected:
80 Container::const_iterator it_;
81 };
82
83 template<typename Iterator>
84 class Adapter
85 {
86 public:
87 Adapter(const Container &container)
88 : container_(container)
89 {
90 }
91
92 Iterator begin() const
93 {
94 return Iterator{ container_.begin() };
95 }
96
97 Iterator end() const
98 {
99 return Iterator{ container_.end() };
100 }
101
102 protected:
103 const Container &container_;
104 };
105
106 class ListIterator : public Iterator<ListIterator>
107 {
108 public:
109 using value_type = const YamlObject &;
110 using pointer = const YamlObject *;
111 using reference = value_type;
112
113 value_type operator*() const
114 {
115 return *it_->value.get();
116 }
117
118 pointer operator->() const
119 {
120 return it_->value.get();
121 }
122 };
123
124 class DictIterator : public Iterator<DictIterator>
125 {
126 public:
127 using value_type = std::pair<const std::string &, const YamlObject &>;
128 using pointer = value_type *;
129 using reference = value_type &;
130
131 value_type operator*() const
132 {
133 return { it_->key, *it_->value.get() };
134 }
135 };
136
137 class DictAdapter : public Adapter<DictIterator>
138 {
139 public:
140 using key_type = std::string;
141 };
142
143 class ListAdapter : public Adapter<ListIterator>
144 {
145 };
146#endif /* __DOXYGEN__ */
147
148 YamlObject();
149 ~YamlObject();
150
151 bool isValue() const
152 {
153 return type_ == Type::Value;
154 }
155 bool isList() const
156 {
157 return type_ == Type::List;
158 }
159 bool isDictionary() const
160 {
161 return type_ == Type::Dictionary;
162 }
163 bool isEmpty() const
164 {
165 return type_ == Type::Empty;
166 }
167 explicit operator bool() const
168 {
169 return type_ != Type::Empty;
170 }
171
172 std::size_t size() const;
173
174 template<typename T>
175 std::optional<T> get() const
176 {
177 return Getter<T>{}.get(*this);
178 }
179
180 template<typename T, typename U>
181 T get(U &&defaultValue) const
182 {
183 return get<T>().value_or(std::forward<U>(defaultValue));
184 }
185
186#ifndef __DOXYGEN__
187 template<typename T,
188 std::enable_if_t<
189 std::is_same_v<bool, T> ||
190 std::is_same_v<float, T> ||
191 std::is_same_v<double, T> ||
192 std::is_same_v<int8_t, T> ||
193 std::is_same_v<uint8_t, T> ||
194 std::is_same_v<int16_t, T> ||
195 std::is_same_v<uint16_t, T> ||
196 std::is_same_v<int32_t, T> ||
197 std::is_same_v<uint32_t, T> ||
198 std::is_same_v<std::string, T> ||
199 std::is_same_v<Size, T>> * = nullptr>
200#else
201 template<typename T>
202#endif
203 std::optional<std::vector<T>> getList() const;
204
205 DictAdapter asDict() const { return DictAdapter{ list_ }; }
206 ListAdapter asList() const { return ListAdapter{ list_ }; }
207
208 const YamlObject &operator[](std::size_t index) const;
209
210 bool contains(std::string_view key) const;
211 const YamlObject &operator[](std::string_view key) const;
212
213private:
215
216 template<typename T>
217 friend struct Getter;
218 friend class YamlParserContext;
219
220 enum class Type {
221 Dictionary,
222 List,
223 Value,
224 Empty,
225 };
226
227 template<typename T, typename Enable = void>
228 struct Getter {
229 std::optional<T> get(const YamlObject &obj) const;
230 };
231
232 Type type_;
233
234 std::string value_;
235 Container list_;
236 std::map<std::string, YamlObject *, std::less<>> dictionary_;
237};
238
239class YamlParser final
240{
241public:
242 static std::unique_ptr<YamlObject> parse(File &file);
243};
244
245} /* namespace libcamera */
Utilities to help constructing class interfaces.
#define LIBCAMERA_DISABLE_COPY_AND_MOVE(klass)
Disable copy and move construction and assignment of the klass.
Definition class.h:29
Interface for I/O operations on files.
Definition file.h:25
A class representing the tree structure of the YAML content.
Definition yaml_parser.h:28
std::size_t size() const
Retrieve the number of elements in a dictionary or list YamlObject.
Definition yaml_parser.cpp:99
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:175
T get(U &&defaultValue) const
Parse the YamlObject as a T value.
Definition yaml_parser.h:181
bool isValue() const
Return whether the YamlObject is a value.
Definition yaml_parser.h:151
bool contains(std::string_view key) const
Check if an element of a dictionary exists.
Definition yaml_parser.cpp:372
bool isDictionary() const
Return whether the YamlObject is a dictionary.
Definition yaml_parser.h:159
const YamlObject & operator[](std::size_t index) const
Retrieve the element from list YamlObject by index.
Definition yaml_parser.cpp:353
DictAdapter asDict() const
Wrap a dictionary YamlObject in an adapter that exposes iterators.
Definition yaml_parser.h:205
bool isEmpty() const
Return whether the YamlObject is an empty.
Definition yaml_parser.h:163
std::optional< std::vector< T > > getList() const
Parse the YamlObject as a list of T.
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition yaml_parser.h:206
bool isList() const
Return whether the YamlObject is a list.
Definition yaml_parser.h:155
A helper class for parsing a YAML file.
Definition yaml_parser.h:240
static std::unique_ptr< YamlObject > parse(File &file)
Parse a YAML file as a YamlObject.
Definition yaml_parser.cpp:765
Data structures related to geometric objects.
Top-level libcamera namespace.
Definition backtrace.h:17
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:133