From 9c8df7ba4674d78fa08d441abbbf3a3ee4cbf534 Mon Sep 17 00:00:00 2001 From: Artyom Beilis Date: Wed, 11 Nov 2009 13:02:52 +0000 Subject: [PATCH] Now external locale library is used --- CMakeLists.txt | 34 ++- application.cpp | 16 -- application.h | 5 - base_view.cpp | 4 - config.js | 17 +- filters.cpp | 147 ++----------- filters.h | 371 +------------------------------- form.cpp | 12 +- form.h | 3 +- hello_world.cpp | 73 ++----- http_context.cpp | 7 +- http_context.h | 5 +- http_response.cpp | 7 +- locale.h | 13 -- locale_charset.cpp | 144 ------------- locale_charset.h | 143 ------------- locale_collate.cpp | 144 ------------- locale_collate.h | 62 ------ locale_convert.cpp | 221 ------------------- locale_convert.h | 89 -------- locale_environment.cpp | 88 -------- locale_environment.h | 40 ---- locale_gettext.cpp | 561 ------------------------------------------------- locale_gettext.h | 57 ----- locale_icu_locale.cpp | 24 --- locale_icu_locale.h | 33 --- locale_info.cpp | 43 ---- locale_info.h | 40 ---- locale_mo_file.cpp | 342 ------------------------------ locale_mo_file.h | 30 --- locale_numeric.cpp | 287 ------------------------- locale_numeric.h | 67 ------ locale_pool.cpp | 95 --------- locale_pool.h | 32 --- localization.h | 13 ++ service.cpp | 61 +++++- service.h | 12 +- service_impl.h | 4 +- utf8_iterator.cpp | 446 --------------------------------------- utf8_iterator.h | 432 ------------------------------------- 40 files changed, 163 insertions(+), 4061 deletions(-) delete mode 100644 locale.h delete mode 100644 locale_charset.cpp delete mode 100644 locale_charset.h delete mode 100644 locale_collate.cpp delete mode 100644 locale_collate.h delete mode 100644 locale_convert.cpp delete mode 100644 locale_convert.h delete mode 100644 locale_environment.cpp delete mode 100644 locale_environment.h delete mode 100644 locale_gettext.cpp delete mode 100644 locale_gettext.h delete mode 100644 locale_icu_locale.cpp delete mode 100644 locale_icu_locale.h delete mode 100644 locale_info.cpp delete mode 100644 locale_info.h delete mode 100644 locale_mo_file.cpp delete mode 100644 locale_mo_file.h delete mode 100644 locale_numeric.cpp delete mode 100644 locale_numeric.h delete mode 100644 locale_pool.cpp delete mode 100644 locale_pool.h create mode 100644 localization.h delete mode 100644 utf8_iterator.cpp delete mode 100644 utf8_iterator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 92e6c73..098a67b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,15 +28,25 @@ endif(NOT ICU_UC OR NOT ICU_DATA OR NOT ICU_I18N) set(HAVE_ICU 1) -find_library(ICONV_LIB iconv) + +check_cxx_source_compiles( + "#include + int main() { iconv_t v=iconv_open((char *)0,(char *)); " + HAVE_ICONV) +if(NOT HAVE_ICONV) + find_library(ICONV_LIB iconv) + if(NOT ICONV_LIB) + message(FATAL " Can't find iconv") + endif(NOT ICONV_LIB) +endif(NOT HAVE_ICONV) include_directories(${CMAKE_BINARY_DIR}) include_directories(boost_locale) -include_directories(${Boost_INCLUDE_DIRS}) + -Check_type_size(wchar_t SIZEOF_WCHAR_T) +check_type_size(wchar_t SIZEOF_WCHAR_T) check_cxx_source_compiles( "int main() { volatile long v;__sync_add_and_fetch(&v,1); }" @@ -113,12 +123,7 @@ set(CPPCMS_SOURCES url_dispatcher.cpp http_cookie.cpp util.cpp - locale_mo_file.cpp - locale_gettext.cpp - locale_environment.cpp - locale_pool.cpp base64.cpp - locale_info.cpp base_view.cpp internal_file_server.cpp scgi_api.cpp @@ -128,15 +133,8 @@ set(CPPCMS_SOURCES aio_timer.cpp json.cpp encoding.cpp - locale_charset.cpp - locale_icu_locale.cpp - locale_convert.cpp - locale_numeric.cpp - locale_collate.cpp - icu_util.cpp form.cpp - filters.cpp - utf8_iterator.cpp) + filters.cpp) add_definitions(-DDLL_EXPORT) @@ -160,8 +158,8 @@ if(ICONV_LIB) endif(ICONV_LIB) if(WS2_32 AND WSOCK32) - target_link_libraries(cppcms ws2_32) - target_link_libraries(cppcms wsock32) + target_link_libraries(cppcms ${WS2_32}) + target_link_libraries(cppcms ${WSOCK32}) endif(WS2_32 AND WSOCK32) if(LIB_GETHOSTBYNAME) diff --git a/application.cpp b/application.cpp index 5233004..576b76c 100644 --- a/application.cpp +++ b/application.cpp @@ -5,8 +5,6 @@ #include "service.h" #include "cppcms_error.h" #include "url_dispatcher.h" -#include "locale_environment.h" -#include "locale_gettext.h" #include "intrusive_ptr.h" #include "applications_pool.h" #include "http_response.h" @@ -100,20 +98,6 @@ intrusive_ptr application::release_context() } -cppcms::locale::environment &application::locale() -{ - return context().locale(); -} - -char const *application::gt(char const *s) -{ - return locale().gt(s); -} - -char const *application::ngt(char const *s,char const *p,int n) -{ - return locale().ngt(s,p,n); -} bool application::is_asynchronous() { return pool_id() < 0; diff --git a/application.h b/application.h index 878352d..d30b0d1 100644 --- a/application.h +++ b/application.h @@ -41,11 +41,6 @@ namespace cppcms { http::request &request(); http::response &response(); url_dispatcher &dispatcher(); - locale::environment &locale(); - - char const *gt(char const *s); - char const *ngt(char const *s,char const *p,int n); - void add(application &app); void add(application &app,std::string regex,int part); diff --git a/base_view.cpp b/base_view.cpp index 3c5e656..a71193f 100644 --- a/base_view.cpp +++ b/base_view.cpp @@ -1,9 +1,6 @@ #define CPPCMS_SOURCE #include "base_view.h" #include "util.h" -#include "locale_gettext.h" -#include "locale_environment.h" -#include "locale_convert.h" #include "cppcms_error.h" #include @@ -13,7 +10,6 @@ namespace cppcms { struct base_view::data { std::ostream *out; - locale::gettext::tr const *tr; }; base_view::base_view(std::ostream &out) : diff --git a/config.js b/config.js index ce96e38..cb5c2d2 100644 --- a/config.js +++ b/config.js @@ -29,23 +29,14 @@ // "level" : 1, // "buffer" : 4096 }, - "l10n" : { - "defaults" : { - "encoding" : "UTF-8", - "locale" : "en_US", - "std_locale" : [ "ICU" , "C" ] - }, + "localization" : { + "encoding" : "UTF-8", "messages" : { - "paths" : [ "./transtext/locale" ], + "paths" : [ "../transtext/locale" ], "domains" : [ "app", "test" ], "default_domain" : ["test"] }, - "locales" : [ - "he_IL", - "he_IL@calendar=hebrew", - "en_US", - { "locale" : "ru_RU" , "std_locale" : "C" } - ] + "locales" : [ "en_US", "he_IL", "he_IL@calendar=hebrew" ] }, "locale" : { "locales" : diff --git a/filters.cpp b/filters.cpp index b269533..9c0145f 100644 --- a/filters.cpp +++ b/filters.cpp @@ -1,7 +1,6 @@ #define CPPCMS_SOURCE #include "filters.h" #include "base64.h" -#include "locale_convert.h" #include "util.h" #include @@ -79,7 +78,9 @@ namespace cppcms { namespace filters { to_upper const &to_upper::operator=(to_upper const &other){ obj_ = other.obj_; return *this; } void to_upper::operator()(std::ostream &out) const { - out << std::use_facet(out.getloc()).to_upper(obj_.get(out)); + std::string tmp =obj_.get(out) ; + std::locale loc = out.getloc(); + out << ::cppcms::locale::to_upper( tmp,loc); } struct to_lower::data {}; @@ -90,7 +91,7 @@ namespace cppcms { namespace filters { to_lower const &to_lower::operator=(to_lower const &other){ obj_ = other.obj_; return *this; } void to_lower::operator()(std::ostream &out) const { - out << std::use_facet(out.getloc()).to_lower(obj_.get(out)); + out << locale::to_lower(obj_.get(out),out.getloc()); } struct to_title::data {}; @@ -101,7 +102,7 @@ namespace cppcms { namespace filters { to_title const &to_title::operator=(to_title const &other){ obj_ = other.obj_; return *this; } void to_title::operator()(std::ostream &out) const { - out << std::use_facet(out.getloc()).to_title(obj_.get(out)); + out << locale::to_title(obj_.get(out),out.getloc()); } struct escape::data {}; @@ -156,151 +157,43 @@ namespace cppcms { namespace filters { os< >(out.getloc()).put(out,out,' ',t_,fmt.data(),fmt.data()+fmt.size()); - } - - - void format::init(streamable const &f) - { - format_=f; - size_ = 0; - } - streamable const *format::at(size_t n) const - { - n--; - if(n >= size_ || n < 0) - return 0; - - const size_t objects_size = sizeof(objects_) / sizeof(objects_[0]); - - if(n < objects_size) - return &objects_[n]; - return &vobjects_[n - objects_size]; - } - format &format::add(streamable const &obj) - { - if(size_ >= sizeof(objects_) / sizeof(objects_[0])) - vobjects_.push_back(obj); - else - objects_[size_] = obj; - size_ ++; - return *this; - } - void format::write(std::ostream &output) const - { - int pos = 0; - std::string const fmt=format_.get(output); - for(std::string::const_iterator p=fmt.begin(),e=fmt.end();p!=e;) { - char c=*p++; - if(c=='%') { - format_one(output,p,e,pos); - } - else - output.put(c); - } - } - - void format::format_one(std::ostream &out,std::string::const_iterator &p,std::string::const_iterator e,int &pos) const - { - if(p==e) - return; - if(*p == '%') { - ++p; - out << '%'; - return; - } - pos++; - int the_pos = pos; - - if('1' <= *p && *p<='9') { - int n=0; - while(p!=e && '0' <= *p && *p<='9') { - n=n*10 + (*p - '0'); - ++p; - } - if(p==e) - return; - if(*p=='%') { - ++p; - the_pos = n; - streamable const *obj=at(the_pos); - if(obj) { - out<<*obj; - } - return; - } - return; - } - } - - std::string format::str(std::locale const &loc) const - { - std::ostringstream oss; - oss.imbue(loc); - write(oss); - return oss.str(); - } - struct date::data {}; struct time::data {}; struct datetime::data {}; - date::date() : t_(0) {} - datetime::datetime() : t_(0){} - time::time() : t_(0) {} + date::date() : time_(0) {} + datetime::datetime() : time_(0){} + time::time() : time_(0) {} date::~date() {} datetime::~datetime() {} time::~time() {} - date::date(date const &other) : t_(other.t_) {} - time::time(time const &other) : t_(other.t_) {} - datetime::datetime(datetime const &other) : t_(other.t_) {} + date::date(date const &other) : time_(other.time_) {} + time::time(time const &other) : time_(other.time_) {} + datetime::datetime(datetime const &other) : time_(other.time_) {} - date const &date::operator=(date const &other) { t_=other.t_; return *this; } - time const &time::operator=(time const &other) { t_=other.t_; return *this; } - datetime const &datetime::operator=(datetime const &other) { t_=other.t_; return *this; } + date const &date::operator=(date const &other) { time_=other.time_; return *this; } + time const &time::operator=(time const &other) { time_=other.time_; return *this; } + datetime const &datetime::operator=(datetime const &other) { time_=other.time_; return *this; } - date::date(std::tm const &t) : t_(&t) {} - time::time(std::tm const &t) : t_(&t) {} - datetime::datetime(std::tm const &t) : t_(&t) {} + date::date(double t) : time_(t) {} + time::time(double t) : time_(t) {} + datetime::datetime(double t) : time_(t) {} void date::operator()(std::ostream &out) const { - if(out.getloc().name()=="*") - out< #include "defs.h" #include "copy_ptr.h" +#include "localization.h" -#include "locale_gettext.h" namespace cppcms { namespace filters { @@ -287,35 +287,7 @@ namespace cppcms { return out; } - /// - /// \brief Output filter strftime - /// - /// Format time according to locale using time_put facet. (has similar - /// parameters to C strftime - /// - - class CPPCMS_API strftime { - public: - strftime(); - ~strftime(); - strftime(strftime const &); - strftime const &operator=(strftime const &other); - void operator()(std::ostream &out) const; - strftime(streamable const &obj,std::tm const &t); - - private: - streamable format_; - std::tm const *t_; - struct data; - util::copy_ptr d; - }; - inline std::ostream &operator<<(std::ostream &out,strftime const &obj) - { - obj(out); - return out; - } - class CPPCMS_API date { public: @@ -324,11 +296,11 @@ namespace cppcms { date const &operator=(date const &other); ~date(); - date(std::tm const &t); + date(double time); void operator()(std::ostream &out) const; private: struct data; - std::tm const *t_; + double time_; util::copy_ptr d; }; @@ -345,11 +317,11 @@ namespace cppcms { time const &operator=(time const &other); ~time(); - time(std::tm const &t); + time(double time); void operator()(std::ostream &out) const; private: struct data; - std::tm const *t_; + double time_; util::copy_ptr d; }; @@ -365,11 +337,11 @@ namespace cppcms { datetime const &operator=(datetime const &other); ~datetime(); - datetime(std::tm const &t); + datetime(double t); void operator()(std::ostream &out) const; private: struct data; - std::tm const *t_; + double time_; util::copy_ptr d; }; @@ -378,339 +350,14 @@ namespace cppcms { obj(out); return out; } - - class gt { - public: - gt(char const *msg) : - domain_(0), - msg_(msg) - { - } - gt(char const *domain,char const *msg) : - domain_(domain), - msg_(msg) - { - } - void operator()(std::ostream &out) const - { - locale::gettext const &trans = std::use_facet(out.getloc()); - if(domain_) - out << trans.dictionary(domain_).gettext(msg_); - else - out << trans.dictionary().gettext(msg_); - } - private: - char const *domain_; - char const *msg_; - }; - - CPPCMS_STREAMED(gt) - - class ngt { - public: - ngt(char const *s,char const *p,int n) : - domain_(0), - s_(s), - p_(p), - n_(n) - { - } - ngt(char const *domain,char const *s,char const *p,int n) : - domain_(domain), - s_(s), - p_(p), - n_(n) - { - } - void operator()(std::ostream &out) const - { - locale::gettext const &trans = std::use_facet(out.getloc()); - if(domain_) - out << trans.dictionary(domain_).ngettext(s_,p_,n_); - else - out << trans.dictionary().ngettext(s_,p_,n_); - } - private: - char const *domain_; - char const *s_,*p_; - int n_; - }; - - CPPCMS_STREAMED(ngt) - - class CPPCMS_API format { - public: - format(streamable const &f) - { - init(f); - } -#ifdef CPPCMS_HAVE_VARIADIC_TEMPLATES - template - format(streamable const &f,Args... args) - { - init(f); - add_args(args...); - } - private: - void add_args() - { - } - template - void add_args(T const &v,Args... args) - { - add(v); - add_args(args...); - } - public: -#else - template - format( streamable const &f, - T1 const &v1) - { - init(f); - add(v1); - } - template< typename T1, - typename T2> - format( streamable const &f, - T1 const &v1, - T2 const &v2) - { - init(f); - add(v1); - add(v2); - } - template< typename T1, - typename T2, - typename T3> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3) - { - init(f); - add(v1); - add(v2); - add(v3); - } - template< typename T1, - typename T2, - typename T3, - typename T4> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - add(v5); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5, - T6 const &v6) - { - init(f); - add(v1); - add(v2); - add(v4); - add(v5); - add(v6); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5, - T6 const &v6, - T7 const &v7) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - add(v5); - add(v6); - add(v7); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5, - T6 const &v6, - T7 const &v7, - T8 const &v8) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - add(v5); - add(v6); - add(v7); - add(v8); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5, - T6 const &v6, - T7 const &v7, - T8 const &v8, - T9 const &v9) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - add(v5); - add(v6); - add(v7); - add(v8); - add(v9); - } - template< typename T1, - typename T2, - typename T3, - typename T4, - typename T5, - typename T6, - typename T7, - typename T8, - typename T9, - typename T10> - format( streamable const &f, - T1 const &v1, - T2 const &v2, - T3 const &v3, - T4 const &v4, - T5 const &v5, - T6 const &v6, - T7 const &v7, - T8 const &v8, - T9 const &v9, - T10 const &v10) - { - init(f); - add(v1); - add(v2); - add(v3); - add(v4); - add(v5); - add(v6); - add(v7); - add(v8); - add(v9); - add(v10); - } -#endif - - template - format &operator % (Streamable const &object) - { - return add(streamable(object)); - } - - void operator()(std::ostream &output) const - { - write(output); - } - - std::string str(std::locale const &locale) const; - - std::string str() const - { - return str(std::locale::classic()); - } - - format &add(streamable const &obj); - private: - void write(std::ostream &output) const; - void format_one(std::ostream &out,std::string::const_iterator &p,std::string::const_iterator e,int &pos) const; - - void init(streamable const &f); - - streamable const *at(size_t n) const; - - streamable format_; - std::vector vobjects_; - streamable objects_[10]; - size_t size_; - }; - CPPCMS_STREAMED(format) + using locale::translate; + using locale::format; } /////////////////////////////// - using filters::format; - using filters::ngt; - using filters::gt; } #undef CPPCMS_STREAMED diff --git a/form.cpp b/form.cpp index a5f22d9..d98b2a9 100644 --- a/form.cpp +++ b/form.cpp @@ -3,8 +3,6 @@ #include #include #include -#include "locale_charset.h" -#include "locale_environment.h" namespace cppcms { @@ -380,12 +378,14 @@ void base_text::value(std::string v) std::string base_text::value(std::locale const &v) { - return std::use_facet(v).to_utf8(value_); + //return std::use_facet(v).to_utf8(value_); + return value_; } void base_text::value(std::string v,std::locale const &l) { - value(std::use_facet(l).from_utf8(v)); + //value(std::use_facet(l).from_utf8(v)); + value(v); } void base_text::non_empty() @@ -432,9 +432,9 @@ void base_text::load(http::context &context) set(true); if(validate_charset_) { code_points_ = 0; - locale::charset const &charset=std::use_facet(context.locale().get()); + /* locale::charset const &charset=std::use_facet(context.locale().get()); if(!charset.validate(value_,code_points_)) - valid(false); + valid(false);*/ } else { code_points_=value_.size(); diff --git a/form.h b/form.h index 7794692..a032ea9 100644 --- a/form.h +++ b/form.h @@ -14,7 +14,6 @@ #include "http_context.h" #include "http_request.h" #include "http_response.h" -#include "locale_environment.h" #include "copy_ptr.h" #include "cppcms_error.h" #include "util.h" @@ -897,7 +896,7 @@ namespace cppcms { return; std::istringstream ss(loaded_string_); - ss.imbue(context.locale().get()); + ss.imbue(context.locale()); ss>>value_; if(ss.fail() || !ss.eof()) valid(false); diff --git a/hello_world.cpp b/hello_world.cpp index 3660e3c..de93d95 100644 --- a/hello_world.cpp +++ b/hello_world.cpp @@ -5,15 +5,12 @@ #include "http_response.h" #include "http_request.h" #include "http_cookie.h" -#include "locale_environment.h" -#include "locale_charset.h" +#include "localization.h" #include "http_context.h" #include "filters.h" #include "aio_timer.h" #include "intrusive_ptr.h" #include "form.h" -#include "locale_convert.h" -#include "utf8_iterator.h" #include #include #include @@ -203,35 +200,16 @@ public: { } - template - void devide(std::string const &str,char const *name) + void devide(cppcms::locale::boundary::boundary_type type,std::string const &str,char const *name) { response().out()<\n"<\nRandom "<\n"; + response().out()<<"|
\n"; } void form() @@ -247,14 +225,15 @@ public: response().out()<< "\n"; - cppcms::locale::convert const &cv=std::use_facet(locale().get()); + std::locale loc = context().locale(); if(f.name.set()) { + using namespace cppcms::locale; std::string name = f.name.value(); - response().out() <<"Upper: "<"<"<"<"<"<"<"<"<(descr,"code"); - devide(descr,"char"); - devide(descr,"word"); - devide(descr,"sentence"); - devide(descr,"line"); + using namespace cppcms::locale; + devide(boundary::character,descr,"code"); + devide(boundary::word,descr,"word"); + devide(boundary::sentence,descr,"sentence"); + devide(boundary::line,descr,"line"); } if(ok) { @@ -315,19 +293,14 @@ public: response().out()<second<<"
\n"; } - time_t t=::time(NULL); - std::tm tt; - localtime_r(&t,&tt); - - response().out() << filters::date(tt) <"; + response().out() << filters::escape(locale::translate("hello\n")) << "
"; for(int i=0;i<30;i++) { - response().out() << format("To be or not to be %1%\n
",10); + response().out() << locale::format("To be or not to be {1}\n
") % 10; - response().out() << format(ngt("passed one day","passed %1% days",i),i) << "
\n"; - //cppcms::util::format(response().out(),ngt("passed one day","passed %1% days",i),i) << "
"; + response().out() << locale::format(locale::translate("passed one day","passed {1} days",i)) % i << "
\n"; } response().out() <<"\n"; diff --git a/http_context.cpp b/http_context.cpp index 877b93e..eb97f22 100644 --- a/http_context.cpp +++ b/http_context.cpp @@ -5,7 +5,6 @@ #include "http_context.h" #include "http_request.h" #include "http_response.h" -#include "locale_environment.h" #include "application.h" #include "applications_pool.h" #include "thread_pool.h" @@ -19,11 +18,11 @@ namespace cppcms { namespace http { struct context::data { - cppcms::locale::environment locale; + std::locale locale; http::request request; std::auto_ptr response; data(context &cntx) : - locale(cntx.connection().service()), + locale(cntx.connection().service().locale()), request(cntx.connection()) { } @@ -173,7 +172,7 @@ json::value const &context::settings() return conn_->service().settings(); } -cppcms::locale::environment &context::locale() +std::locale context::locale() { return d->locale; } diff --git a/http_context.h b/http_context.h index e874f1d..f4794f6 100644 --- a/http_context.h +++ b/http_context.h @@ -8,12 +8,13 @@ #include "callback0.h" #include "callback1.h" +#include + namespace cppcms { class service; class application; namespace json { class value; } - namespace locale { class environment; } namespace impl { namespace cgi { class connection; } } namespace http { @@ -30,7 +31,7 @@ namespace cppcms { http::request &request(); http::response &response(); json::value const &settings(); - cppcms::locale::environment &locale(); + std::locale locale(); cppcms::service &service(); void run(); diff --git a/http_response.cpp b/http_response.cpp index cadd8f5..18df3b8 100644 --- a/http_response.cpp +++ b/http_response.cpp @@ -9,8 +9,7 @@ #include "cppcms_error.h" #include "service.h" #include "config.h" -#include "locale_environment.h" -#include "locale_info.h" +#include "localization.h" #include "util.h" #include @@ -94,7 +93,7 @@ void response::set_content_header(std::string const &content_type) set_header("Content-Type",content_type); } else { - std::string charset=std::use_facet(context_.locale().get()).encoding(); + std::string charset=std::use_facet(context_.locale()).encoding(); set_header("Content-Type",content_type+"; charset="+charset); } } @@ -249,7 +248,7 @@ std::ostream &response::out() else stream_=real_sink; - stream_->imbue(context_.locale().get()); + stream_->imbue(context_.locale()); return *stream_; } diff --git a/locale.h b/locale.h deleted file mode 100644 index 504cfc5..0000000 --- a/locale.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CPPCMS_LOCALE_H -#define CPPCMS_LOCALE_H -#include - -namespace cppcms { - namespace locale { - using namespace boost::locale; - // Get there all of boost locale - } -} - - -#endif diff --git a/locale_charset.cpp b/locale_charset.cpp deleted file mode 100644 index 1756944..0000000 --- a/locale_charset.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_charset.h" -#include "encoding.h" -#include "utf_iterator.h" -#include "cppcms_error.h" -#include - -namespace cppcms { -namespace locale { - -struct charset::data {}; - -std::locale::id charset::id; - -charset::charset(std::size_t refs) : - std::locale::facet(refs), - is_utf8_(true), - validators_(0) -{ -} - - -charset::charset(std::string charset,std::size_t refs) : - std::locale::facet(refs), - name_(charset), - validators_(0) -{ - is_utf8_ = charset=="utf8" || charset=="UTF8" || charset=="utf-8" || charset=="UTF-8"; -} - - -charset::charset(std::string charset,intrusive_ptr p,std::size_t refs) : - std::locale::facet(refs), - name_(charset), - validators_(p) -{ - is_utf8_ = charset=="utf8" || charset=="UTF8" || charset=="utf-8" || charset=="UTF-8"; -} - -charset::~charset() -{ -} - - -bool charset::do_validate(char const *begin,char const *end,size_t &count) const -{ - if(!validators_) - return true; - encoding::validator v=(*validators_)[name_]; - return v.valid(begin,end,count); -} -std::string charset::do_to_utf8(std::string const &v) const -{ - if(is_utf8_) - return v; - encoding::converter conv(name_); - return conv.to_utf8(v.data(),v.data()+v.size()); - -} -std::string charset::do_from_utf8(std::string const &v) const -{ - if(is_utf8_) - return v; - encoding::converter conv(name_); - return conv.from_utf8(v.data(),v.data()+v.size()); -} - - -std::basic_string charset::do_to_utf16(char const *begin,char const *end) const -{ - if(is_utf8_) { - std::basic_string result; - result.reserve(end-begin); - while(begin < end) { - uint32_t code_point=utf8::next(begin,end,false,true); - if(code_point==utf::illegal) - throw cppcms_error("Invalid utf8"); - utf16::seq s=utf16::encode(code_point); - result.append(s.c,s.len); - } - return result; - } - encoding::converter conv(name_); - return conv.to_utf16(begin,end); -} - -std::basic_string charset::do_to_utf32(char const *begin,char const *end) const -{ - if(is_utf8_) { - std::basic_string result; - result.reserve(end-begin); - while(begin < end) { - uint32_t code_point=utf8::next(begin,end,false,true); - if(code_point==utf::illegal) - throw cppcms_error("Invalid utf8"); - result+=code_point; - } - return result; - } - - encoding::converter conv(name_); - return conv.to_utf32(begin,end); -} - - -std::string charset::do_from_utf16(uint16_t const *begin,uint16_t const *end) const -{ - if(is_utf8_) { - std::string result; - result.reserve(end-begin); - while(begin < end) { - uint32_t code_point=utf16::next(begin,end); - if(code_point==utf::illegal) - throw cppcms_error("Invalid utf16"); - utf8::seq s=utf8::encode(code_point); - result.append(s.c,s.len); - } - return result; - } - encoding::converter conv(name_); - return conv.from_utf16(begin,end); -} - - -std::string charset::do_from_utf32(uint32_t const *begin,uint32_t const *end) const -{ - if(is_utf8_) { - std::string result; - result.reserve(end-begin); - while(begin < end) { - uint32_t code_point=*begin++; - if(!utf::valid(code_point)) - throw cppcms_error("Invalid utf32"); - utf8::seq s=utf8::encode(code_point); - result.append(s.c,s.len); - } - return result; - } - encoding::converter conv(name_); - return conv.from_utf32(begin,end); -} - -} // locale -} // cppcms diff --git a/locale_charset.h b/locale_charset.h deleted file mode 100644 index b325108..0000000 --- a/locale_charset.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef CPPCMS_LOCALE_CHARSET_H -#define CPPCMS_LOCALE_CHARSET_H - -#include "defs.h" -#include "hold_ptr.h" -#include "intrusive_ptr.h" -#include "config.h" - -#include -#include - -#ifndef HAVE_STD_WSTRING -namespace std { - typedef basic_string wstring; -} -#endif - - -namespace cppcms { - namespace encoding { - class validators_set; - } - -namespace locale { - - class CPPCMS_API charset : public std::locale::facet { - public: - static std::locale::id id; - charset(std::size_t refs=0); - charset(std::string charset,std::size_t refs=0); - charset(std::string charset,intrusive_ptr p,std::size_t refs=0); - ~charset(); - - bool validate(char const *begin,char const *end,size_t &count) const - { - return do_validate(begin,end,count); - } - bool validate(std::string const &s,size_t &count) const - { - return do_validate(s.data(),s.data()+s.size(),count); - } - - std::string to_utf8(std::string const &v) const - { - return do_to_utf8(v); - } - - std::string from_utf8(std::string const &v) const - { - return do_from_utf8(v); - } - - std::basic_string to_utf16(char const *begin,char const *end) const - { - return do_to_utf16(begin,end); - } - - std::string from_utf16(uint16_t const *begin,uint16_t const *end) const - { - return do_from_utf16(begin,end); - } - - std::basic_string to_utf32(char const *begin,char const *end) const - { - return do_to_utf32(begin,end); - } - - std::string from_utf32(uint32_t const *begin,uint32_t const *end) const - { - return do_from_utf32(begin,end); - } - - std::wstring to_wstring(std::string const &v) const - { - #if SIZEOF_WCHAR_T==2 - std::basic_string tmp=do_to_utf16(v.data(),v.data()+v.size()); - #else - std::basic_string tmp=do_to_utf32(v.data(),v.data()+v.size()); - #endif - return std::wstring(tmp.begin(),tmp.end()); - } - std::string from_wstring(std::wstring const &v) const - { - #if SIZEOF_WCHAR_T==2 - uint16_t const *begin=reinterpret_cast(v.data()); - uint16_t const *end=begin+v.size(); - return do_from_utf16(begin,end); - #else - uint32_t const *begin=reinterpret_cast(v.data()); - uint32_t const *end=begin+v.size(); - return do_from_utf32(begin,end); - #endif - } - -#ifdef HAVE_CPP0X_UXSTRING - std::u16string to_u16string(std::string const &v) const - { - std::basic_string tmp=do_to_utf16(v.data(),v.data()+v.size()); - return std::u16string(tmp.begin(),tmp.end()); - } - std::string from_u16string(std::u16string const &v) const - { - uint16_t const *begin=reinterpret_cast(v.data()); - uint16_t const *end=begin+v.size(); - return do_from_utf16(begin,end); - } - std::u32string to_u32string(std::string const &v) const - { - std::basic_string tmp=do_to_utf32(v.data(),v.data()+v.size()); - return std::u32string(tmp.begin(),tmp.end()); - } - std::string from_u32string(std::u32string const &v) const - { - uint32_t const *begin=reinterpret_cast(v.data()); - uint32_t const *end=begin+v.size(); - return do_from_utf32(begin,end); - } -#endif - - private: - virtual bool do_validate(char const *begin,char const *end,size_t &count) const; - - virtual std::string do_to_utf8(std::string const &v) const; - virtual std::string do_from_utf8(std::string const &v) const; - - virtual std::basic_string do_to_utf16(char const *begin,char const *end) const; - virtual std::string do_from_utf16(uint16_t const *begin,uint16_t const *end) const; - - virtual std::basic_string do_to_utf32(char const *begin,char const *end) const; - virtual std::string do_from_utf32(uint32_t const *begin,uint32_t const *end) const; - - struct data; - util::hold_ptr d; - std::string name_; - bool is_utf8_; - intrusive_ptr validators_; - - }; - - -} } // cppcms::locale - -#endif diff --git a/locale_collate.cpp b/locale_collate.cpp deleted file mode 100644 index 3bf8d05..0000000 --- a/locale_collate.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_collate.h" -#include "locale_icu_locale.h" -#include "noncopyable.h" -#include "icu_util.h" - -#include - -#include -#include -#include - - -namespace cppcms { -namespace locale { - - class collate_impl : public util::noncopyable { - public: - typedef collate::level_type level_type; - - int compare(level_type level,std::string const &l,std::string const &r) const - { - - UErrorCode status=U_ZERO_ERROR; - - icu::UnicodeString left(impl::std_to_icu(l,locale_)); - icu::UnicodeString right(impl::std_to_icu(r,locale_)); - - int res = get(level)->compare(left,right,status); - - if(U_FAILURE(status)) - throw std::runtime_error(std::string("collation failed:") + u_errorName(status)); - if(res<0) - return -1; - else if(res > 0) - return 1; - return 0; - } - - std::string transform(level_type level,std::string const &s) const - { - icu::UnicodeString us(impl::std_to_icu(s,locale_)); - std::string tmp; - tmp.resize(s.size()); - boost::shared_ptr collator=get(level); - int len = collator->getSortKey(us,reinterpret_cast(&tmp[0]),tmp.size()); - if(len > int(tmp.size())) { - tmp.resize(len); - collator->getSortKey(us,reinterpret_cast(&tmp[0]),tmp.size()); - } - else - tmp.resize(len); - return tmp; - } - - collate_impl(std::locale const &l) : locale_(l) - { - icu_locale const &iculoc=std::use_facet(locale_); - static const icu::Collator::ECollationStrength levels[collators_size] = - { - icu::Collator::PRIMARY, - icu::Collator::SECONDARY, - icu::Collator::TERTIARY, - icu::Collator::QUATERNARY - }; - - for(int i=0;isetStrength(levels[i]); - } - - } - - private: - - static const int collators_size = 4; - - boost::shared_ptr get(level_type level) const - { - int l=int(level); - if(l < 0) - l=0; - else if(l >= collators_size) - l = collators_size-1; - return collators_[l]; - } - - - boost::shared_ptr collators_[collators_size]; - std::locale locale_; - }; - -///////// - - collate::collate(collate_impl *impl,size_t refs) : std::collate(refs),impl_(impl) - { - } - collate::~collate() - { - } - int collate::compare(level_type level,std::string const &l,std::string const &r) const - { - return impl_->compare(level,l,r); - } - int collate::compare( level_type level, - char const *p1_start,char const *p1_end, - char const *p2_start,char const *p2_end) const - { - return impl_->compare(level,std::string(p1_start,p1_end),std::string(p2_start,p2_end)); - } - std::string collate::transform(level_type level,std::string const &s) const - { - return impl_->transform(level,s); - } - std::string collate::transform(level_type level,char const *b,char const *e) const - { - return impl_->transform(level,std::string(b,e)); - } - - long collate::hash(level_type level,std::string const &s) const - { - boost::hash hasher; - return hasher(transform(level,s)); - } - long collate::hash(level_type level,char const *b,char const *e) const - { - boost::hash hasher; - return hasher(transform(level,b,e)); - } - - collate *collate::create(std::locale const &l) - { - return new collate(new collate_impl(l)); - } - - -} } // cppcms::locale diff --git a/locale_collate.h b/locale_collate.h deleted file mode 100644 index 95d03bd..0000000 --- a/locale_collate.h +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -#include "defs.h" -#include "hold_ptr.h" - -namespace cppcms { namespace locale { - - class collate_impl; - - class CPPCMS_API collate : public std::collate { - public: - - typedef enum { - primary = 0, - alphabetic_sensitive = primary, - secondary = 1, - diacritic_sensitive = secondary, - tertiary = 2, - case_sensitive = tertiary, - quaternary = 3 - } level_type; - - int compare( level_type level, - char const *p1_start,char const *p1_end, - char const *p2_start,char const *p2_end) const; - - int compare(level_type level,std::string const &l,std::string const &r) const; - long hash(level_type level,std::string const &s) const; - long hash(level_type level,char const *b,char const *e) const; - std::string transform(level_type level,std::string const &s) const; - std::string transform(level_type level,char const *b,char const *e) const; - - static collate *create(std::locale const &l); - - private: - - collate(collate_impl *impl,size_t refs = 0); - virtual ~collate(); - - /// Standard functions... override - virtual int do_compare( char const *p1_start,char const *p1_end, - char const *p2_start,char const *p2_end) const - { - return compare(primary,p1_start,p1_end,p2_start,p2_end); - } - virtual std::string do_transform(char const *b,char const *e) const - { - return transform(primary,b,e); - } - - virtual long do_hash(char const *b,char const *e) const - { - return hash(primary,b,e); - } - - - util::hold_ptr impl_; - - }; - -} } // cppcms::locale diff --git a/locale_convert.cpp b/locale_convert.cpp deleted file mode 100644 index 5c42fdf..0000000 --- a/locale_convert.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_convert.h" -#include "locale_icu_locale.h" -#include "locale_charset.h" -#include "noncopyable.h" -#include "utf_iterator.h" - -#ifdef HAVE_ICU -#include -#include -#include "icu_util.h" -#endif - -#include -#include - -namespace cppcms { -namespace locale { - class convert_impl : public util::noncopyable { - public: - virtual std::string to_upper(std::string const &str) const = 0; - virtual std::string to_lower(std::string const &str) const = 0; - virtual std::string to_title(std::string const &str) const = 0; - virtual std::string to_normal(std::string const &str,convert::norm_type how) const = 0; - virtual ~convert_impl() {}; - }; - - - - -#ifdef HAVE_ICU - - class icu_convert_impl : public convert_impl { - public: - icu_convert_impl(std::locale const &loc) : - std_locale_(loc), - icu_locale_(std::use_facet(loc).get()) - { - } - - static icu::UnicodeString normalize(icu::UnicodeString const &str,convert::norm_type how) - { - UNormalizationMode mode; - switch(how) { - case convert::norm_nfc: mode = UNORM_NFC; break; - case convert::norm_nfd: mode = UNORM_NFD; break; - case convert::norm_nfkc: mode = UNORM_NFKC; break; - case convert::norm_nfkd: mode = UNORM_NFKD; break; - default: mode=UNORM_DEFAULT; - } - - icu::UnicodeString res; - UErrorCode status = U_ZERO_ERROR; - - icu::Normalizer::normalize(str,mode,0,res,status); - if(U_FAILURE(status)) - throw std::runtime_error(std::string("normalization failed:") + u_errorName(status)); - return res; - } - - std::string to_upper(std::string const &str) const - { - return impl::icu_to_std((impl::std_to_icu(str,std_locale_).toUpper(icu_locale_)),std_locale_); - } - std::string to_lower(std::string const &str) const - { - return impl::icu_to_std((impl::std_to_icu(str,std_locale_).toLower(icu_locale_)),std_locale_); - } - std::string to_title(std::string const &str) const - { - return impl::icu_to_std((impl::std_to_icu(str,std_locale_).toTitle(0,icu_locale_)),std_locale_); - } - std::string to_normal(std::string const &str,convert::norm_type how) const - { - return impl::icu_to_std(normalize(impl::std_to_icu(str,std_locale_),how),std_locale_); - } - private: - friend class convert; - std::locale std_locale_; - icu::Locale icu_locale_; - }; - - - - -#endif - - class std_convert_impl : public convert_impl { - public: - - - std_convert_impl(std::locale const &l) : - locale_(l), - cfacet_(0), - wfacet_(0), - charset_(0) - { - if(std::has_facet >(locale_)) { - wfacet_ = & std::use_facet >(locale_); - charset_ = & std::use_facet(locale_); - } - else { - cfacet_ = & std::use_facet >(locale_); - } - } - - template - void titelize(std::basic_string &str,std::ctype const *conv) const - { - bool prev_is_not_alpha = true; - for(unsigned i=0;itoupper(c); - else - str[i]=conv->tolower(c); - prev_is_not_alpha=!conv->is(std::ctype_base::alpha,c); - } - } - - std::string to_upper(std::string const &str) const - { - if(wfacet_) { - std::wstring tmp=charset_->to_wstring(str); - wfacet_->toupper(&tmp[0],&tmp[0]+tmp.size()); - return charset_->from_wstring(tmp); - } - else { - std::string tmp=str; - cfacet_->toupper(&tmp[0],&tmp[0]+tmp.size()); - return tmp; - } - } - - std::string to_lower(std::string const &str) const - { - if(wfacet_) { - std::wstring tmp=charset_->to_wstring(str); - wfacet_->tolower(&tmp[0],&tmp[0]+tmp.size()); - return charset_->from_wstring(tmp); - } - else { - std::string tmp=str; - cfacet_->tolower(&tmp[0],&tmp[0]+tmp.size()); - return tmp; - } - } - - std::string to_title(std::string const &str) const - { - if(wfacet_) { - std::wstring tmp=charset_->to_wstring(str); - titelize(tmp,wfacet_); - return charset_->from_wstring(tmp); - } - else { - std::string tmp=str; - titelize(tmp,cfacet_); - return tmp; - } - } - - std::string to_normal(std::string const &str,convert::norm_type how) const - { - #ifdef HAVE_ICU - return impl::icu_to_std(icu_convert_impl::normalize(impl::std_to_icu(str,locale_),how),locale_); - #else - return str; - #endif - } - private: - std::locale locale_; - std::ctype const *cfacet_; - std::ctype const *wfacet_; - charset const *charset_; - }; // std_convert - - - - std::locale::id convert::id; - - convert *convert::create(std::locale const &l,std::string provider) - { - #ifdef HAVE_ICU - char const *default_provider="icu"; - #else - char const *default_provider="std"; - #endif - - if(provider=="default") - provider=default_provider; - - #ifdef HAVE_ICU - if(provider=="icu") { - return new convert(new icu_convert_impl(l)); - } - #endif - - if(provider=="std") { - return new convert(new std_convert_impl(l)); - } - throw std::runtime_error("Unknown locale provider:"+provider); - - } - - convert::convert(convert_impl *impl,size_t refs) : std::locale::facet(refs), impl_(impl) - { - } - convert::~convert() - { - } - - std::string convert::to_upper(std::string const &str) const { return impl_->to_upper(str); } - std::string convert::to_lower(std::string const &str) const { return impl_->to_lower(str); } - std::string convert::to_title(std::string const &str) const { return impl_->to_title(str); } - std::string convert::to_normal(std::string const &str,norm_type how) const { return impl_->to_normal(str,how); } - - -} /// locale -} /// convert - diff --git a/locale_convert.h b/locale_convert.h deleted file mode 100644 index 48bce55..0000000 --- a/locale_convert.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef CPPCMS_LOCALE_ICU_H -#define CPPCMS_LOCALE_ICU_H - -#include "defs.h" -#include "config.h" -#include "hold_ptr.h" -#include - - -namespace cppcms { -namespace locale { - - class convert_impl; - - /// - /// \brief This class provides basic unicode aware string manipulation utilities - /// - /// If CppCMS is compiled with ICU support it performs these operations using ICU - /// library, otherwise it uses std::locale facets for these operations, so some - /// functionality may have lower quality or not supported at all - /// - - class CPPCMS_API convert : public std::locale::facet { - public: - static std::locale::id id; - - typedef enum { norm_default, /// < Default Unicode normalization as provided by ICU - norm_nfc, /// < NFC Unicode normalization - norm_nfd, /// < NFD Unicode normalization - norm_nfkc, /// < NFKC Unicode normalization - norm_nfkd /// < NFKD Unicode normalization - } norm_type; - - - /// - /// Create convert facet. - /// - /// \a charset, \a icu_locale and \a info facets should be assigned to \a source - /// - - convert(convert_impl *impl,size_t refs=0); - virtual ~convert(); - - /// - /// Convert string in current locale representation (utf8 or other encoding) - /// to upper case. - /// - - std::string to_upper(std::string const &str) const; - /// - /// Convert string in current locale representation (utf8 or other encoding) - /// to lower case. - /// - - std::string to_lower(std::string const &str) const; - - /// - /// Convert string in current locale representation (utf8 or other encoding) - /// to title case. - /// - std::string to_title(std::string const &str) const; - - /// - /// Perform Unicode normalization of the string in current locale representation - /// (utf8 or other encoding). Such conversion may be meaningless for non-Unicode locale. - /// - /// Note: if CppCMS is compiled without support of ICU this function does nothing. - /// - - std::string to_normal(std::string const &str,norm_type how = norm_default) const; - - /// - /// Create instance of the facet - /// - - static convert *create(std::locale const &l,std::string provider="default"); - - private: - - util::hold_ptr impl_; - - }; - - -} // locale -} // cppcms - - -#endif diff --git a/locale_environment.cpp b/locale_environment.cpp deleted file mode 100644 index 73714e1..0000000 --- a/locale_environment.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_environment.h" -#include "service.h" -#include "locale_pool.h" -#include "json.h" - -namespace cppcms { -namespace locale { - -struct environment::data { - std::locale const *locale; - gettext::tr const *current; - std::string domain_name; - std::string locale_name; -}; - -environment::environment(cppcms::service &srv) : - service_(srv), - d(new data) -{ - d->locale_name=service_.settings().get("locale.default","C"); - setup(); -} - -environment::~environment() -{ -} - - -void environment::setup() -{ - d->locale=&service_.locale_pool().get(d->locale_name); - - if(std::has_facet(*d->locale)){ - cppcms::locale::gettext const >=std::use_facet(*d->locale); - if(d->domain_name.empty()) - d->current=>.dictionary(); - else - d->current=>.dictionary(d->domain_name.c_str()); - } - else { - static cppcms::locale::gettext::tr const tr; - d->current=&tr; - } -} - -void environment::locale(std::string l) -{ - d->locale_name=l; - setup(); -} - -std::string environment::locale() -{ - return d->locale_name; -} - -void environment::gettext_domain(std::string s) -{ - d->domain_name=s; - setup(); -} - -std::string environment::gettext_domain() -{ - return d->domain_name; -} - - -char const *environment::ngt(char const *s,char const *p,int n) -{ - return d->current->ngettext(s,p,n); -} -char const *environment::gt(char const *s) -{ - return d->current->gettext(s); -} - -std::locale const &environment::get() -{ - return *d->locale; -} - - -} // locale -} // cppcms - - diff --git a/locale_environment.h b/locale_environment.h deleted file mode 100644 index dbdc33e..0000000 --- a/locale_environment.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CPPCMS_LOCALE_ENVIRONMENT_H -#define CPPCMS_LOCALE_ENVIRONMENT_H - -#include "defs.h" -#include "hold_ptr.h" -#include "noncopyable.h" -#include "locale_gettext.h" - -namespace cppcms { - class service; - namespace locale { - - class CPPCMS_API environment : public util::noncopyable { - public: - std::locale const &get(); - void set(std::locale const &); - void gettext_domain(std::string s); - std::string gettext_domain(); - void locale(std::string); - std::string locale(); - - char const *gt(char const *s); - char const *ngt(char const *s,char const *p,int n); - - - environment(cppcms::service &srv); - ~environment(); - - private: - void setup(); - - struct data; - cppcms::service &service_; - util::hold_ptr d; - }; - }// -} // cppcms - - -#endif diff --git a/locale_gettext.cpp b/locale_gettext.cpp deleted file mode 100644 index 2e03f1d..0000000 --- a/locale_gettext.cpp +++ /dev/null @@ -1,561 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_gettext.h" -#include "locale_mo_file.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace cppcms { -namespace locale { -namespace impl { - namespace lambda { - struct plural { // INTERFACE - virtual int operator()(int n) const = 0; - virtual ~plural(){}; - }; - plural *compile(char const *expr); - } - - - class trans_thread_safe : public gettext::tr { - - struct default_plural : public lambda::plural { - int operator()(int n) const { return n==1 ? 0 : 1; }; - ~default_plural() {}; - }; - - std::auto_ptr dic_; - std::auto_ptr converter_; - - static lambda::plural *get_converter(char const *header) - { - using namespace std; - char const *ptr,*ptr2; - string tmp; - lambda::plural *result; - if(!header) goto error; - ptr=strstr(header,"Plural-Forms:"); - if(!ptr) goto error; - ptr=strstr(ptr,"plural"); - if(!ptr) goto error; - if(ptr[6]=='s') { // Prevent detecting plurals as plural - ptr=strstr(ptr+6,"plural"); - } - if(!ptr) goto error; - ptr+=6; - while(*ptr && isblank(*ptr)) ptr++; - if(*ptr!='=') goto error; - ptr++; - ptr2=strstr(ptr,";"); - if(!ptr2) goto error; - tmp.append(ptr,ptr2-ptr); - result=lambda::compile(tmp.c_str()); - if(!result) goto error; - return result; - error: - return new default_plural(); - } - public: - trans_thread_safe(dictionary *dic) : - dic_(dic) - { - char const *header=dic_->lookup("",0); - converter_.reset(get_converter(header)); - } - virtual ~trans_thread_safe() - { - } - virtual char const *gettext(char const *s) const - { - char const *t=dic_->lookup(s,0); - return t ? t : s; - } - - virtual char const *ngettext(char const *s,char const *p,int n) const - { - int idx=(*converter_)(n); - if(idx<0) idx=0; - char const *t=dic_->lookup(s,idx); - if(!t) { - return n==1 ? s : p; - } - return t; - } - }; - -} // impl - - -// The actual gettext class - -gettext::tr::~tr() -{ -} - -char const *gettext::tr::gettext(char const *m) const -{ - return m; -} - -char const *gettext::tr::ngettext(char const *s,char const *p,int n) const -{ - return n==1 ? s : p; -} - - -std::locale::id gettext::id; - -struct gettext::data { - typedef std::map > translators_type; - translators_type translators; - std::string default_domain; -}; - - -gettext::gettext(std::size_t refs) : - std::locale::facet(refs), - d(new data) -{ -} -gettext::~gettext() -{ -} - - -bool gettext::load(std::string locale,std::string dir,std::string domain) -{ - std::auto_ptr dic; - - static boost::regex lreg("^([a-zA-Z]+)(_([a-zA-Z])+)?(\\.([a-zA-Z0-9_\\-]+))?(\\@(.*))?$"); - boost::cmatch m; - if(!boost::regex_match(locale.c_str(),m,lreg)) { - return false; - } - - std::string variants[4]={ - m[1]+m[2]+m[6], - m[1]+m[2], - m[1]+m[6], - m[1] - }; - for(int i=0;i<4;i++) { - std::string path=dir + "/" + variants[i] +"/LC_MESSAGES/" + domain + ".mo"; - dic.reset(impl::dictionary::load(path.c_str())); - if(dic.get()) { - d->translators[domain].reset(new impl::trans_thread_safe(dic.release())); - return true; - } - } - return false; -} - -void gettext::set_default_domain(std::string domain) -{ - d->default_domain=domain; -} - - -gettext::tr const &gettext::do_dictionary() const -{ - return do_dictionary(d->default_domain.c_str()); -} - -gettext::tr const &gettext::do_dictionary(char const *domain) const -{ - data::translators_type::const_iterator p=d->translators.find(domain); - if(p == d->translators.end()) { - static const gettext::tr default_one; - return default_one; - } - return *p->second; -} - - -namespace impl { -namespace lambda { - -#define LOG(x) - -struct identity : public plural { - virtual int operator()(int n) const { LOG(cout<<"id("<>",2)==0) { pos+=2; next_tocken=SHR; } - else if(strncmp(ptr,"&&",2)==0) { pos+=2; next_tocken=AND; } - else if(strncmp(ptr,"||",2)==0) { pos+=2; next_tocken=OR; } - else if(strncmp(ptr,"<=",2)==0) { pos+=2; next_tocken=LTE; } - else if(strncmp(ptr,">=",2)==0) { pos+=2; next_tocken=GTE; } - else if(strncmp(ptr,"==",2)==0) { pos+=2; next_tocken=EQ; } - else if(strncmp(ptr,"!=",2)==0) { pos+=2; next_tocken=NEQ; } - else if(*ptr=='n') { pos++; next_tocken=VARIABLE; } - else if(isdigit(*ptr)) { int_value=strtol(text+pos,&tmp_ptr,0); pos=tmp_ptr-text; next_tocken=NUM; } - else if(*ptr=='\0') { next_tocken=0; } - else { next_tocken=*ptr; pos++; } - #ifdef DEBUG_LAMBDA - if(next_tocken>=' ' && next_tocken<=127) - std::cout<<"Tocken:"<<(char)next_tocken<<'\n'; - else if(next_tocken==NUM) - std::cout<<"Number:"<(p); - if(pi) { return string("n"); }; - unary *pu=dynamic_cast(p); - if(pu) { return string(typeid(*pu).name())+"("+printtree(pu->op1)+")"; } - binary *pb=dynamic_cast(p); - if(pb) { return string(typeid(*pb).name())+"("+printtree(pb->op1)+","+printtree(pb->op2)+")"; }; - number *pn=dynamic_cast(p); - if(pn) { char buf[32]; snprintf(buf,sizeof(buf),"(%d)",pn->val); return string(buf); }; - conditional *pc=dynamic_cast(p); - if(pc) { return "("+printtree(pc->op1)+")?("+printtree(pc->op2)+"):("+printtree(pc->op3)+")"; }; - return string("PLURAL"); -} -#endif - -plural *compile(char const *str) -{ - LOG(cout<<"Compiling:["< - -namespace cppcms { -namespace locale { - - class CPPCMS_API gettext : public std::locale::facet { - public: - static std::locale::id id; - - - struct CPPCMS_API tr { - public: - virtual char const *gettext(char const *m) const; - virtual char const *ngettext(char const *s,char const *p,int n) const; - virtual ~tr(); - }; - - gettext(std::size_t refs=0); - ~gettext(); - - - tr const &dictionary(char const *domain) const - { - return do_dictionary(domain); - } - - tr const &dictionary() const - { - return do_dictionary(); - } - - bool load(std::string locale_name,std::string path,std::string domain); - void set_default_domain(std::string domain); - - protected: - - virtual tr const &do_dictionary(char const *domain) const; - virtual tr const &do_dictionary() const; - - private: - - - struct data; - util::hold_ptr d; - }; - -} // locale -} // cppcms - - - -#endif diff --git a/locale_icu_locale.cpp b/locale_icu_locale.cpp deleted file mode 100644 index 972c34e..0000000 --- a/locale_icu_locale.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#define CPPCMS_SOURCE - -#include "locale_icu_locale.h" -#ifdef HAVE_ICU -namespace cppcms { namespace locale { - std::locale::id icu_locale::id; - - struct icu_locale::data {}; - - icu_locale::icu_locale(std::string name,size_t refs) : - std::locale::facet(refs), - locale_(icu::Locale::createCanonical(name.c_str())) - { - } - icu_locale::~icu_locale() - { - } - icu::Locale const &icu_locale::get() const - { - return locale_; - } - -}} // locale::cppcms -#endif diff --git a/locale_icu_locale.h b/locale_icu_locale.h deleted file mode 100644 index e269dbd..0000000 --- a/locale_icu_locale.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CPPCMS_LOCALE_ICU_LOCALE_H -#define CPPCMS_LOCALE_ICU_LOCALE_H -#include "defs.h" -#include "config.h" -#include "hold_ptr.h" - -#ifdef HAVE_ICU - -#include -#include -#include - -namespace cppcms { - namespace locale { - - class CPPCMS_API icu_locale : public std::locale::facet { - public: - static std::locale::id id; - icu_locale(std::string name,size_t refs = 0); - - icu::Locale const &get() const; - virtual ~icu_locale(); - private: - struct data; - util::hold_ptr d; - icu::Locale locale_; - }; - } -} - - -#endif // HAVE_ICU -#endif diff --git a/locale_info.cpp b/locale_info.cpp deleted file mode 100644 index 9133773..0000000 --- a/locale_info.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_info.h" -#include - - -namespace cppcms { -namespace locale { - - std::locale::id info::id; - - struct info::data {}; - - info::info(std::string name,std::size_t refs) : - std::locale::facet(refs), - name_(name), - is_utf8_(false) - { - static boost::regex lreg("^([a-zA-Z]+)(_([a-zA-Z])+)?(\\.([a-zA-Z0-9_\\-]+))?(\\@(.*))?$"); - boost::cmatch m; - if(!boost::regex_match(name_.c_str(),m,lreg)) { - return; - } - - language_=m[1]; - territory_=m[3]; - encoding_=m[5]; - variant_=m[7]; - if(encoding_ == "utf-8" || encoding_=="UTF-8" || encoding_=="utf8" || encoding_=="UTF8") - is_utf8_=true; - } - info::~info() - { - } - - std::string info::name() const { return name_; } - std::string info::language() const { return language_; } - std::string info::territory() const { return territory_; } - std::string info::encoding() const { return encoding_; } - std::string info::variant() const { return variant_; } - bool info::is_utf8() const { return is_utf8_; } - -} // locale -} // cppcms diff --git a/locale_info.h b/locale_info.h deleted file mode 100644 index a3efd24..0000000 --- a/locale_info.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CPPCMS_LOCALE_INFO_H -#define CPPCMS_LOCALE_INFO_H - -#include "defs.h" -#include "hold_ptr.h" -#include -#include - -namespace cppcms { namespace locale { - - class CPPCMS_API info : public std::locale::facet { - public: - static std::locale::id id; - info(std::string name,std::size_t refs=0); - ~info(); - - std::string name() const ; - - std::string language() const; - std::string territory() const; - std::string encoding() const; - std::string variant() const; - - bool is_utf8() const; - private: - struct data; - util::hold_ptr d; - std::string name_; - std::string language_; - std::string territory_; - std::string encoding_; - std::string variant_; - bool is_utf8_; - - }; - - -} } // cppcms::locale - -#endif diff --git a/locale_mo_file.cpp b/locale_mo_file.cpp deleted file mode 100644 index 3fe46e9..0000000 --- a/locale_mo_file.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "locale_mo_file.h" - -/******************************************************** - * This file was adopted by Artyom Tonkikh for * - * purouses of thread safe gettext implementation * - ********************************************************/ - -/* - -The MIT License - -Copyright (c) 2007 Jonathan Blow (jon [at] number-none [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - - - -/* - This code is designed to be a very simple drop-in method for reading .mo - files, which are a standard format for storing text strings to help with - internationalization. - - For more information, see: http://www.gnu.org/software/gettext/manual/gettext.html - - Unfortunately the gettext code is unwieldy. For a simple program like - a video game, we just want to look up some strings in a pre-baked file, - which is what this code does. - - We assume that you started with a .po file (which is a human-readable format - containing all the strings) and then compiled it into a .mo file (which is - a binary format that can be efficiently read into memory all in one chunk). - This code then reads straight from the .mo file, so there is no extra - string allocation and corresponding memory fragmentation. - - You can generate a .mo file from a .po file using programs such as poedit - or msgfmt. - - This code assumes you compiled the hash table into the .mo file. It also - doesn't attempt to care about the encoding of your text; it assumes you - already know what that is. (I use UTF-8 which seems like the only sane - choice). - - There's no good reason that this is a C++ file, rather than a C file; I just - wrote it that way originally. You can trivially get rid of the C++-ness if - you want it to compile as straight C. - - Send questions to jon [at] number-none [dot] com. - - 21 December 2007 -*/ - - -// From the header file: -// From the .cpp fie: - -#include -#include -#include -#include -#include - - - -namespace cppcms { namespace locale { namespace impl { - -struct Localization_Text { - Localization_Text(char const*); - ~Localization_Text(); - - void abort(); - - void *mo_data; - int reversed; - - int num_strings; - int original_table_offset; - int translated_table_offset; - int hash_num_entries; - int hash_offset; -}; - - -// This is just the common hashpjw routine, pasted in: - -#define HASHWORDBITS 32 - -inline unsigned long hashpjw(const char *str_param) { - - unsigned long hval = 0; - unsigned long g; - const char *s = str_param; - - while (*s) { - hval <<= 4; - hval += (unsigned char) *s++; - g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); - if (g != 0) { - hval ^= g >> (HASHWORDBITS - 8); - hval ^= g; - } - } - - return hval; -} - - -// Here is the actual code: - - - -// Read an entire file into memory. Replace this with any equivalent function. - -#ifdef WIN32 -#define fileno _fileno -#define fstat _fstat -#define stat _stat -#endif -int os_read_entire_file(FILE *file, void **data_return) { - assert(file); - int descriptor = fileno(file); - - struct stat file_stats; - int result = fstat(descriptor, &file_stats); - if (result == -1) return -1; - - int length = file_stats.st_size; - - unsigned char *data = new unsigned char[length]; - - fseek(file, 0, SEEK_SET); - int success = fread((void *)data, length, 1, file); - if (success < 1) { - delete [] data; - return -1; - } - - *data_return = data; - return length; -} - - -// Swap the endianness of a 4-byte word. -// On some architectures you can replace my_swap4 with an inlined instruction. -inline unsigned long my_swap4(unsigned long result) { - unsigned long c0 = (result >> 0) & 0xff; - unsigned long c1 = (result >> 8) & 0xff; - unsigned long c2 = (result >> 16) & 0xff; - unsigned long c3 = (result >> 24) & 0xff; - - return (c0 << 24) | (c1 << 16) | (c2 << 8) | c3; -} - -inline int read4_from_offset(Localization_Text *loc, int offset) { - unsigned long *ptr = (unsigned long *)(((char *)loc->mo_data) + offset); - - if (loc->reversed) { - return my_swap4(*ptr); - } else { - return *ptr; - } -} - -inline char *get_source_string(Localization_Text *loc, int index,int *len=NULL) { - int addr_offset = loc->original_table_offset + 8 * index; - int string_len = read4_from_offset(loc, addr_offset); - int string_offset = read4_from_offset(loc, addr_offset+4); - - char *t = ((char *)loc->mo_data) + string_offset; - if(len) *len=string_len; - return t; -} - -inline char *get_translated_string(Localization_Text *loc, int index, int *len=NULL) { - int addr_offset = loc->translated_table_offset + 8 * index; - if(len) *len=read4_from_offset(loc, addr_offset); - int string_offset = read4_from_offset(loc, addr_offset+4); - - char *t = ((char *)loc->mo_data) + string_offset; - return t; -} - -static bool label_matches(Localization_Text *loc, char const *s, int index) { - char *t = get_source_string(loc, index); - if (strcmp(s, t) == 0) return true; - - return false; -} - -inline int get_target_index(Localization_Text *loc, char const *s) { - unsigned long V = hashpjw(s); - int S = loc->hash_num_entries; - - int hash_cursor = V % S; - int orig_hash_cursor = hash_cursor; - int increment = 1 + (V % (S - 2)); - - while (1) { - unsigned int index = read4_from_offset(loc, loc->hash_offset + 4 * hash_cursor); - if (index == 0) break; - - index--; // Because entries in the table are stored +1 so that 0 means empty. - - if (label_matches(loc, s, index)) return index; - // if (index_empty(loc, index)) break; - - hash_cursor += increment; - hash_cursor %= S; - - if (hash_cursor == orig_hash_cursor) break; - } - - return -1; -} - - - - -Localization_Text::Localization_Text(char const *filename) { - mo_data = NULL; - num_strings = 0; - original_table_offset = 0; - translated_table_offset = 0; - hash_num_entries = 0; - hash_offset = 0; - - FILE *f = fopen(filename, "rb"); - if (!f) return; - - void *data; - int length = os_read_entire_file(f, &data); // Replace this with any function that will read an entire file and return it in a block of newly-allocated memory. - fclose(f); - - if (length < 0) return; // os_read_entire_file returns -1 on failure. - if (length < 24) { // There has to be at least this much in the header... - abort(); - return; - } - - mo_data = data; - - unsigned long *long_ptr = (unsigned long *)data; - - const unsigned long TARGET_MAGIC = 0x950412DE; - const unsigned long TARGET_MAGIC_REVERSED = 0xDE120495; - unsigned long magic = long_ptr[0]; - - if (magic == TARGET_MAGIC) { - reversed = 0; - } else if (magic == TARGET_MAGIC_REVERSED) { - reversed = 1; - } else { - abort(); - return; - } - - num_strings = read4_from_offset(this, 8); - original_table_offset = read4_from_offset(this, 12); - translated_table_offset = read4_from_offset(this, 16); - hash_num_entries = read4_from_offset(this, 20); - hash_offset = read4_from_offset(this, 24); - - if (hash_num_entries == 0) { // We expect a hash table to be there; if it's not, bail. - abort(); - return; - } -} - -void Localization_Text::abort() { - delete [] (char *)mo_data; - mo_data = NULL; - return; -} - -Localization_Text::~Localization_Text() { - if (mo_data) delete [] ((char *)mo_data); -} - - -dictionary::dictionary(std::auto_ptr l) : loc_(l) -{ -} - -dictionary::~dictionary() -{ -} - -dictionary *dictionary::load(char const *fname) -{ - std::auto_ptr loc(new Localization_Text(fname)); - if(!loc->mo_data) - return 0; - return new dictionary(loc); -} - -char const *dictionary::lookup(char const *s,int std_id) const -{ - - int len; - int target_index = get_target_index(loc_.get(), s); - if (target_index == -1) return NULL; // Maybe we want to log an error? - - char *tmp=get_translated_string(loc_.get(), target_index, &len); - - char *p=tmp; - while(std_id>0 && p-tmp - -namespace cppcms { - namespace locale { - namespace impl { - struct Localization_Text; - - class dictionary { - public: - ~dictionary(); - char const *lookup(char const *s,int std_id) const; - static dictionary *load(char const *file_name); - private: - dictionary(std::auto_ptr); - dictionary(dictionary const &); - dictionary const &operator=(dictionary const &); - - std::auto_ptr loc_; - }; - } - } - -} - - - -#endif diff --git a/locale_numeric.cpp b/locale_numeric.cpp deleted file mode 100644 index dee9593..0000000 --- a/locale_numeric.cpp +++ /dev/null @@ -1,287 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_numeric.h" -#include "icu_util.h" -#include "locale_icu_locale.h" -#include "cppcms_error.h" - -#include -#include -#include -#include - -#include - -namespace cppcms { -namespace locale { - - class numeric_impl { - public: - typedef boost::shared_ptr formatter_type; - - typedef numeric::format_type format_type; - - formatter_type get(format_type type,int presision=-1) const - { - formatter_type fmt; - - if(type < 0 || type >= numeric::format_count) - type=numeric::format_normal; - - fmt=formatters_[type]; - - if(presision == -1) - return fmt; - - fmt.reset(static_cast(fmt->clone())); - - fmt->setMaximumFractionDigits(presision); - fmt->setMinimumFractionDigits(presision); - - return fmt; - } - - std::string format(format_type type,double v,int pres=-1) const - { - icu::UnicodeString str; - return impl::icu_to_std(get(type,pres)->format(v,str),locale_); - } - - std::string format(format_type type,int32_t v) const - { - icu::UnicodeString str; - return impl::icu_to_std(get(type)->format(v,str),locale_); - } - - std::string format(format_type type,int64_t v) const - { - icu::UnicodeString str; - return impl::icu_to_std(get(type)->format(v,str),locale_); - } - - bool parse_base(format_type type,std::string const &str,icu::Formattable &fmt) const - { - icu::ParsePosition pos; - icu::UnicodeString ustr=impl::std_to_icu(str,locale_); - - get(type)->parse(ustr,fmt,pos); - - if(pos.getIndex()==0 || pos.getIndex()!=ustr.length()) - return false; - return true; - } - - - bool parse(format_type type,std::string const &str,double &v) const - { - icu::Formattable fmt; - if(!parse_base(type,str,fmt)) - return false; - - UErrorCode code=U_ZERO_ERROR; - double tmp=fmt.getDouble(code); - if(U_FAILURE(code)) - return false; - v=tmp; - return true; - } - - bool parse(format_type type,std::string const &str,int32_t &v) const - { - icu::Formattable fmt; - if(!parse_base(type,str,fmt)) - return false; - - UErrorCode code=U_ZERO_ERROR; - int32_t tmp=fmt.getLong(code); - if(U_FAILURE(code)) - return false; - v=tmp; - return true; - } - - bool parse(format_type type,std::string const &str,int64_t &v) const - { - icu::Formattable fmt; - if(!parse_base(type,str,fmt)) - return false; - - UErrorCode code=U_ZERO_ERROR; - int64_t tmp=fmt.getInt64(code); - if(U_FAILURE(code)) - return false; - v=tmp; - return true; - } - - numeric_impl(std::locale const &std_loc) : locale_(std_loc) - { - #define CPPCMS_ICU_VERSION (U_ICU_VERSION_MAJOR_NUM * 100 + U_ICU_VERSION_MINOR_NUM) - - icu::Locale const &icu_loc = std::use_facet(locale_).get(); - - UErrorCode err=U_ZERO_ERROR; - - formatters_[numeric::format_normal].reset(icu::NumberFormat::createInstance(icu_loc,err)); - check(err); - - formatters_[numeric::format_scientific].reset(icu::NumberFormat::createScientificInstance(icu_loc,err)); - check(err); - - formatters_[numeric::format_percent].reset(icu::NumberFormat::createPercentInstance(icu_loc,err)); - check(err); - - formatters_[numeric::format_currency].reset(icu::NumberFormat::createCurrencyInstance(icu_loc,err)); - check(err); - - #if CPPCMS_ICU_VERSION >= 402 - - formatter_type fmt(icu::NumberFormat::createInstance(icu_loc,icu::NumberFormat::kIsoCurrencyStyle,err)); - - #else - - formatter_type fmt(static_cast(formatters_[numeric::format_currency]->clone())); - std::string iso_str = std::use_facet >(locale_).curr_symbol(); - icu::UnicodeString iso=impl::std_to_icu(iso_str,locale_); - fmt->setCurrency(iso.getBuffer(),err); - - #endif - - formatters_[numeric::format_iso_currency] = fmt; - check(err); - - formatters_[numeric::format_spellout].reset(new icu::RuleBasedNumberFormat(URBNF_SPELLOUT,icu_loc,err)); - check(err); - - formatters_[numeric::format_ordinal].reset(new icu::RuleBasedNumberFormat(URBNF_ORDINAL,icu_loc,err)); - check(err); - - #if CPPCMS_ICU_VERSION >= 402 - - formatters_[numeric::format_numbering].reset(new icu::RuleBasedNumberFormat(URBNF_NUMERING,icu_loc,err)); - - #else - - formatters_[numeric::format_numbering] = formatters_[numeric::format_normal]; - - #endif - - check(err); - - } - private: - void check(UErrorCode err) - { - if(U_FAILURE(err)) - throw cppcms_error(std::string("Failed to create NumericFormat") + u_errorName(err)); - } - formatter_type formatters_[numeric::format_count]; - std::locale locale_; - - }; - - -//// Proxy - - numeric::~numeric() - { - } - - numeric::numeric(numeric_impl *ptr,size_t refs) : std::locale::facet(refs), impl_(ptr) - { - } - - std::locale::id numeric::id; - - std::string numeric::format(format_type type,double value) const - { - return impl_->format(type,value); - } - - std::string numeric::format(format_type type,double value,int presision) const - { - return impl_->format(type,value,presision); - } - - std::string numeric::format(format_type type,long long value) const - { - return impl_->format(type,int64_t(value)); - } - std::string numeric::format(format_type type,unsigned long long value) const - { - return impl_->format(type,int64_t(value)); - } - - std::string numeric::format(format_type type,long value) const - { - return impl_->format(type,int64_t(value)); - } - std::string numeric::format(format_type type,unsigned long value) const - { - return impl_->format(type,int64_t(value)); - } - - std::string numeric::format(format_type type,int value) const - { - return impl_->format(type,int32_t(value)); - } - std::string numeric::format(format_type type,unsigned value) const - { - return impl_->format(type,int64_t(value)); - } - - bool numeric::parse(format_type type,std::string const &str,double &value) const - { - return impl_->parse(type,str,value); - } - bool numeric::parse(format_type type,std::string const &str,int &value) const - { - int32_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - bool numeric::parse(format_type type,std::string const &str,unsigned int &value) const - { - int64_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - - bool numeric::parse(format_type type,std::string const &str,long &value) const - { - int64_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - bool numeric::parse(format_type type,std::string const &str,unsigned long &value) const - { - int64_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - - bool numeric::parse(format_type type,std::string const &str,long long &value) const - { - int64_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - bool numeric::parse(format_type type,std::string const &str,unsigned long long &value) const - { - int64_t tmp; - if(!impl_->parse(type,str,tmp)) return false; - value=tmp; - return true; - } - - numeric *numeric::create(std::locale const &l) - { - return new numeric(new numeric_impl(l)); - } - -} // locale -} // cppcms diff --git a/locale_numeric.h b/locale_numeric.h deleted file mode 100644 index 458653b..0000000 --- a/locale_numeric.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef CPPCMS_LOCALE_NUMERIC_H -#define CPPCMS_LOCALE_NUMERIC_H -#include - -#include "defs.h" -#include "hold_ptr.h" - -namespace cppcms { - namespace locale { - - - class numeric_impl; - - class CPPCMS_API numeric : public std::locale::facet { - public: - - static std::locale::id id; - - static numeric *create(std::locale const &l); - - typedef enum { - format_normal = 0, ///< Normal, locale default formatting - format_scientific, ///< scientific format - format_percent, ///< percent format - format_currency, ///< currency format - format_iso_currency, ///< currency with ISO currency marker -- '$' -> 'USD' - format_spellout, ///< spellout number if rules availible - format_ordinal, ///< display ordinal format 1st, 2nd etc. - format_numbering, ///< display alternative number format Roman, Hebrew - - format_count, - } format_type; - - std::string format(format_type type,double value) const; - std::string format(format_type type,double value,int presision) const; - - std::string format(format_type type,long long value) const; - std::string format(format_type type,unsigned long long value) const; - - std::string format(format_type type,long value) const; - std::string format(format_type type,unsigned long value) const; - - std::string format(format_type type,int value) const; - std::string format(format_type type,unsigned value) const; - - bool parse(format_type type,std::string const &,double &value) const; - - bool parse(format_type type,std::string const &,int &value) const; - bool parse(format_type type,std::string const &,unsigned int &value) const; - - bool parse(format_type type,std::string const &,long &value) const; - bool parse(format_type type,std::string const &,unsigned long &value) const; - - bool parse(format_type type,std::string const &,long long &value) const; - bool parse(format_type type,std::string const &,unsigned long long &value) const; - - private: - numeric(numeric_impl *,size_t refs=0); - virtual ~numeric(); - - util::hold_ptr impl_; - - }; - } -} - -#endif diff --git a/locale_pool.cpp b/locale_pool.cpp deleted file mode 100644 index 6692f54..0000000 --- a/locale_pool.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#define CPPCMS_SOURCE -#include "locale_pool.h" -#include "cppcms_error.h" -#include "locale_gettext.h" -#include "locale_info.h" -#include "locale_charset.h" -#include "locale_convert.h" -#include "locale_icu_locale.h" -#include "encoding.h" -#include "json.h" -#include -#include -#include - -namespace cppcms { namespace locale { - -struct pool::data { - std::vector domains; - typedef std::map > locales_type; - locales_type locales; - std::string path; - std::locale fallback; - - data() : fallback(std::locale::classic()) {} -}; - -pool::pool(json::value const &settings) : - d(new data) -{ - d->path=settings.get("locale.gettext_path","/usr/local/locale"); - d->domains=settings.get("locale.gettext_domains",std::vector()); - std::string default_domain; - if(!d->domains.empty()) - default_domain=d->domains.front(); - default_domain=settings.get("locale.default_gettext_domain",default_domain); - std::vector const &locales=settings.get("locale.locales",std::vector()); - - intrusive_ptr validators(new encoding::validators_set); - - for(unsigned i=0;i gt(new gettext()); - - for(unsigned i=0;i < d->domains.size();i++) { - gt->load(name,d->path,d->domains[i]); - } - gt->set_default_domain(default_domain); - - boost::shared_ptr base; - - try { - base.reset(new std::locale(name.c_str())); - } - catch(std::runtime_error const &e) { - base.reset(new std::locale("C")); - } - - boost::shared_ptr combined(new std::locale(*base,gt.release())); - base=combined; - - std::auto_ptr inf(new info(name)); - std::string enc=inf->encoding(); - combined.reset(new std::locale(*base,inf.release())); - base=combined; - combined.reset(new std::locale(*base,new charset(enc,validators))); - base=combined; -#ifdef HAVE_ICU - combined.reset(new std::locale(*base,new icu_locale(name))); - base=combined; -#endif - combined.reset(new std::locale(*base,convert::create(*base))); - base=combined; - - d->locales[name]=combined; - } -} - -std::locale const &pool::get(std::string const &name) const -{ - data::locales_type::const_iterator p; - if((p=d->locales.find(name))==d->locales.end()) { - return d->fallback; - } - return *p->second; -} - - -pool::~pool() -{ -} - - - - -} } // cppcms::locale diff --git a/locale_pool.h b/locale_pool.h deleted file mode 100644 index 8b407fc..0000000 --- a/locale_pool.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef CPPCMS_LOCALE_POOL_H -#define CPPCMS_LOCALE_POOL_H - - -#include "defs.h" -#include "hold_ptr.h" -#include "noncopyable.h" -#include -#include - - -namespace cppcms { -namespace json { class value; } - -namespace locale { - class CPPCMS_API pool : util::noncopyable { - public: - pool(json::value const &conf); - ~pool(); - - std::locale const &get(std::string const &name) const; - - private: - struct data; - util::hold_ptr d; - }; - -} // locale -} // cppcms - - -#endif diff --git a/localization.h b/localization.h new file mode 100644 index 0000000..504cfc5 --- /dev/null +++ b/localization.h @@ -0,0 +1,13 @@ +#ifndef CPPCMS_LOCALE_H +#define CPPCMS_LOCALE_H +#include + +namespace cppcms { + namespace locale { + using namespace boost::locale; + // Get there all of boost locale + } +} + + +#endif diff --git a/service.cpp b/service.cpp index 1ce5dcd..c555f0d 100644 --- a/service.cpp +++ b/service.cpp @@ -1,4 +1,5 @@ #define CPPCMS_SOURCE +#include "asio_config.h" #include "service.h" #include "service_impl.h" #include "applications_pool.h" @@ -9,11 +10,10 @@ #include "scgi_api.h" #include "http_api.h" #include "fastcgi_api.h" -#include "locale_pool.h" #include "internal_file_server.h" #include "json.h" +#include "localization.h" -#include "asio_config.h" #ifdef CPPCMS_POSIX #include @@ -24,6 +24,7 @@ #include #include + namespace cppcms { service::service(json::value const &v) : @@ -241,7 +242,6 @@ void service::shutdown() void service::run() { - locale_pool(); start_acceptor(); if(settings().get("file_server.enable",false)) @@ -426,15 +426,58 @@ void service::stop() impl_->get_io_service().stop(); } -locale::pool const &service::locale_pool() +locale::generator const &service::generator() { - if(!impl_->locale_pool_.get()) { - impl_->locale_pool_.reset(new locale::pool(settings())); - + if(impl_->locale_generator_.get()) + return *impl_->locale_generator_.get(); + + typedef std::vector vstr_type; + impl_->locale_generator_.reset(new locale::generator()); + locale::generator &gen= *impl_->locale_generator_; + gen.characters(locale::char_facet); + std::string enc = settings().get("localization.encoding",""); + + if(!enc.empty()) + gen.octet_encoding(enc); + + vstr_type paths= settings().get("localization.messages.path",vstr_type()); + vstr_type domains = settings().get("localization.messages.domains",vstr_type()); + + if(!paths.empty() && !domains.empty()) { + unsigned i; + for(i=0;idefault_locale_=gen(""); + } + else { + for(unsigned i=0;idefault_locale_=gen(locales[0]); } - return *impl_->locale_pool_; + + return *impl_->locale_generator_.get(); + +} + +std::locale service::locale() +{ + generator(); + return impl_->default_locale_; +} +std::locale service::locale(std::string const &name) +{ + return generator().get(name); } + namespace impl { service::service() : io_service_(new boost::asio::io_service()), @@ -452,7 +495,7 @@ namespace impl { // applications pool should be destroyed after // io_service, because soma apps may try unregister themselfs applications_pool_.reset(); - locale_pool_.reset(); + locale_generator_.reset(); settings_.reset(); } diff --git a/service.h b/service.h index bddba2c..a04bf4b 100644 --- a/service.h +++ b/service.h @@ -5,19 +5,18 @@ #include "noncopyable.h" #include "hold_ptr.h" #include "callback0.h" +#include - +namespace boost { namespace locale { class generator; }} namespace cppcms { + namespace locale { using namespace boost::locale; } namespace impl { class service; } class applications_pool; class thread_pool; - namespace locale { - class pool; - } namespace json { class value; } @@ -35,7 +34,10 @@ namespace cppcms { cppcms::applications_pool &applications_pool(); cppcms::thread_pool &thread_pool(); json::value const &settings(); - cppcms::locale::pool const &locale_pool(); + + locale::generator const &generator(); + std::locale locale(); + std::locale locale(std::string const &name); cppcms::impl::service &impl(); diff --git a/service_impl.h b/service_impl.h index 8cee7d1..1d88d56 100644 --- a/service_impl.h +++ b/service_impl.h @@ -3,6 +3,7 @@ #include "asio_config.h" #include "json.h" +#include "localization.h" #include namespace cppcms { @@ -33,7 +34,8 @@ namespace impl { std::auto_ptr settings_; std::auto_ptr applications_pool_; std::auto_ptr thread_pool_; - std::auto_ptr locale_pool_; + std::auto_ptr locale_generator_; + std::locale default_locale_; #ifdef CPPCMS_WIN32 typedef SOCKET native_socket_type; diff --git a/utf8_iterator.cpp b/utf8_iterator.cpp deleted file mode 100644 index cf8c3fc..0000000 --- a/utf8_iterator.cpp +++ /dev/null @@ -1,446 +0,0 @@ -#define CPPCMS_SOURCE -#include "utf8_iterator.h" -#include "config.h" -#include "utf_iterator.h" -#include "noncopyable.h" -#include "locale_icu_locale.h" - -#ifdef HAVE_ICU -#include -#include -#include -#endif -#include -#include - - -namespace cppcms { namespace utf8 { namespace details { -#ifdef HAVE_ICU - - - /// Implementation - - class break_iterator_impl : util::noncopyable { - public: - break_iterator_impl(char const *b,char const *e,icu::BreakIterator *it,UText *text = 0,size_t pos = (size_t)(-1)) : - begin_(b), - end_(e), - br_(it), - text_(text) - { - if(text_ == 0) { - UErrorCode status = U_ZERO_ERROR; - text_=utext_openUTF8(0,begin_,end_-begin_,&status); - - if(!U_SUCCESS(status)) { - delete br_; - throw std::runtime_error(u_errorName(status)); - } - } - - UErrorCode status = U_ZERO_ERROR; - br_->setText(text_,status); - - if(!U_SUCCESS(status)) { - utext_close(text_); - delete br_; - throw std::runtime_error(u_errorName(status)); - } - - if(pos!=(size_t)(-1)) - br_->isBoundary(pos); - else - first(); - } - ~break_iterator_impl() - { - utext_close(text_); - delete br_; - } - break_iterator_impl *clone() const - { - UErrorCode status = U_ZERO_ERROR; - UText *text=utext_clone(0,text_,false,true,&status); - if(!U_SUCCESS(status)) { - throw std::runtime_error(u_errorName(status)); - } - return new break_iterator_impl(begin_,end_,br_->clone(),text,br_->current()); - } - - bool equal(break_iterator_impl const &other) const - { - return *br_ == *other.br_; - } - bool less(break_iterator_impl const &other) const - { - return br_->current() < other.br_->current(); - } - - char const *to_che(int32_t n) const - { - if(n == icu::BreakIterator::DONE || begin_ + n > end_) - return end_; - return begin_ + n; - } - - char const *to_chb(int32_t n) const - { - if(n == icu::BreakIterator::DONE || begin_ + n < begin_) - return begin_; - return begin_ + n; - } - - char const *curr() const - { - return to_che(br_->current()); - } - char const *first() - { - return to_che(br_->first()); - } - - char const *next() - { - return to_che(br_->next()); - } - - char const *last() - { - return to_chb(br_->last()); - } - char const *prev() - { - return to_chb(br_->previous()); - } - void curr(char const *pos) - { - br_->isBoundary(pos - begin_); - } - char const *following(char const *pos) - { - return to_che(br_->following(pos - begin_)); - } - char const *preceding(char const *pos) - { - return to_chb(br_->preceding(pos - begin_)); - } - - char const *move(int n) - { - if(n>0) - return to_che(br_->next(n)); - else - return to_chb(br_->next(n)); - } - - char const *begin_; - char const *end_; - icu::BreakIterator *br_; - UText *text_; - }; - - - /// Actual Iterator - - - namespace { - icu::Locale const &icu_locale(std::locale const &l) - { - try { - return std::use_facet(l).get(); - } - catch(std::bad_cast const &e) { - return icu::Locale::getDefault(); - } - } - icu::BreakIterator *create_iterator( std::locale const &l, - icu::BreakIterator *(*factory)(icu::Locale const &l,UErrorCode &err)) - { - icu::Locale const &loc=icu_locale(l); - - UErrorCode status = U_ZERO_ERROR; - icu::BreakIterator *br = factory(loc,status); - if(!U_SUCCESS(status)) { - delete br; - throw std::runtime_error(u_errorName(status)); - } - return br; - } - } - - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,character_tag tag) : - impl_(new break_iterator_impl(begin,end,create_iterator(loc, &icu::BreakIterator::createCharacterInstance))) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,word_tag tag) : - impl_(new break_iterator_impl(begin,end,create_iterator(loc, &icu::BreakIterator::createWordInstance))) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,line_tag tag) : - impl_(new break_iterator_impl(begin,end,create_iterator(loc, &icu::BreakIterator::createLineInstance))) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,sentence_tag tag) : - impl_(new break_iterator_impl(begin,end,create_iterator(loc, &icu::BreakIterator::createSentenceInstance))) - { - } - - -#else /// NO ICU - - class break_iterator_impl { - codepoint_iterator current_; - public: - typedef enum { charrecter, word, sentence, line } iter_type; - - iter_type type_; - - char const *begin_,*end_; - std::ctype const *wfacet_; - std::ctype const *facet_; - - - break_iterator_impl *clone() const - { - return new break_iterator_impl(*this); - } - - break_iterator_impl(char const *begin,char const *end,std::locale const &l,iter_type type) : - current_(begin,end,l,code_point_tag()), - type_(type), - begin_(begin), - end_(end), - wfacet_(0), - facet_(0) - { - if(std::has_facet >(l)) { - wfacet_ = & std::use_facet >(l); - } - else { - facet_ = & std::use_facet >(l);; - } - } - - bool is(std::ctype_base::mask m) - { - char const *ptr=curr(); - if(ptr >= end_) - return false; - if(wfacet_) { - wchar_t v=utf8::next(ptr,end_); - return wfacet_->is(m,v); - } - else { - return facet_->is(m,*ptr); - } - } - bool is_alpha() - { - return is(std::ctype_base::alpha); - } - bool is_sentence_break() - { - char const *ptr=curr(); - if(ptr >= end_) - return false; - if(wfacet_) { - wchar_t v=utf8::next(ptr,end_); - static const std::basic_string breakers(L".;?!"); - return breakers.find(v)!=std::basic_string::npos; - } - else { - char v=*ptr; - static const std::string breakers(".;?!"); - return breakers.find(v)!=std::string::npos; - } - } - bool is_space() - { - return is(std::ctype_base::space); - } - - bool equal(break_iterator_impl const &other) const - { - return current_.equal(other.current_); - } - bool less(break_iterator_impl const &other) const - { - return current_.less(other.current_); - } - - char const *curr() const - { - return current_.curr(); - } - char const *next() - { - switch(type_) { - case charrecter: - return current_.next(); - case word: - do - current_.next(); - while(current_.curr() < end_ && is_alpha()); - return curr(); - case sentence: - while(current_.curr() < end_ && !is_sentence_break()) - current_.next(); - return current_.next(); - case line: - do - current_.next(); - while(current_.curr() < end_ && !is_space()); - return curr(); - default: throw std::runtime_error("Internal Error in " __FILE__ ); - } - } - char const *prev() - { - switch(type_) { - case charrecter: - return current_.prev(); - case word: - do - current_.prev(); - while(current_.curr() > begin_ && is_alpha()); - return curr(); - case sentence: - do - current_.prev(); - while(current_.curr() > begin_ && !is_sentence_break()); - return current_.curr(); - - case line: - do - current_.prev(); - while(current_.curr() > begin_ && !is_space()); - return curr(); - default: throw std::runtime_error("Internal Error in " __FILE__ ); - } - } - char const *first() - { - return current_.first(); - } - char const *last() - { - return current_.last(); - } - void curr(char const *iter) - { - switch(type_) { - case charrecter: current_.curr(iter); break; - default: - current_.curr(); - next(); - prev(); - } - } - char const *following(char const *pos) - { - switch(type_) { - case charrecter: return current_.following(pos); - default: - current_.curr(); - return next(); - } - } - - char const *preceding(char const *pos) - { - switch(type_) { - case charrecter: return current_.preceding(pos); - default: - current_.curr(); - return prev(); - } - } - char const *move(int steps) - { - while(steps > 0) { - next(); - steps --; - } - while(steps < 0) { - prev(); - steps ++; - } - return curr(); - } - }; - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,character_tag tag) : - impl_(new break_iterator_impl(begin,end,loc,break_iterator_impl::charrecter)) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,word_tag tag) : - impl_(new break_iterator_impl(begin,end,loc,break_iterator_impl::word)) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,line_tag tag) : - impl_(new break_iterator_impl(begin,end,loc,break_iterator_impl::line)) - { - } - - template<> - break_iterator::break_iterator(char const *begin,char const *end,std::locale const &loc,sentence_tag tag) : - impl_(new break_iterator_impl(begin,end,loc,break_iterator_impl::sentence)) - { - } - - -#endif - - break_iterator::break_iterator() - { - } - break_iterator::~break_iterator() - { - } - break_iterator::break_iterator(break_iterator const &other) : impl_(other.impl_) - { - } - break_iterator const &break_iterator::operator=(break_iterator const &other) - { - impl_ = other.impl_; - return *this; - } - bool break_iterator::equal(break_iterator const &other) const - { - if(impl_.get() && other.impl_.get()) - return impl_->equal(*other.impl_); - if(!impl_.get() && !other.impl_.get()) - return true; - return false; - } - bool break_iterator::less(break_iterator const &other) const - { - if(impl_.get() && other.impl_.get()) - return impl_->less(*other.impl_); - return false; - } - - char const *break_iterator::move(int n) { return impl_->move(n); } - char const *break_iterator::next() { return impl_->next(); } - char const *break_iterator::first() { return impl_->first(); } - char const *break_iterator::prev() { return impl_->prev(); } - char const *break_iterator::last() { return impl_->last(); } - char const *break_iterator::curr() const { return impl_->curr(); } - char const *break_iterator::following(char const *p) { return impl_->following(p); } - char const *break_iterator::preceding(char const *p) { return impl_->preceding(p); } - void break_iterator::curr(char const *p) { impl_->curr(p); } - -}}} // cppcms::utf8::details diff --git a/utf8_iterator.h b/utf8_iterator.h deleted file mode 100644 index 638b683..0000000 --- a/utf8_iterator.h +++ /dev/null @@ -1,432 +0,0 @@ -#ifndef CPPCMS_UTF8_ITERATOR_H -#define CPPCMS_UTF8_ITERATOR_H - -#include "defs.h" -#include "clone_ptr.h" -#include -#include - -namespace cppcms { - - namespace utf8 { - - namespace details { - - struct code_point_tag {}; - struct character_tag {}; - struct word_tag {}; - struct sentence_tag {}; - struct line_tag {}; - - - template - struct string_traits; - - template - struct string_traits &> - { - typedef typename std::basic_string string_type; - typedef typename string_type::iterator iterator_type; - typedef string_type *pointer_type; - }; - - template - struct string_traits const &> - { - typedef typename std::basic_string string_type; - typedef typename string_type::const_iterator iterator_type; - typedef string_type const *pointer_type; - }; - - class codepoint_iterator { - public: - codepoint_iterator() : begin_(0), end_(0), current_(0) - { - } - template - codepoint_iterator(char const *begin,char const *end,std::locale const &loc,Tag t); - - bool equal(codepoint_iterator const &other) const - { - return current_ == other.current_; - } - - bool less(codepoint_iterator const &other) const - { - return current_ < other.current_; - } - - char const *curr() const - { - return current_; - } - - char const *next() - { - if(current_ >= end_) - return current_; - - unsigned char tmp=*current_++; - if((tmp & 0x80) == 0) - return current_; - while(current_ < end_ && ((unsigned char)(*current_) & 0xC0) == 0x80) - current_ ++; - return current_; - - } - - char const *prev() - { - while(current_ > begin_) { - unsigned char c = * (--current_); - if( (c & 0xC0) != 0x80 )// 10xxxxxx -- utf8 part - break; - } - return current_; - } - - char const *first() - { - current_ = begin_; - return current_; - } - - char const *last() - { - current_ = end_; - return current_; - } - - void curr(char const *iter) - { - if(iter <= begin_) { - current_ = begin_; - } - else if(iter >= end_) { - current_ = end_; - } - else { - current_ = iter; - } - - while( current_ != end_ && (((unsigned char)(*current_)) & 0xC0) == 0x80) - current_++; - } - - char const *following(char const *pos) - { - curr(pos); - return next(); - } - - char const *preceding(char const *pos) - { - curr(pos); - return prev(); - } - char const *move(int steps) - { - while(steps > 0) { - next(); - steps --; - } - while(steps < 0) { - prev(); - steps ++; - } - return curr(); - - } - - private: - char const *begin_; - char const *end_; - char const *current_; - }; - - template<> - inline codepoint_iterator::codepoint_iterator( char const *begin, - char const *end, - std::locale const &loc, - code_point_tag unused) : - begin_(begin), - end_(end), - current_(begin) - { - } - - class break_iterator_impl; - - class CPPCMS_API break_iterator { - public: - break_iterator(); - template - break_iterator(char const *begin,char const *end,std::locale const &loc,Tag t); - break_iterator(break_iterator const &); - break_iterator const &operator = (break_iterator const &); - ~break_iterator(); - - bool equal(break_iterator const &other) const; - bool less(break_iterator const &other) const; - - char const *curr() const; - char const *next(); - char const *prev(); - char const *first(); - char const *last(); - void curr(char const *iter); - char const *following(char const *pos); - char const *preceding(char const *pos); - char const *move(int n); - private: - util::clone_ptr impl_; - - }; - - template<> - CPPCMS_API break_iterator::break_iterator( char const *begin, - char const *end, - std::locale const &l, - character_tag tag); - template<> - CPPCMS_API break_iterator::break_iterator( char const *begin, - char const *end, - std::locale const &l, - word_tag tag); - template<> - CPPCMS_API break_iterator::break_iterator( char const *begin, - char const *end, - std::locale const &l, - sentence_tag tag); - template<> - CPPCMS_API break_iterator::break_iterator( char const *begin, - char const *end, - std::locale const &l, - line_tag tag); - - } // details - - - - - template - class base_iterator { - public: - typedef typename details::string_traits::iterator_type iterator_type; - typename details::string_traits::pointer_type pointer_type; - - - bool operator==(base_iterator const &other) const - { - return walker_.equal(other.walker_); - } - - bool operator!=(base_iterator const &other) const - { - return !walker_.equal(other.walker_); - } - - bool operator< (base_iterator const &other) const - { - return walker_.less(other.walker_); - } - - bool operator> (base_iterator const &other) const - { - return other.walker_.less(walker_); - } - - bool operator>= (base_iterator const &other) const - { - return !walker_.less(other.walker_); - } - - bool operator<= (base_iterator const &other) const - { - return !other.walker_.less(walker_); - } - - base_iterator(StringType str,std::locale const &l = std::locale()) : - walker_(&*str.begin(),&*str.end(),l,TagType()), - begin_(str.begin()), - cbegin_(str.data()) - { - } - - base_iterator(iterator_type begin,iterator_type end,std::locale const &l = std::locale()) : - walker_(&*begin,&*end,l,TagType()), - begin_(begin), - cbegin_(&*begin) - { - } - - base_iterator(){} - - iterator_type operator*() const - { - return to_iterator(walker_.curr()); - } - - iterator_type next() - { - return to_iterator(walker_.next()); - - } - - iterator_type prev() - { - return to_iterator(walker_.prev()); - } - - iterator_type first() - { - return to_iterator(walker_.first()); - } - - iterator_type last() - { - return to_iterator(walker_.last()); - } - - iterator_type to_iterator(char const *ptr) const - { - return begin_ + (ptr - cbegin_); - } - - - base_iterator const &operator=(iterator_type iter) - { - walker_.curr(cbegin_ + (iter - begin_)); - return *this; - } - - iterator_type following(iterator_type pos) - { - return to_iterator(walker_.following(cbegin_ + (pos - begin_))); - } - - iterator_type preceding(iterator_type pos) - { - return to_iterator(walker_.preceding(cbegin_ + (pos - begin_))); - } - - base_iterator operator++(int unused) - { - base_iterator tmp(*this); - next(); - return tmp; - } - - base_iterator &operator++() - { - next(); - return *this; - } - - base_iterator operator--(int unused) - { - base_iterator tmp(*this); - prev(); - return tmp; - } - - base_iterator &operator--() - { - prev(); - return *this; - } - - base_iterator const &operator+=(int n) - { - walker_.move(n); - return *this; - } - base_iterator const &operator-=(int n) - { - walker_.move(-n); - return *this; - } - - private: - WalkerType walker_; - iterator_type begin_; - char const *cbegin_; - }; - - template - base_iterator operator+( - base_iterator const &iter, - int n) - { - base_iterator tmp=iter; - tmp+=n; - return tmp; - } - - template - base_iterator operator+( - int n, - base_iterator const &iter) - { - base_iterator tmp=iter; - tmp+=n; - return tmp; - } - - template - base_iterator operator-( - base_iterator const &iter, - int n) - { - base_iterator tmp=iter; - tmp-=n; - return tmp; - } - - template - base_iterator operator-( - base_iterator const &a, - base_iterator const &b) - { - int n=0; - if(a > b) { - base_iterator tmp=b; - int n = 0; - while(b < a) { - ++b; - ++n; - } - } - else if( b > a ) { - base_iterator tmp=a; - int n = 0; - while(b > a) { - ++a; - --n; - } - } - return n; - } - - typedef base_iterator code_point_iterator; - typedef base_iterator const_code_point_iterator; - typedef base_iterator character_iterator; - typedef base_iterator const_character_iterator; - - typedef base_iterator word_iterator; - typedef base_iterator const_word_iterator; - - typedef base_iterator sentence_iterator; - typedef base_iterator const_sentence_iterator; - - typedef base_iterator line_iterator; - typedef base_iterator const_line_iterator; - - } // utf8 - -} // cppcms - - - - -#endif