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