X-Git-Url: https://main.carlh.net/gitweb/?p=libdcp.git;a=blobdiff_plain;f=src%2Flanguage_tag.cc;h=c2e81869ed133cbb8a10a5eeed5d6a980e3a471f;hp=cb5f84c92b3039b825b6caa88dec991310e4d00a;hb=ceaf7bc52712cb60708ed5eb5c62c5e463dd8e89;hpb=f3e69079eefa18407b110ff23df26f7711ebf7e5 diff --git a/src/language_tag.cc b/src/language_tag.cc index cb5f84c9..c2e81869 100644 --- a/src/language_tag.cc +++ b/src/language_tag.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of libdcp. @@ -32,12 +32,16 @@ */ +/** @file src/language_tag.cc + * @brief LanguageTag class + */ + + #include "compose.hpp" #include "dcp_assert.h" #include "exceptions.h" #include "language_tag.h" #include -#include #include @@ -47,23 +51,28 @@ using std::pair; using std::string; using std::vector; using boost::optional; +using boost::algorithm::trim; using namespace dcp; -#include "language_tag_lists.cc" +static vector language_list; +static vector variant_list; +static vector region_list; +static vector script_list; +static vector extlang_list; static optional -find_in_list (LanguageTag::SubtagData const * list, int length, string subtag) +find_in_list (vector const& list, string subtag) { - for (int i = 0; i < length; ++i) { - if (list[i].subtag == subtag) { - return list[i]; + for (auto const& i: list) { + if (boost::iequals(i.subtag, subtag)) { + return i; } } - return optional(); + return {}; } @@ -143,7 +152,7 @@ LanguageTag::to_string () const throw LanguageTagError("No language set up"); } - string s = _language->subtag(); + auto s = _language->subtag(); if (_script) { s += "-" + _script->subtag(); @@ -153,11 +162,11 @@ LanguageTag::to_string () const s += "-" + _region->subtag(); } - BOOST_FOREACH (VariantSubtag i, _variants) { + for (auto i: _variants) { s += "-" + i.subtag(); } - BOOST_FOREACH (ExtlangSubtag i, _extlangs) { + for (auto i: _extlangs) { s += "-" + i.subtag(); } @@ -204,7 +213,7 @@ check_for_duplicates (vector const& subtags, dcp::LanguageTag::SubtagType typ vector sorted = subtags; sort (sorted.begin(), sorted.end()); optional last; - BOOST_FOREACH (T const& i, sorted) { + for (auto const& i: sorted) { if (last && i == *last) { throw LanguageTagError (String::compose("Duplicate %1 subtag %2", dcp::LanguageTag::subtag_type_name(type), i.subtag())); } @@ -216,7 +225,7 @@ check_for_duplicates (vector const& subtags, dcp::LanguageTag::SubtagType typ void LanguageTag::set_variants (vector variants) { - check_for_duplicates (variants, VARIANT); + check_for_duplicates (variants, SubtagType::VARIANT); _variants = variants; } @@ -235,7 +244,7 @@ LanguageTag::add_extlang (ExtlangSubtag extlang) void LanguageTag::set_extlangs (vector extlangs) { - check_for_duplicates (extlangs, EXTLANG); + check_for_duplicates (extlangs, SubtagType::EXTLANG); _extlangs = extlangs; } @@ -249,30 +258,30 @@ LanguageTag::description () const string d; - BOOST_FOREACH (VariantSubtag const& i, _variants) { - optional variant = get_subtag_data (VARIANT, i.subtag()); + for (auto const& i: _variants) { + optional variant = get_subtag_data (SubtagType::VARIANT, i.subtag()); DCP_ASSERT (variant); d += variant->description + " dialect of "; } - optional language = get_subtag_data (LANGUAGE, _language->subtag()); + auto language = get_subtag_data (SubtagType::LANGUAGE, _language->subtag()); DCP_ASSERT (language); d += language->description; if (_script) { - optional script = get_subtag_data (SCRIPT, _script->subtag()); + auto script = get_subtag_data (SubtagType::SCRIPT, _script->subtag()); DCP_ASSERT (script); d += " written using the " + script->description + " script"; } if (_region) { - optional region = get_subtag_data (REGION, _region->subtag()); + auto region = get_subtag_data (SubtagType::REGION, _region->subtag()); DCP_ASSERT (region); d += " for " + region->description; } - BOOST_FOREACH (ExtlangSubtag const& i, _extlangs) { - optional extlang = get_subtag_data (EXTLANG, i.subtag()); + for (auto const& i: _extlangs) { + auto extlang = get_subtag_data (SubtagType::EXTLANG, i.subtag()); DCP_ASSERT (extlang); d += ", " + extlang->description; } @@ -281,40 +290,23 @@ LanguageTag::description () const } -vector +vector const & LanguageTag::get_all (SubtagType type) { - vector all; - switch (type) { - case LANGUAGE: - for (size_t i = 0; i < sizeof(language_list) / sizeof(LanguageTag::SubtagData); ++i) { - all.push_back (language_list[i]); - } - break; - case SCRIPT: - for (size_t i = 0; i < sizeof(script_list) / sizeof(LanguageTag::SubtagData); ++i) { - all.push_back (script_list[i]); - } - break; - case REGION: - for (size_t i = 0; i < sizeof(region_list) / sizeof(LanguageTag::SubtagData); ++i) { - all.push_back (region_list[i]); - } - break; - case VARIANT: - for (size_t i = 0; i < sizeof(variant_list) / sizeof(LanguageTag::SubtagData); ++i) { - all.push_back (variant_list[i]); - } - break; - case EXTLANG: - for (size_t i = 0; i < sizeof(extlang_list) / sizeof(LanguageTag::SubtagData); ++i) { - all.push_back (extlang_list[i]); - } - break; + case SubtagType::LANGUAGE: + return language_list; + case SubtagType::SCRIPT: + return script_list; + case SubtagType::REGION: + return region_list; + case SubtagType::VARIANT: + return variant_list; + case SubtagType::EXTLANG: + return extlang_list; } - return all; + return language_list; } @@ -322,19 +314,19 @@ string LanguageTag::subtag_type_name (SubtagType type) { switch (type) { - case LANGUAGE: + case SubtagType::LANGUAGE: return "Language"; - case SCRIPT: + case SubtagType::SCRIPT: return "Script"; - case REGION: + case SubtagType::REGION: return "Region"; - case VARIANT: + case SubtagType::VARIANT: return "Variant"; - case EXTLANG: + case SubtagType::EXTLANG: return "Extended"; } - return ""; + return {}; } bool @@ -383,26 +375,26 @@ dcp::operator<< (ostream& os, dcp::LanguageTag const& tag) vector > LanguageTag::subtags () const { - vector > s; + vector> s; if (_language) { - s.push_back (make_pair(LANGUAGE, *get_subtag_data(LANGUAGE, _language->subtag()))); + s.push_back (make_pair(SubtagType::LANGUAGE, *get_subtag_data(SubtagType::LANGUAGE, _language->subtag()))); } if (_script) { - s.push_back (make_pair(SCRIPT, *get_subtag_data(SCRIPT, _script->subtag()))); + s.push_back (make_pair(SubtagType::SCRIPT, *get_subtag_data(SubtagType::SCRIPT, _script->subtag()))); } if (_region) { - s.push_back (make_pair(REGION, *get_subtag_data(REGION, _region->subtag()))); + s.push_back (make_pair(SubtagType::REGION, *get_subtag_data(SubtagType::REGION, _region->subtag()))); } - BOOST_FOREACH (VariantSubtag const& i, _variants) { - s.push_back (make_pair(VARIANT, *get_subtag_data(VARIANT, i.subtag()))); + for (auto const& i: _variants) { + s.push_back (make_pair(SubtagType::VARIANT, *get_subtag_data(SubtagType::VARIANT, i.subtag()))); } - BOOST_FOREACH (ExtlangSubtag const& i, _extlangs) { - s.push_back (make_pair(EXTLANG, *get_subtag_data(EXTLANG, i.subtag()))); + for (auto const& i: _extlangs) { + s.push_back (make_pair(SubtagType::EXTLANG, *get_subtag_data(SubtagType::EXTLANG, i.subtag()))); } return s; @@ -413,30 +405,74 @@ optional LanguageTag::get_subtag_data (LanguageTag::SubtagType type, string subtag) { switch (type) { - case dcp::LanguageTag::LANGUAGE: - return find_in_list(language_list, sizeof(language_list) / sizeof(LanguageTag::SubtagData), subtag); - case dcp::LanguageTag::SCRIPT: - return find_in_list(script_list, sizeof(script_list) / sizeof(LanguageTag::SubtagData), subtag); - case dcp::LanguageTag::REGION: - return find_in_list(region_list, sizeof(region_list) / sizeof(LanguageTag::SubtagData), subtag); - case dcp::LanguageTag::VARIANT: - return find_in_list(variant_list, sizeof(variant_list) / sizeof(LanguageTag::SubtagData), subtag); - case dcp::LanguageTag::EXTLANG: - return find_in_list(extlang_list, sizeof(extlang_list) / sizeof(LanguageTag::SubtagData), subtag); + case SubtagType::LANGUAGE: + return find_in_list(language_list, subtag); + case SubtagType::SCRIPT: + return find_in_list(script_list, subtag); + case SubtagType::REGION: + return find_in_list(region_list, subtag); + case SubtagType::VARIANT: + return find_in_list(variant_list, subtag); + case SubtagType::EXTLANG: + return find_in_list(extlang_list, subtag); } - return optional(); + return {}; } optional LanguageTag::get_subtag_description (LanguageTag::SubtagType type, string subtag) { - optional data = get_subtag_data (type, subtag); + auto data = get_subtag_data (type, subtag); if (!data) { - return optional(); + return {}; } return data->description; } + +void +load_language_tag_list (boost::filesystem::path tags_directory, string name, vector& list) +{ + auto f = fopen_boost (tags_directory / name, "r"); + if (!f) { + throw FileError ("Could not open tags file", tags_directory / name, errno); + } + char buffer[512]; + + int i = 0; + while (!feof(f)) { + char* r = fgets (buffer, sizeof(buffer), f); + if (r == 0) { + break; + } + string a = buffer; + trim (a); + r = fgets (buffer, sizeof(buffer), f); + if (r == 0) { + fclose (f); + throw FileError ("Bad tags file", tags_directory / name, -1); + } + string b = buffer; + trim (b); + list.push_back (LanguageTag::SubtagData(a, b)); + ++i; + } + + fclose (f); +} + + +void +dcp::load_language_tag_lists (boost::filesystem::path tags_directory) +{ + load_language_tag_list (tags_directory, "language", language_list); + load_language_tag_list (tags_directory, "variant", variant_list); + load_language_tag_list (tags_directory, "region", region_list); + load_language_tag_list (tags_directory, "script", script_list); + load_language_tag_list (tags_directory, "extlang", extlang_list); +} + +