libcamera  v0.3.2
Supporting cameras in Linux since 2019
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 
21 namespace libcamera {
22 
23 class File;
24 class YamlParserContext;
25 
27 {
28 private:
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 
41 public:
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 
212 private:
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 {
240 public:
241  static std::unique_ptr<YamlObject> parse(File &file);
242 };
243 
244 } /* 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.
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:27
std::size_t size() const
Retrieve the number of elements in a dictionary or list YamlObject.
Definition: yaml_parser.cpp:98
bool contains(const std::string &key) const
Check if an element of a dictionary exists.
Definition: yaml_parser.cpp:484
bool isEmpty() const
Return whether the YamlObject is an empty.
Definition: yaml_parser.h:162
bool isList() const
Return whether the YamlObject is a list.
Definition: yaml_parser.h:154
T get(U &&defaultValue) const
Parse the YamlObject as a T value.
Definition: yaml_parser.h:180
std::optional< std::vector< T > > getList() const
Parse the YamlObject as a list of T.
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition: yaml_parser.h:174
const YamlObject & operator[](std::size_t index) const
Retrieve the element from list YamlObject by index.
Definition: yaml_parser.cpp:465
DictAdapter asDict() const
Wrap a dictionary YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:204
bool isValue() const
Return whether the YamlObject is a value.
Definition: yaml_parser.h:150
bool isDictionary() const
Return whether the YamlObject is a dictionary.
Definition: yaml_parser.h:158
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:205
A helper class for parsing a YAML file.
Definition: yaml_parser.h:239
static std::unique_ptr< YamlObject > parse(File &file)
Parse a YAML file as a YamlObject.
Definition: yaml_parser.cpp:871
Data structures related to geometric objects.
Top-level libcamera namespace.
Definition: backtrace.h:17
Transform operator*(Transform t0, Transform t1)
Compose two transforms by applying t0 first then t1.
Definition: transform.cpp:209
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition: color_space.cpp:506