CppCMS

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

message.h
1 //
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOSTER_LOCALE_MESSAGE_H_INCLUDED
9 #define BOOSTER_LOCALE_MESSAGE_H_INCLUDED
10
11 #include <booster/config.h>
12 #ifdef BOOSTER_MSVC
13 # pragma warning(push)
14 # pragma warning(disable : 4275 4251 4231 4660)
15 #endif
16 #include <locale>
17 #include <string>
18 #include <vector>
19 #include <set>
20 #include <booster/auto_ptr_inc.h>
21 #include <booster/locale/formatting.h>
22
23
24 namespace booster {
25 namespace locale {
33
35
36 template<typename CharType>
37 struct base_message_format: public std::locale::facet
38 {
39 };
40
42
46 template<typename CharType>
47 class message_format : public base_message_format<CharType>
48 {
49 public:
50
54 typedef CharType char_type;
58 typedef std::basic_string<CharType> string_type;
59
63 message_format(size_t refs = 0) :
64 base_message_format<CharType>(refs)
65 {
66 }
67
78 virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const = 0;
92 virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const = 0;
93
97 virtual int domain(std::string const &domain) const = 0;
98
107 virtual char_type const *convert(char_type const *msg,string_type &buffer) const = 0;
108
109 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
110 std::locale::id& __get_id (void) const { return id; }
111 #endif
112 protected:
113 virtual ~message_format()
114 {
115 }
116
117 };
118
120
121 namespace details {
122 inline bool is_us_ascii_char(char c)
123 {
124 // works for null terminated strings regardless char "signness"
125 return 0<c && c<0x7F;
126 }
127 inline bool is_us_ascii_string(char const *msg)
128 {
129 while(*msg) {
130 if(!is_us_ascii_char(*msg++))
131 return false;
132 }
133 return true;
134 }
135
136 template<typename CharType>
137 struct string_cast_traits {
138 static CharType const *cast(CharType const *msg,std::basic_string<CharType> &/*unused*/)
139 {
140 return msg;
141 }
142 };
143
144 template<>
145 struct string_cast_traits<char> {
146 static char const *cast(char const *msg,std::string &buffer)
147 {
148 if(is_us_ascii_string(msg))
149 return msg;
150 buffer.reserve(strlen(msg));
151 char c;
152 while((c=*msg++)!=0) {
153 if(is_us_ascii_char(c))
154 buffer+=c;
155 }
156 return buffer.c_str();
157 }
158 };
159 } // details
160
162
170 template<typename CharType>
171 class basic_message {
172 public:
173
174 typedef CharType char_type;
175 typedef std::basic_string<char_type> string_type;
176 typedef message_format<char_type> facet_type;
177
181 basic_message() :
182 n_(0),
183 c_id_(0),
184 c_context_(0),
185 c_plural_(0)
186 {
187 }
188
193 explicit basic_message(char_type const *id) :
194 n_(0),
195 c_id_(id),
196 c_context_(0),
197 c_plural_(0)
198 {
199 }
200
207 explicit basic_message(char_type const *single,char_type const *plural,int n) :
208 n_(n),
209 c_id_(single),
210 c_context_(0),
211 c_plural_(plural)
212 {
213 }
214
220 explicit basic_message(char_type const *context,char_type const *id) :
221 n_(0),
222 c_id_(id),
223 c_context_(context),
224 c_plural_(0)
225 {
226 }
227
234 explicit basic_message(char_type const *context,char_type const *single,char_type const *plural,int n) :
235 n_(n),
236 c_id_(single),
237 c_context_(context),
238 c_plural_(plural)
239 {
240 }
241
242
246 explicit basic_message(string_type const &id) :
247 n_(0),
248 c_id_(0),
249 c_context_(0),
250 c_plural_(0),
251 id_(id)
252 {
253 }
254
260 explicit basic_message(string_type const &single,string_type const &plural,int number) :
261 n_(number),
262 c_id_(0),
263 c_context_(0),
264 c_plural_(0),
265 id_(single),
266 plural_(plural)
267 {
268 }
269
273 explicit basic_message(string_type const &context,string_type const &id) :
274 n_(0),
275 c_id_(0),
276 c_context_(0),
277 c_plural_(0),
278 id_(id),
279 context_(context)
280 {
281 }
282
288 explicit basic_message(string_type const &context,string_type const &single,string_type const &plural,int number) :
289 n_(number),
290 c_id_(0),
291 c_context_(0),
292 c_plural_(0),
293 id_(single),
294 context_(context),
295 plural_(plural)
296 {
297 }
298
302 basic_message(basic_message const &other) :
303 n_(other.n_),
304 c_id_(other.c_id_),
305 c_context_(other.c_context_),
306 c_plural_(other.c_plural_),
307 id_(other.id_),
308 context_(other.context_),
309 plural_(other.plural_)
310 {
311 }
312
316 basic_message const &operator=(basic_message const &other)
317 {
318 if(this==&other) {
319 return *this;
320 }
321 basic_message tmp(other);
322 swap(tmp);
323 return *this;
324 }
325
329 void swap(basic_message &other)
330 {
331 std::swap(n_,other.n_);
332 std::swap(c_id_,other.c_id_);
333 std::swap(c_context_,other.c_context_);
334 std::swap(c_plural_,other.c_plural_);
335
336 id_.swap(other.id_);
337 context_.swap(other.context_);
338 plural_.swap(other.plural_);
339 }
340
344
345 operator string_type () const
346 {
347 return str();
348 }
349
353 string_type str() const
354 {
355 std::locale loc;
356 return str(loc,0);
357 }
358
362 string_type str(std::locale const &locale) const
363 {
364 return str(locale,0);
365 }
366
370 string_type str(std::locale const &locale,std::string const &domain_id) const
371 {
372 int id=0;
373 if(std::has_facet<facet_type>(locale))
374 id=std::use_facet<facet_type>(locale).domain(domain_id);
375 return str(locale,id);
376 }
377
381 string_type str(std::string const &domain_id) const
382 {
383 int id=0;
384 std::locale loc;
385 if(std::has_facet<facet_type>(loc))
386 id=std::use_facet<facet_type>(loc).domain(domain_id);
387 return str(loc,id);
388 }
389
390
394 string_type str(std::locale const &loc,int id) const
395 {
396 string_type buffer;
397 char_type const *ptr = write(loc,id,buffer);
398 if(ptr == buffer.c_str())
399 return buffer;
400 else
401 buffer = ptr;
402 return buffer;
403 }
404
405
410 void write(std::basic_ostream<char_type> &out) const
411 {
412 std::locale const &loc = out.getloc();
413 int id = ios_info::get(out).domain_id();
414 string_type buffer;
415 out << write(loc,id,buffer);
416 }
417
418 private:
419 char_type const *plural() const
420 {
421 if(c_plural_)
422 return c_plural_;
423 if(plural_.empty())
424 return 0;
425 return plural_.c_str();
426 }
427 char_type const *context() const
428 {
429 if(c_context_)
430 return c_context_;
431 if(context_.empty())
432 return 0;
433 return context_.c_str();
434 }
435
436 char_type const *id() const
437 {
438 return c_id_ ? c_id_ : id_.c_str();
439 }
440
441 char_type const *write(std::locale const &loc,int domain_id,string_type &buffer) const
442 {
443 char_type const *translated = 0;
444 static const char_type empty_string[1] = {0};
445
446 char_type const *id = this->id();
447 char_type const *context = this->context();
448 char_type const *plural = this->plural();
449
450 if(*id == 0)
451 return empty_string;
452
453 facet_type const *facet = 0;
454 if(std::has_facet<facet_type>(loc))
455 facet = &std::use_facet<facet_type>(loc);
456
457 if(facet) {
458 if(!plural) {
459 translated = facet->get(domain_id,context,id);
460 }
461 else {
462 translated = facet->get(domain_id,context,id,n_);
463 }
464 }
465
466 if(!translated) {
467 char_type const *msg = plural ? ( n_ == 1 ? id : plural) : id;
468
469 if(facet) {
470 translated = facet->convert(msg,buffer);
471 }
472 else {
473 translated = details::string_cast_traits<char_type>::cast(msg,buffer);
474 }
475 }
476 return translated;
477 }
478
480
481 int n_;
482 char_type const *c_id_;
483 char_type const *c_context_;
484 char_type const *c_plural_;
485 string_type id_;
486 string_type context_;
487 string_type plural_;
488 };
489
490
494 typedef basic_message<char> message;
498 typedef basic_message<wchar_t> wmessage;
499 #ifdef BOOSTER_HAS_CHAR16_T
500 typedef basic_message<char16_t> u16message;
504 #endif
505 #ifdef BOOSTER_HAS_CHAR32_T
506 typedef basic_message<char32_t> u32message;
510 #endif
511
515 template<typename CharType>
516 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_message<CharType> const &msg)
517 {
518 msg.write(out);
519 return out;
520 }
521
525
529 template<typename CharType>
530 inline basic_message<CharType> translate(CharType const *msg)
531 {
532 return basic_message<CharType>(msg);
533 }
537 template<typename CharType>
538 inline basic_message<CharType> translate( CharType const *context,
539 CharType const *msg)
540 {
541 return basic_message<CharType>(context,msg);
542 }
546 template<typename CharType>
547 inline basic_message<CharType> translate( CharType const *single,
548 CharType const *plural,
549 int n)
550 {
551 return basic_message<CharType>(single,plural,n);
552 }
556 template<typename CharType>
557 inline basic_message<CharType> translate( CharType const *context,
558 CharType const *single,
559 CharType const *plural,
560 int n)
561 {
562 return basic_message<CharType>(context,single,plural,n);
563 }
564
568 template<typename CharType>
569 inline basic_message<CharType> translate(std::basic_string<CharType> const &msg)
570 {
571 return basic_message<CharType>(msg);
572 }
573
577 template<typename CharType>
578 inline basic_message<CharType> translate( std::basic_string<CharType> const &context,
579 std::basic_string<CharType> const &msg)
580 {
581 return basic_message<CharType>(context,msg);
582 }
586 template<typename CharType>
587 inline basic_message<CharType> translate( std::basic_string<CharType> const &context,
588 std::basic_string<CharType> const &single,
589 std::basic_string<CharType> const &plural,
590 int n)
591 {
592 return basic_message<CharType>(context,single,plural,n);
593 }
594
598
599 template<typename CharType>
600 inline basic_message<CharType> translate( std::basic_string<CharType> const &single,
601 std::basic_string<CharType> const &plural,
602 int n)
603 {
604 return basic_message<CharType>(single,plural,n);
605 }
606
608
612
616 template<typename CharType>
617 std::basic_string<CharType> gettext(CharType const *id,
618 std::locale const &loc=std::locale())
619 {
620 return basic_message<CharType>(id).str(loc);
621 }
625 template<typename CharType>
626 std::basic_string<CharType> ngettext( CharType const *s,
627 CharType const *p,
628 int n,
629 std::locale const &loc=std::locale())
630 {
631 return basic_message<CharType>(s,p,n).str(loc);
632 }
636 template<typename CharType>
637 std::basic_string<CharType> dgettext( char const *domain,
638 CharType const *id,
639 std::locale const &loc=std::locale())
640 {
641 return basic_message<CharType>(id).str(loc,domain);
642 }
643
647 template<typename CharType>
648 std::basic_string<CharType> dngettext( char const *domain,
649 CharType const *s,
650 CharType const *p,
651 int n,
652 std::locale const &loc=std::locale())
653 {
654 return basic_message<CharType>(s,p,n).str(loc,domain);
655 }
659 template<typename CharType>
660 std::basic_string<CharType> pgettext( CharType const *context,
661 CharType const *id,
662 std::locale const &loc=std::locale())
663 {
664 return basic_message<CharType>(context,id).str(loc);
665 }
669 template<typename CharType>
670 std::basic_string<CharType> npgettext( CharType const *context,
671 CharType const *s,
672 CharType const *p,
673 int n,
674 std::locale const &loc=std::locale())
675 {
676 return basic_message<CharType>(context,s,p,n).str(loc);
677 }
681 template<typename CharType>
682 std::basic_string<CharType> dpgettext( char const *domain,
683 CharType const *context,
684 CharType const *id,
685 std::locale const &loc=std::locale())
686 {
687 return basic_message<CharType>(context,id).str(loc,domain);
688 }
692 template<typename CharType>
693 std::basic_string<CharType> dnpgettext(char const *domain,
694 CharType const *context,
695 CharType const *s,
696 CharType const *p,
697 int n,
698 std::locale const &loc=std::locale())
699 {
700 return basic_message<CharType>(context,s,p,n).str(loc,domain);
701 }
702
706
707 template<>
708 struct BOOSTER_API base_message_format<char> : public std::locale::facet
709 {
710 base_message_format(size_t refs = 0) : std::locale::facet(refs)
711 {
712 }
713 static std::locale::id id;
714 };
715
716 template<>
717 struct BOOSTER_API base_message_format<wchar_t> : public std::locale::facet
718 {
719 base_message_format(size_t refs = 0) : std::locale::facet(refs)
720 {
721 }
722 static std::locale::id id;
723 };
724
725 #ifdef BOOSTER_HAS_CHAR16_T
726
727 template<>
728 struct BOOSTER_API base_message_format<char16_t> : public std::locale::facet
729 {
730 base_message_format(size_t refs = 0) : std::locale::facet(refs)
731 {
732 }
733 static std::locale::id id;
734 };
735
736 #endif
737
738 #ifdef BOOSTER_HAS_CHAR32_T
739
740 template<>
741 struct BOOSTER_API base_message_format<char32_t> : public std::locale::facet
742 {
743 base_message_format(size_t refs = 0) : std::locale::facet(refs)
744 {
745 }
746 static std::locale::id id;
747 };
748
749 #endif
750
752
756
757 namespace as {
759 namespace details {
760 struct set_domain {
761 std::string domain_id;
762 };
763 template<typename CharType>
764 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out, set_domain const &dom)
765 {
766 int id = std::use_facet<message_format<CharType> >(out.getloc()).domain(dom.domain_id);
767 ios_info::get(out).domain_id(id);
768 return out;
769 }
770 } // details
772
777
783 inline
784 #ifdef BOOSTER_LOCALE_DOXYGEN
785 unspecified_type
786 #else
787 details::set_domain
788 #endif
789 domain(std::string const &id)
790 {
791 details::set_domain tmp = { id };
792 return tmp;
793 }
795 } // as
796 } // locale
797 } // boost
798
799 #ifdef BOOSTER_MSVC
800 #pragma warning(pop)
801 #endif
802
803
804 #endif
805
806 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
807
booster::locale::basic_message::swap
void swap(basic_message &other)
Definition: message.h:329
booster::locale::basic_message::basic_message
basic_message(basic_message const &other)
Definition: message.h:302
booster::locale::ios_info::domain_id
void domain_id(int)
booster::locale::dgettext
std::basic_string< CharType > dgettext(char const *domain, CharType const *id, std::locale const &loc=std::locale())
Definition: message.h:637
booster::locale::message_format::message_format
message_format(size_t refs=0)
Definition: message.h:63
booster::locale::basic_message::str
string_type str(std::string const &domain_id) const
Definition: message.h:381
booster::locale::basic_message::basic_message
basic_message()
Definition: message.h:181
booster::locale::basic_message::char_type
CharType char_type
The character this message object is used with.
Definition: message.h:174
booster::locale::basic_message::basic_message
basic_message(string_type const &context, string_type const &single, string_type const &plural, int number)
Definition: message.h:288
booster::locale::as::domain
details::set_domain domain(std::string const &id)
Definition: message.h:789
booster::locale::message_format
This facet provides message formatting abilities.
Definition: message.h:47
booster::locale::dpgettext
std::basic_string< CharType > dpgettext(char const *domain, CharType const *context, CharType const *id, std::locale const &loc=std::locale())
Definition: message.h:682
booster::locale::pgettext
std::basic_string< CharType > pgettext(CharType const *context, CharType const *id, std::locale const &loc=std::locale())
Definition: message.h:660
booster::locale::basic_message::facet_type
message_format< char_type > facet_type
The type of the facet the messages are fetched with.
Definition: message.h:176
booster::locale::message_format::char_type
CharType char_type
Definition: message.h:54
booster::locale::translate
basic_message< CharType > translate(CharType const *msg)
Translate a message, msg is not copied.
Definition: message.h:530
booster::locale::basic_message::write
void write(std::basic_ostream< char_type > &out) const
Definition: message.h:410
booster::locale::ios_info::get
static ios_info & get(std::ios_base &ios)
booster::locale::gettext
std::basic_string< CharType > gettext(CharType const *id, std::locale const &loc=std::locale())
Definition: message.h:617
booster::locale::basic_message::str
string_type str(std::locale const &locale, std::string const &domain_id) const
Definition: message.h:370
booster::locale::dngettext
std::basic_string< CharType > dngettext(char const *domain, CharType const *s, CharType const *p, int n, std::locale const &loc=std::locale())
Definition: message.h:648
booster::locale::basic_message::str
string_type str(std::locale const &loc, int id) const
Definition: message.h:394
booster::locale::ngettext
std::basic_string< CharType > ngettext(CharType const *s, CharType const *p, int n, std::locale const &loc=std::locale())
Definition: message.h:626
booster::locale::message_format::get
virtual char_type const * get(int domain_id, char_type const *context, char_type const *id) const =0
booster::locale::basic_message::str
string_type str(std::locale const &locale) const
Definition: message.h:362
booster::locale
This is the main namespace that encloses all localization classes.
Definition: locale_fwd.h:14
booster::locale::basic_message::basic_message
basic_message(char_type const *context, char_type const *single, char_type const *plural, int n)
Definition: message.h:234
booster::locale::message_format::convert
virtual char_type const * convert(char_type const *msg, string_type &buffer) const =0
booster::locale::basic_message::operator=
basic_message const & operator=(basic_message const &other)
Definition: message.h:316
booster::locale::basic_message::basic_message
basic_message(string_type const &single, string_type const &plural, int number)
Definition: message.h:260
booster::locale::basic_message::basic_message
basic_message(char_type const *id)
Definition: message.h:193
booster::locale::wmessage
basic_message< wchar_t > wmessage
Definition: message.h:498
booster::locale::dnpgettext
std::basic_string< CharType > dnpgettext(char const *domain, CharType const *context, CharType const *s, CharType const *p, int n, std::locale const &loc=std::locale())
Definition: message.h:693
booster::locale::message
basic_message< char > message
Definition: message.h:494
booster::locale::as::number
std::ios_base & number(std::ios_base &ios)
Definition: formatting.h:292
booster::locale::basic_message::basic_message
basic_message(string_type const &id)
Definition: message.h:246
booster::locale::basic_message
This class represents a message that can be converted to a specific locale message.
Definition: message.h:171
booster::locale::basic_message::basic_message
basic_message(char_type const *context, char_type const *id)
Definition: message.h:220
booster::locale::basic_message::basic_message
basic_message(string_type const &context, string_type const &id)
Definition: message.h:273
booster::locale::basic_message::string_type
std::basic_string< char_type > string_type
The string type this object can be used with.
Definition: message.h:175
booster::locale::message_format::string_type
std::basic_string< CharType > string_type
Definition: message.h:58
booster
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
booster::locale::npgettext
std::basic_string< CharType > npgettext(CharType const *context, CharType const *s, CharType const *p, int n, std::locale const &loc=std::locale())
Definition: message.h:670
booster::locale::basic_message::str
string_type str() const
Definition: message.h:353
booster::locale::basic_message::basic_message
basic_message(char_type const *single, char_type const *plural, int n)
Definition: message.h:207