libcamera  v0.3.2+116-83c5ad0f
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 <string_view>
16 #include <vector>
17 
18 #include <libcamera/base/class.h>
19 
20 #include <libcamera/geometry.h>
21 
22 namespace libcamera {
23 
24 class File;
25 class YamlParserContext;
26 
28 {
29 private:
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 
42 public:
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 
213 private:
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 
239 class YamlParser final
240 {
241 public:
242  static std::unique_ptr<YamlObject> parse(File &file);
243 };
244 
245 } /* namespace libcamera */
bool isEmpty() const
Return whether the YamlObject is an empty.
Definition: yaml_parser.h:163
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:151
const YamlObject & operator[](std::size_t index) const
Retrieve the element from list YamlObject by index.
Definition: yaml_parser.cpp:353
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:206
bool isDictionary() const
Return whether the YamlObject is a dictionary.
Definition: yaml_parser.h:159
bool isList() const
Return whether the YamlObject is a list.
Definition: yaml_parser.h:155
std::optional< std::vector< T > > getList() const
Parse the YamlObject as a list of T.
bool contains(std::string_view key) const
Check if an element of a dictionary exists.
Definition: yaml_parser.cpp:372
Interface for I/O operations on files.
Definition: file.h:24
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:99
DictAdapter asDict() const
Wrap a dictionary YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:205
A class representing the tree structure of the YAML content.
Definition: yaml_parser.h:27
A helper class for parsing a YAML file.
Definition: yaml_parser.h:239
Data structures related to geometric objects.