27 #include <boost/multi_index/hashed_index.hpp> 34 #define LOG_CF LOG_STREAM(info, log_config) 35 #define ERR_CF LOG_STREAM(err, log_config) 41 const char TRANSLATABLE_PART = 0x01;
42 const char UNTRANSLATABLE_PART = 0x02;
43 const char TEXTDOMAIN_SEPARATOR = 0x03;
44 const char ID_TRANSLATABLE_PART = 0x04;
45 const char PLURAL_PART = 0x05;
51 boost::hash_combine(seed,
value_);
60 , end_(string_.
size())
71 static std::string
mark = std::string(TRANSLATABLE_PART, 1) + UNTRANSLATABLE_PART + ID_TRANSLATABLE_PART + PLURAL_PART;
82 case TRANSLATABLE_PART: {
84 std::string::size_type textdomain_end =
string_.find(TEXTDOMAIN_SEPARATOR, begin_ + 1);
86 if(textdomain_end == std::string::npos || textdomain_end >=
string_.size() - 1) {
88 begin_ = string_.size();
93 if(
end_ == std::string::npos) {
99 begin_ = textdomain_end + 1;
103 case ID_TRANSLATABLE_PART:
105 if(begin_ + 3 >=
string_.size()) {
107 begin_ = string_.size();
112 if(
end_ == std::string::npos) {
116 id =
static_cast<unsigned char>(
string_[begin_ + 1]) + static_cast<unsigned char>(
string_[begin_ + 2]) * 256;
119 begin_ = string_.size();
129 case UNTRANSLATABLE_PART:
131 if(
end_ == std::string::npos) {
135 if(
end_ <= begin_ + 1) {
137 begin_ = string_.size();
148 if(begin_ == std::string::npos) {
152 if(
string_[begin_] == PLURAL_PART) {
154 begin_ = string_.size();
172 begin_ = string_.size();
176 std::string::size_type real_end =
string_.find_first_of(
mark,
end_ + 6);
177 if(real_end <
string_.size() &&
string_[real_end] == PLURAL_PART) {
179 begin_ = string_.size();
190 std::copy_n(
string_.data() +
end_ + 1, 4, cvt.data);
214 if(pl_end == std::string::npos) {
218 return string_.begin() + pl_end;
253 :
value_(1, ID_TRANSLATABLE_PART)
265 std::map<std::string, unsigned int>::const_iterator idi =
textdomain_to_id.find(textdomain);
276 value_ +=
static_cast<char>(
id & 0xff);
277 value_ +=
static_cast<char>(
id >> 8);
282 :
value_(1, ID_TRANSLATABLE_PART)
288 if(sing.empty() && pl.empty()) {
294 std::map<std::string, unsigned int>::const_iterator idi =
textdomain_to_id.find(textdomain);
305 value_ +=
static_cast<char>(
id & 0xff);
306 value_ +=
static_cast<char>(
id >> 8);
316 for(
char c : cvt.data) {
336 if(!
string.
empty() && (
string[0] == TRANSLATABLE_PART ||
string[0] == UNTRANSLATABLE_PART)) {
344 for(
walker w(orig); !
w.eos();
w.next()) {
345 std::string substr(
w.begin(),
w.end());
347 if(
w.translatable()) {
360 for(
walker w(*
this); !
w.eos();
w.next()) {
361 res += std::string(
w.begin(),
w.end());
371 for(
walker w(*
this); !
w.eos();
w.next()) {
374 std::string substr(
w.begin(),
w.end());
375 if(
w.translatable()) {
378 chunk.
value_ = TRANSLATABLE_PART +
w.textdomain() + TEXTDOMAIN_SEPARATOR + substr;
446 if(
string.
value_.empty()) {
458 translatable_ =
true;
464 if(
string.translatable_) {
466 value_.append(
string.
value_.begin() + 1,
string.value_.end());
474 value_ += UNTRANSLATABLE_PART;
500 value_ += UNTRANSLATABLE_PART;
526 value_ += UNTRANSLATABLE_PART;
571 for(
walker w(*
this); !
w.eos();
w.next()) {
572 std::string part(
w.begin(),
w.end());
574 if(
w.translatable()) {
576 std::string plural(
w.plural_begin(),
w.plural_end());
627 :
val_(new
base(s, pl, c, textdomain))
646 LOG_CF <<
"Binding textdomain " << name <<
" to path " <<
path;
664 stream <<
string.str();
static unsigned language_counter
std::string::const_iterator begin() const
std::string base_str() const
static void reset_translations()
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
std::string::const_iterator plural_begin() const
void bind_textdomain(const char *domain, const char *directory, const char *)
static std::vector< std::string > id_to_textdomain
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
std::string to_serialized() const
void swap(t_string &other)
std::string dsngettext(const char *domainname, const char *singular, const char *plural, int n)
std::string::size_type end_
const std::string & string_
bool operator==(const t_string_base &) const
const std::string & value() const
bool last_untranslatable_
std::string::size_type size() const
bool operator<(const t_string_base &string) const
const std::string & str() const
std::string dsgettext(const char *domainname, const char *msgid)
t_string_base & operator=(const t_string_base &)
Default implementation, but defined out-of-line for efficiency reasons.
unsigned translation_timestamp_
std::string translated_value_
std::string::size_type begin_
static void add_textdomain(const std::string &name, const std::string &path)
std::size_t hash_value() const
walker(const t_string_base &string)
t_string & operator=(const t_string &)
Default implementation, but defined out-of-line for efficiency reasons.
std::string::const_iterator plural_end() const
static lg::log_domain log_config("config")
std::string id
Text to match against addon_info.tags()
const route_iterator begin_
~t_string()
Default implementation, but defined out-of-line for efficiency reasons.
static map_location::DIRECTION s
std::string::const_iterator end() const
std::shared_ptr< const t_string_base > val_
Standard logging facilities (interface).
t_string_base & operator+=(const t_string_base &)
t_string_base operator+(const t_string_base &) const
std::ostream & operator<<(std::ostream &stream, const t_string_base &string)
static std::map< std::string, unsigned int > textdomain_to_id
static t_string_base from_serialized(const std::string &string)