libcamera: include/libcamera/internal/yaml_parser.h Source File

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