00001
00002
00003
00004
00005
00006
00007
00008 #ifndef BOOST_LOCALE_MESSAGE_HPP_INCLUDED
00009 #define BOOST_LOCALE_MESSAGE_HPP_INCLUDED
00010
00011 #include <boost/locale/config.hpp>
00012 #ifdef BOOST_MSVC
00013 # pragma warning(push)
00014 # pragma warning(disable : 4275 4251 4231 4660)
00015 #endif
00016 #include <locale>
00017 #include <string>
00018 #include <vector>
00019 #include <set>
00020 #include <memory>
00021 #include <boost/locale/formatting.hpp>
00022
00023
00024
00025 namespace boost {
00026 namespace locale {
00034
00035 class info;
00036
00040 template<typename CharType>
00041 struct base_message_format: public std::locale::facet
00042 {
00043 };
00044
00045
00046 template<typename CharType>
00047 class message_format : public base_message_format<CharType>
00048 {
00049 public:
00050
00051 typedef CharType char_type;
00052 typedef std::basic_string<CharType> string_type;
00053
00054 message_format(size_t refs = 0) :
00055 base_message_format<CharType>(refs)
00056 {
00057 }
00058
00059 virtual char_type const *get(int domain_id,char const *id) const = 0;
00060 virtual char_type const *get(int domain_id,char const *single_id,int n) const = 0;
00061 virtual int domain(std::string const &domain) const = 0;
00062
00063 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
00064 std::locale::id& __get_id (void) const { return id; }
00065 #endif
00066 static message_format<CharType> *create(info const &,std::vector<std::string> const &paths,std::vector<std::string> const &domains);
00067
00068 protected:
00069 virtual ~message_format()
00070 {
00071 }
00072
00073 };
00074
00076
00084 struct message {
00085 public:
00086
00090 message() :
00091 n_(0),
00092 c_id_(""),
00093 c_plural_(0)
00094 {
00095 }
00096
00101 explicit message(char const *id) :
00102 n_(0),
00103 c_id_(id),
00104 c_plural_(0)
00105 {
00106 }
00107
00114 explicit message(char const *single,char const *plural,int n) :
00115 n_(n),
00116 c_id_(single),
00117 c_plural_(plural)
00118 {
00119 }
00120
00124 explicit message(std::string const &id) :
00125 n_(0),
00126 c_id_(0),
00127 c_plural_(0),
00128 id_(id)
00129 {
00130 }
00131
00137 explicit message(std::string const &single,std::string const &plural,int number) :
00138 n_(number),
00139 c_id_(0),
00140 c_plural_(0),
00141 id_(single),
00142 plural_(plural)
00143 {
00144 }
00145
00149
00150 template<typename CharType>
00151 operator std::basic_string<CharType> () const
00152 {
00153 return str<CharType>();
00154 }
00155
00159 template<typename CharType>
00160 std::basic_string<CharType> str() const
00161 {
00162 std::locale loc;
00163 return str<CharType>(loc,0);
00164 }
00165
00169 template<typename CharType>
00170 std::basic_string<CharType> str(std::locale const &locale) const
00171 {
00172 return str<CharType>(locale,0);
00173 }
00174
00178 template<typename CharType>
00179 std::basic_string<CharType> str(std::locale const &locale,std::string domain_id) const
00180 {
00181 int id=0;
00182 if(std::has_facet<message_format<CharType> >(locale))
00183 id=std::use_facet<message_format<CharType> >(locale).domain(domain_id);
00184 return str<CharType>(locale,id);
00185 }
00186
00190 template<typename CharType>
00191 std::basic_string<CharType> str(std::string domain_id) const
00192 {
00193 int id=0;
00194 std::locale locale;
00195 if(std::has_facet<message_format<CharType> >(locale))
00196 id=std::use_facet<message_format<CharType> >(locale).domain(domain_id);
00197 return str<CharType>(locale,id);
00198 }
00199
00200
00204 template<typename CharType>
00205 std::basic_string<CharType> str(std::locale const &loc,int id) const
00206 {
00207 std::basic_string<CharType> buffer;
00208 CharType const *ptr = write(loc,id,buffer);
00209 if(ptr == buffer.c_str())
00210 return buffer;
00211 else
00212 buffer = ptr;
00213 return buffer;
00214 }
00215
00216
00221 template<typename CharType>
00222 void write(std::basic_ostream<CharType> &out) const
00223 {
00224 std::locale const &loc = out.getloc();
00225 int id = ext_value(out,flags::domain_id);
00226 std::basic_string<CharType> buffer;
00227 out << write(loc,id,buffer);
00228 }
00229
00230 private:
00231
00232 template<typename CharType>
00233 CharType const *write(std::locale const &loc,int domain_id,std::basic_string<CharType> &buffer) const
00234 {
00235 CharType const *translated = 0;
00236 static const CharType empty_string[1] = {0};
00237
00238 char const *id = c_id_ ? c_id_ : id_.c_str();
00239 char const *plural = c_plural_ ? c_plural_ : (plural_.empty() ? 0 : plural_.c_str());
00240
00241 if(*id == 0)
00242 return empty_string;
00243
00244 if(std::has_facet<message_format<CharType> >(loc)) {
00245 message_format<CharType> const &msg = std::use_facet<message_format<CharType> >(loc);
00246
00247 if(!plural) {
00248 translated = msg.get(domain_id,id);
00249 }
00250 else {
00251 translated = msg.get(domain_id,id,n_);
00252 }
00253 }
00254
00255 if(!translated) {
00256 char const *msg = plural ? ( n_ == 1 ? cut_comment(id) : plural) : cut_comment(id);
00257
00258 while(*msg)
00259 buffer+=static_cast<CharType>(*msg++);
00260
00261 translated = buffer.c_str();
00262 }
00263 return translated;
00264 }
00265
00266 char const *cut_comment(char const *id) const
00267 {
00268 static const char key = '#';
00269 if(*id == key) {
00270 if(id[1] == key)
00271 return id+1;
00272 char c;
00273 id++;
00274 while((c=*id)!=0 && c!=key)
00275 id++;
00276 if(*id==key)
00277 id++;
00278 }
00279 return id;
00280 }
00281
00283
00284 int n_;
00285 char const *c_id_;
00286 char const *c_plural_;
00287 std::string id_;
00288 std::string plural_;
00289 };
00290
00294 template<typename CharType>
00295 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,message const &msg)
00296 {
00297 msg.write(out);
00298 return out;
00299 }
00300
00301
00305 inline message translate(char const *msg)
00306 {
00307 return message(msg);
00308 }
00312 inline message translate(char const *single,char const *plural,int n)
00313 {
00314 return message(single,plural,n);
00315 }
00316
00320 inline message translate(std::string const &msg)
00321 {
00322 return message(msg);
00323 }
00327 inline message translate(std::string const &single,std::string const &plural,int n)
00328 {
00329 return message(single,plural,n);
00330 }
00331
00335
00336 template<>
00337 struct BOOST_LOCALE_DECL base_message_format<char> : public std::locale::facet
00338 {
00339 base_message_format(size_t refs = 0) : std::locale::facet(refs)
00340 {
00341 }
00342 static std::locale::id id;
00343 };
00344
00345 template<>
00346 BOOST_LOCALE_DECL message_format<char> *message_format<char>::create( info const &,
00347 std::vector<std::string> const &domains,
00348 std::vector<std::string> const &paths);
00349 #ifndef BOOST_NO_STD_WSTRING
00350
00351 template<>
00352 struct BOOST_LOCALE_DECL base_message_format<wchar_t> : public std::locale::facet
00353 {
00354 base_message_format(size_t refs = 0) : std::locale::facet(refs)
00355 {
00356 }
00357 static std::locale::id id;
00358 };
00359 template<>
00360 BOOST_LOCALE_DECL message_format<wchar_t> *message_format<wchar_t>::create( info const &,
00361 std::vector<std::string> const &domains,
00362 std::vector<std::string> const &paths);
00363
00364 #endif
00365
00366 #ifdef BOOST_HAS_CHAR16_T
00367
00368 template<>
00369 struct BOOST_LOCALE_DECL base_message_format<char16_t> : public std::locale::facet
00370 {
00371 base_message_format(size_t refs = 0) : std::locale::facet(refs)
00372 {
00373 }
00374 static std::locale::id id;
00375 };
00376 template<>
00377 BOOST_LOCALE_DECL message_format<char16_t> *message_format<char16_t>::create( info const &,
00378 std::vector<std::string> const &domains,
00379 std::vector<std::string> const &paths);
00380
00381 #endif
00382
00383 #ifdef BOOST_HAS_CHAR32_T
00384
00385 template<>
00386 struct BOOST_LOCALE_DECL base_message_format<char32_t> : public std::locale::facet
00387 {
00388 base_message_format(size_t refs = 0) : std::locale::facet(refs)
00389 {
00390 }
00391 static std::locale::id id;
00392 };
00393
00394 template<>
00395 BOOST_LOCALE_DECL message_format<char32_t> *message_format<char32_t>::create( info const &,
00396 std::vector<std::string> const &domains,
00397 std::vector<std::string> const &paths);
00398
00399 #endif
00400
00402
00406
00407 namespace as {
00409 namespace details {
00410 struct set_domain {
00411 std::string domain_id;
00412 };
00413 template<typename CharType>
00414 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out, set_domain const &dom)
00415 {
00416 int id = std::use_facet<message_format<CharType> >(out.getloc()).domain(dom.domain_id);
00417 ext_value(out,flags::domain_id,id);
00418 return out;
00419 }
00420 }
00422
00427
00431 inline details::set_domain domain(std::string const &id)
00432 {
00433 details::set_domain tmp;
00434 tmp.domain_id = id;
00435 return tmp;
00436 }
00438 }
00439 }
00440 }
00441
00442 #ifdef BOOST_MSVC
00443 #pragma warning(pop)
00444 #endif
00445
00446
00447 #endif
00448
00449
00450