31 #include <boost/functional/hash.hpp>
33 #include <boost/multi_index_container.hpp>
34 #include <boost/multi_index/hashed_index.hpp>
35 #include <boost/multi_index/member.hpp>
38 #define LOG_CF LOG_STREAM(info, log_config)
39 #define ERR_CF LOG_STREAM(err, log_config)
44 const char TRANSLATABLE_PART = 0x01;
45 const char UNTRANSLATABLE_PART = 0x02;
46 const char TEXTDOMAIN_SEPARATOR = 0x03;
47 const char ID_TRANSLATABLE_PART = 0x04;
49 std::vector<std::string> id_to_textdomain;
50 std::map<std::string, unsigned int> textdomain_to_id;
55 boost::hash_combine(seed,
value_);
84 case TRANSLATABLE_PART: {
85 std::string::size_type textdomain_end =
86 string_.find(TEXTDOMAIN_SEPARATOR, begin_ + 1);
88 if(textdomain_end == std::string::npos || textdomain_end >=
string_.size() - 1) {
94 end_ =
string_.find_first_of(mark, textdomain_end + 1);
95 if(end_ == std::string::npos)
100 begin_ = textdomain_end + 1;
104 case ID_TRANSLATABLE_PART:
105 if(begin_ + 3 >=
string_.size()) {
110 end_ =
string_.find_first_of(mark, begin_ + 3);
111 if(end_ == std::string::npos)
115 if(
id >= id_to_textdomain.size()) {
116 ERR_CF <<
"Error: invalid string: " << string_ << std::endl;
117 begin_ = string_.size();
120 textdomain_ = id_to_textdomain[
id];
126 case UNTRANSLATABLE_PART:
127 end_ = string_.find_first_of(mark, begin_ + 1);
128 if(end_ == std::string::npos)
129 end_ = string_.size();
131 if(end_ <= begin_ + 1) {
132 ERR_CF <<
"Error: invalid string: " << string_ << std::endl;
133 begin_ = string_.size();
143 end_ = string_.size();
164 value_(string.value_),
165 translated_value_(string.translated_value_),
166 translation_timestamp_(string.translation_timestamp_),
167 translatable_(string.translatable_),
168 last_untranslatable_(string.last_untranslatable_)
175 translation_timestamp_(0),
176 translatable_(false),
177 last_untranslatable_(false)
182 value_(1, ID_TRANSLATABLE_PART),
184 translation_timestamp_(0),
186 last_untranslatable_(false)
188 if (
string.
empty()) {
194 std::map<std::string, unsigned int>::const_iterator idi = textdomain_to_id.find(textdomain);
197 if(idi == textdomain_to_id.end()) {
198 id = id_to_textdomain.size();
199 textdomain_to_id[textdomain] =
id;
200 id_to_textdomain.push_back(textdomain);
205 value_ += char(
id & 0xff);
213 translation_timestamp_(0),
214 translatable_(false),
215 last_untranslatable_(false)
223 if(!
string.
empty() && (
string[0] == TRANSLATABLE_PART ||
string[0] == UNTRANSLATABLE_PART)) {
231 for(
walker w(orig); !
w.eos();
w.next()) {
234 if(
w.translatable()) {
247 for(
walker w(*
this); !
w.eos();
w.next()) {
257 for(
walker w(*
this); !
w.eos();
w.next()) {
261 if(
w.translatable()) {
264 chunk.
value_ = TRANSLATABLE_PART +
w.textdomain() +
265 TEXTDOMAIN_SEPARATOR + substr;
333 if (
string.
value_.empty())
343 translatable_ =
true;
347 if(
string.translatable_) {
349 value_.append(
string.
value_.begin() + 1,
string.value_.end());
355 value_ += UNTRANSLATABLE_PART;
378 value_ += UNTRANSLATABLE_PART;
401 value_ += UNTRANSLATABLE_PART;
443 for(
walker w(*
this); !
w.eos();
w.next()) {
446 if(
w.translatable()) {
500 LOG_CF <<
"Binding textdomain " << name <<
" to path " << path <<
"\n";
513 stream <<
string.str();
static unsigned language_counter
static void reset_translations()
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
std::string to_serialized() const
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
const std::string & str() const
void swap(t_string &other)
bool operator<(const t_string_base &string) const
t_string_base operator+(const t_string_base &) const
bool last_untranslatable_
std::string base_str() const
std::string dsgettext(const char *domainname, const char *msgid)
void bind_textdomain(const char *domain, const char *directory, const char *encoding)
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_
boost::shared_ptr< const t_string_base > val_
GLsizei const char ** path
static void add_textdomain(const std::string &name, const std::string &path)
GLubyte GLubyte GLubyte GLubyte w
walker(const t_string_base &string)
t_string & operator=(const t_string &)
Default implementation, but defined out-of-line for efficiency reasons.
size_t hash_value() const
static lg::log_domain log_config("config")
const route_iterator begin_
~t_string()
Default implementation, but defined out-of-line for efficiency reasons.
const std::string & value() const
GLuint const GLchar * name
Standard logging facilities (interface).
t_string_base & operator+=(const t_string_base &)
bool operator==(const t_string_base &) const
GLsizei const GLcharARB ** string
std::ostream & operator<<(std::ostream &stream, const t_string_base &string)
static t_string_base from_serialized(const std::string &string)