Allow LanguageTag to be constructed from a tag string.
authorCarl Hetherington <cth@carlh.net>
Thu, 27 Aug 2020 20:48:00 +0000 (22:48 +0200)
committerCarl Hetherington <cth@carlh.net>
Sun, 20 Sep 2020 17:30:46 +0000 (19:30 +0200)
src/language_tag.cc
src/language_tag.h
test/language_tag_test.cc

index 47b4602429da9b8db9905b29360857e4336c94b5..b64dab72ea763036587edcbb4676a31f4de32a93 100644 (file)
@@ -36,6 +36,7 @@
 #include "dcp_assert.h"
 #include "exceptions.h"
 #include "language_tag.h"
+#include <boost/algorithm/string.hpp>
 #include <boost/foreach.hpp>
 #include <string>
 
@@ -93,6 +94,66 @@ LanguageTag::Subtag::Subtag (string subtag, SubtagType type)
 }
 
 
+LanguageTag::LanguageTag (string tag)
+{
+       vector<string> parts;
+       boost::split (parts, tag, boost::is_any_of("-"));
+       if (parts.empty()) {
+               throw LanguageTagError (String::compose("Could not parse language tag %1", tag));
+       }
+
+       vector<string>::size_type p = 0;
+       _language = LanguageSubtag (parts[p]);
+       ++p;
+
+       if (p == parts.size()) {
+               return;
+       }
+
+       try {
+               _script = ScriptSubtag (parts[p]);
+               ++p;
+       } catch (...) {}
+
+       if (p == parts.size()) {
+               return;
+       }
+
+       try {
+               _region = RegionSubtag (parts[p]);
+               ++p;
+       } catch (...) {}
+
+       if (p == parts.size()) {
+               return;
+       }
+
+       try {
+               while (true) {
+                       _variants.push_back (VariantSubtag(parts[p]));
+                       ++p;
+                       if (p == parts.size()) {
+                               return;
+                       }
+               }
+       } catch (...) {}
+
+       try {
+               while (true) {
+                       _extlangs.push_back (ExtlangSubtag(parts[p]));
+                       ++p;
+                       if (p == parts.size()) {
+                               return;
+                       }
+               }
+       } catch (...) {}
+
+       if (p < parts.size()) {
+               throw LanguageTagError (String::compose("Unrecognised subtag %1", parts[p]));
+       }
+}
+
+
 string
 LanguageTag::to_string () const
 {
index 7a6fd159ee18495a7055506e0903547ab3550174..8aa8a723db3ee8ea4923029c863a7463b3185d6c 100644 (file)
@@ -141,6 +141,9 @@ public:
                bool operator< (ExtlangSubtag const& other) const;
        };
 
+       LanguageTag () {}
+       LanguageTag (std::string tag);
+
        void set_language (LanguageSubtag language);
        void set_script (ScriptSubtag script);
        void set_region (RegionSubtag region);
index fd90b6295f5e1cd891f93c0670ac210adf5147f7..28c46b6326d3a5163910f7313dce4b5185a2121d 100644 (file)
@@ -41,7 +41,7 @@ using std::vector;
 using std::string;
 
 
-BOOST_AUTO_TEST_CASE (language_tag_test)
+BOOST_AUTO_TEST_CASE (language_tag_create_test)
 {
        /* Bad subtags raise errors */
 
@@ -177,3 +177,22 @@ BOOST_AUTO_TEST_CASE (language_tag_test)
        }
 
 }
+
+
+BOOST_AUTO_TEST_CASE (language_tag_parse_test)
+{
+       BOOST_CHECK_THROW (dcp::LanguageTag(""), dcp::LanguageTagError);
+       BOOST_CHECK_THROW (dcp::LanguageTag("...Aw498012351!"), dcp::LanguageTagError);
+       BOOST_CHECK_THROW (dcp::LanguageTag("fish"), dcp::LanguageTagError);
+       BOOST_CHECK_THROW (dcp::LanguageTag("de-Dogr-fish"), dcp::LanguageTagError);
+       BOOST_CHECK_THROW (dcp::LanguageTag("de-Dogr-DE-aranes-fish"), dcp::LanguageTagError);
+
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de").to_string(), "de");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr").to_string(), "de-Dogr");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr-DE").to_string(), "de-Dogr-DE");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr-DE-aranes").to_string(), "de-Dogr-DE-aranes");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr-DE-aranes-lemosin").to_string(), "de-Dogr-DE-aranes-lemosin");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr-DE-aranes-lemosin-abv").to_string(), "de-Dogr-DE-aranes-lemosin-abv");
+       BOOST_CHECK_EQUAL (dcp::LanguageTag("de-Dogr-DE-aranes-lemosin-abv-zsm").to_string(), "de-Dogr-DE-aranes-lemosin-abv-zsm");
+}
+