libcamera  v0.0.4
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  * yaml_parser.h - 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 #ifndef __DOXYGEN__
165  template<typename T,
166  std::enable_if_t<
167  std::is_same_v<bool, T> ||
168  std::is_same_v<double, T> ||
169  std::is_same_v<int8_t, T> ||
170  std::is_same_v<uint8_t, T> ||
171  std::is_same_v<int16_t, T> ||
172  std::is_same_v<uint16_t, T> ||
173  std::is_same_v<int32_t, T> ||
174  std::is_same_v<uint32_t, T> ||
175  std::is_same_v<std::string, T> ||
176  std::is_same_v<Size, T>> * = nullptr>
177 #else
178  template<typename T>
179 #endif
180  std::optional<T> get() const;
181 
182  template<typename T>
183  T get(const T &defaultValue) const
184  {
185  return get<T>().value_or(defaultValue);
186  }
187 
188 #ifndef __DOXYGEN__
189  template<typename T,
190  std::enable_if_t<
191  std::is_same_v<bool, T> ||
192  std::is_same_v<double, T> ||
193  std::is_same_v<int8_t, T> ||
194  std::is_same_v<uint8_t, T> ||
195  std::is_same_v<int16_t, T> ||
196  std::is_same_v<uint16_t, T> ||
197  std::is_same_v<int32_t, T> ||
198  std::is_same_v<uint32_t, T> ||
199  std::is_same_v<std::string, T> ||
200  std::is_same_v<Size, T>> * = nullptr>
201 #else
202  template<typename T>
203 #endif
204  std::optional<std::vector<T>> getList() const;
205 
206  DictAdapter asDict() const { return DictAdapter{ list_ }; }
207  ListAdapter asList() const { return ListAdapter{ list_ }; }
208 
209  const YamlObject &operator[](std::size_t index) const;
210 
211  bool contains(const std::string &key) const;
212  const YamlObject &operator[](const std::string &key) const;
213 
214 private:
216 
217  friend class YamlParserContext;
218 
219  enum class Type {
220  Dictionary,
221  List,
222  Value,
223  };
224 
225  Type type_;
226 
227  std::string value_;
228  Container list_;
229  std::map<std::string, YamlObject *> dictionary_;
230 };
231 
232 class YamlParser final
233 {
234 public:
235  static std::unique_ptr<YamlObject> parse(File &file);
236 };
237 
238 } /* 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:26
std::size_t size() const
Retrieve the number of elements in a dictionary or list YamlObject.
Definition: yaml_parser.cpp:84
T get(const T &defaultValue) const
Parse the YamlObject as a T value.
Definition: yaml_parser.h:183
bool contains(const std::string &key) const
Check if an element of a dictionary exists.
Definition: yaml_parser.cpp:450
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.
std::optional< T > get() const
Parse the YamlObject as a T value.
const YamlObject & operator[](std::size_t index) const
Retrieve the element from list YamlObject by index.
Definition: yaml_parser.cpp:431
DictAdapter asDict() const
Wrap a dictionary YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:206
bool isValue() const
Return whether the YamlObject is a value.
Definition: yaml_parser.h:149
bool isDictionary() const
Return whether the YamlObject is a dictionary.
Definition: yaml_parser.h:157
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:207
A helper class for parsing a YAML file.
Definition: yaml_parser.h:233
static std::unique_ptr< YamlObject > parse(File &file)
Parse a YAML file as a YamlObject.
Definition: yaml_parser.cpp:834
Data structures related to geometric objects.
Top-level libcamera namespace.
Definition: backtrace.h:17
Transform operator*(Transform t0, Transform t1)
Compose two transforms together.
Definition: transform.cpp:207
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition: color_space.cpp:506