libdcp
language_tag.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2020-2021 Carl Hetherington <cth@carlh.net>
3 
4  This file is part of libdcp.
5 
6  libdcp is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  libdcp is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with libdcp. If not, see <http://www.gnu.org/licenses/>.
18 
19  In addition, as a special exception, the copyright holders give
20  permission to link the code of portions of this program with the
21  OpenSSL library under certain conditions as described in each
22  individual source file, and distribute linked combinations
23  including the two.
24 
25  You must obey the GNU General Public License in all respects
26  for all of the code used other than OpenSSL. If you modify
27  file(s) with this exception, you may extend this exception to your
28  version of the file(s), but you are not obligated to do so. If you
29  do not wish to do so, delete this exception statement from your
30  version. If you delete this exception statement from all source
31  files in the program, then also delete it here.
32 */
33 
34 
40 #ifndef LIBDCP_LANGUAGE_TAG_H
41 #define LIBDCP_LANGUAGE_TAG_H
42 
43 
44 #include <boost/filesystem.hpp>
45 #include <boost/optional.hpp>
46 #include <string>
47 #include <vector>
48 
49 
50 namespace dcp {
51 
52 
54 {
55 public:
56  std::string to_string () const;
57  std::string description () const;
58 
59  struct SubtagData
60  {
61  SubtagData () {}
62 
63  SubtagData (std::string subtag_, std::string description_)
64  : subtag(subtag_)
65  , description(description_)
66  {}
67 
68  std::string subtag;
69  std::string description;
70 
71  bool operator== (SubtagData const& other) const {
72  return subtag == other.subtag && description == other.description;
73  }
74 
75  bool operator!=(SubtagData const& other) const {
76  return subtag != other.subtag || description != other.description;
77  }
78  };
79 
80  enum class SubtagType
81  {
82  LANGUAGE,
83  SCRIPT,
84  REGION,
85  VARIANT,
86  EXTLANG,
87  };
88 
89  class Subtag
90  {
91  public:
92  virtual ~Subtag () {}
93 
94  std::string subtag () const {
95  return _subtag;
96  }
97 
98  virtual SubtagType type () const = 0;
99 
100  bool operator== (Subtag const& other) const {
101  return _subtag == other._subtag;
102  }
103 
104  bool operator!=(Subtag const& other) const {
105  return _subtag != other._subtag;
106  }
107 
108  bool operator<(Subtag const& other) const {
109  return _subtag < other._subtag;
110  }
111 
112  protected:
113  Subtag (std::string subtag, SubtagType type);
114 
115  private:
116  std::string _subtag;
117  };
118 
119  class LanguageSubtag : public Subtag
120  {
121  public:
122  LanguageSubtag (std::string subtag)
123  : Subtag(subtag, SubtagType::LANGUAGE) {}
124  LanguageSubtag (char const* subtag)
125  : Subtag(subtag, SubtagType::LANGUAGE) {}
126 
127  SubtagType type () const override {
128  return SubtagType::LANGUAGE;
129  }
130  };
131 
132  class ScriptSubtag : public Subtag
133  {
134  public:
135  ScriptSubtag (std::string subtag)
136  : Subtag(subtag, SubtagType::SCRIPT) {}
137  ScriptSubtag (char const* subtag)
138  : Subtag(subtag, SubtagType::SCRIPT) {}
139 
140  SubtagType type () const override {
141  return SubtagType::SCRIPT;
142  }
143  };
144 
145  class RegionSubtag : public Subtag
146  {
147  public:
148  RegionSubtag (std::string subtag)
149  : Subtag(subtag, SubtagType::REGION) {}
150  RegionSubtag (char const* subtag)
151  : Subtag(subtag, SubtagType::REGION) {}
152 
153  SubtagType type () const override {
154  return SubtagType::REGION;
155  }
156  };
157 
158  class VariantSubtag : public Subtag
159  {
160  public:
161  VariantSubtag (std::string subtag)
162  : Subtag(subtag, SubtagType::VARIANT) {}
163  VariantSubtag (char const* subtag)
164  : Subtag(subtag, SubtagType::VARIANT) {}
165 
166  SubtagType type () const override {
167  return SubtagType::VARIANT;
168  }
169  };
170 
171 
172  class ExtlangSubtag : public Subtag
173  {
174  public:
175  ExtlangSubtag (std::string subtag)
176  : Subtag(subtag, SubtagType::EXTLANG) {}
177  ExtlangSubtag (char const* subtag)
178  : Subtag(subtag, SubtagType::EXTLANG) {}
179 
180  SubtagType type () const override {
181  return SubtagType::EXTLANG;
182  }
183  };
184 
185  LanguageTag () {}
186  explicit LanguageTag (std::string tag);
187 
188  boost::optional<LanguageSubtag> language() const {
189  return _language;
190  }
191 
192  void set_language (LanguageSubtag language);
193 
194  boost::optional<ScriptSubtag> script() const {
195  return _script;
196  }
197 
198  void set_script (ScriptSubtag script);
199 
200  boost::optional<RegionSubtag> region() const {
201  return _region;
202  }
203 
204  void set_region (RegionSubtag region);
205 
206  std::vector<VariantSubtag> variants() const {
207  return _variants;
208  }
209 
210  void set_variants (std::vector<VariantSubtag> variants);
211  void add_variant (VariantSubtag variant);
212 
213  std::vector<ExtlangSubtag> extlangs() const {
214  return _extlangs;
215  }
216 
217  void set_extlangs (std::vector<ExtlangSubtag> extlangs);
218  void add_extlang (ExtlangSubtag extlang);
219 
220  std::vector<std::pair<SubtagType, SubtagData>> subtags () const;
221 
222  static std::vector<SubtagData> const& get_all (SubtagType type);
223  static std::string subtag_type_name (SubtagType type);
224 
225  static boost::optional<std::string> get_subtag_description (SubtagType, std::string subtag);
226  static boost::optional<SubtagData> get_subtag_data (SubtagType, std::string subtag);
227 
228  template <class T>
229  static boost::optional<std::string> get_subtag_description (T s) {
230  return get_subtag_description (s.type(), s.subtag());
231  }
232 
233  template <class T>
234  static boost::optional<SubtagData> get_subtag_data (T s) {
235  return get_subtag_data (s.type(), s.subtag());
236  }
237 
238 private:
239 
240  boost::optional<LanguageSubtag> _language;
241  boost::optional<ScriptSubtag> _script;
242  boost::optional<RegionSubtag> _region;
243  std::vector<VariantSubtag> _variants;
244  std::vector<ExtlangSubtag> _extlangs;
245 };
246 
247 
248 extern bool operator==(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
249 extern bool operator!=(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
250 extern bool operator<(dcp::LanguageTag const& a, dcp::LanguageTag const& b);
251 extern std::ostream& operator<<(std::ostream& os, dcp::LanguageTag const& tag);
252 
253 
254 extern void load_language_tag_lists (boost::filesystem::path tags_directory);
255 
256 
257 extern std::vector<std::pair<std::string, std::string>> dcnc_tags ();
258 
259 
260 }
261 
262 
263 #endif
Namespace for everything in libdcp.
Definition: array_data.h:50