/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #ifndef CPPCMS_FILTERS_H #define CPPCMS_FILTERS_H #include #include #include #include #include #include #include #include #include #include namespace cppcms { /// /// \brief set gettext domain id withing specific scope /// /// \ver{v1_2} class CPPCMS_API translation_domain_scope : public booster::noncopyable { public: /// /// Get numeric id for the domain /// static int domain_id(std::ostream &out,std::string const &domain); /// /// Set domain id on the stream and save previous one to restore in the destructor /// translation_domain_scope(std::ostream &output,int domain_id); /// /// Set domain on the stream and save previous one to restore in the destructor /// translation_domain_scope(std::ostream &output,std::string const &domain); /// /// Restrore domain /// ~translation_domain_scope(); private: void set_and_save(int id); struct _data; booster::hold_ptr<_data> d; std::ostream *output_; int prev_id_; }; /// /// /// \brief This namespace various filters that can be used in templates for filtering data /// /// namespace filters { /// /// \brief A special proxy object for writing any object to a std::ostream /// /// This is special object that is used to store a reference to any other object /// that can be written to std::ostream, giving as easy way to write a filter for /// any object that can be written to stream /// class CPPCMS_API streamable { public: /// \cond INTERNAL typedef void (*to_stream_type)(std::ostream &,void const *ptr); typedef std::string (*to_string_type)(std::ios &,void const *ptr); /// \endcond streamable(); ~streamable(); streamable(streamable const &other); streamable const &operator=(streamable const &other); /// /// Create a streamable object from arbitrary object that can be written to stream /// template streamable(S const &ptr) { void const *p=&ptr; to_stream_type s1=&to_stream; to_string_type s2=&to_string; std::type_info const *info=&typeid(S); set(p,s1,s2,info); } /// /// Get the reference to "streamed object", throws std::bad_cast if the type is wrong /// template T const &get() const { if(typeid(T) != type()) throw std::bad_cast(); T const *object=reinterpret_cast(ptr_); return *object; } /// /// Create a streamable object from C string /// streamable(char const *ptr); /// /// Write the object to output stream /// void operator()(std::ostream &output) const; /// /// Convert the object to string using settings and locale in ios class /// std::string get(std::ios &ios) const; private: void set(void const *ptr,to_stream_type f1,to_string_type f2,std::type_info const *type); template static void to_stream(std::ostream &out,void const *ptr) { T const *object=reinterpret_cast(ptr); out << *object; } template static std::string to_string(std::ios &out,void const *ptr) { T const *object=reinterpret_cast(ptr); std::ostringstream oss; oss.copyfmt(out); oss << *object; return oss.str(); } std::type_info const &type() const; private: void const *ptr_; to_stream_type to_stream_; to_string_type to_string_; std::type_info const *type_; }; /// /// \brief we can specialize for string because std::string get(ios &) const may be much more /// efficient. /// template<> CPPCMS_API streamable::streamable(std::string const &str); /// /// \brief Output filter to_upper /// /// Convert text to upper case according to locale /// class CPPCMS_API to_upper { public: to_upper(); ~to_upper(); to_upper(to_upper const &); to_upper const &operator=(to_upper const &other); void operator()(std::ostream &out) const; to_upper(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,to_upper const &obj) { obj(out); return out; } /// /// \brief Output filter to_lower /// /// Convert text to lower case according to locale /// class CPPCMS_API to_lower { public: to_lower(); ~to_lower(); to_lower(to_lower const &); to_lower const &operator=(to_lower const &other); void operator()(std::ostream &out) const; to_lower(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,to_lower const &obj) { obj(out); return out; } /// /// \brief Output filter to_title /// /// Convert text to title case according to locale /// class CPPCMS_API to_title { public: to_title(); ~to_title(); to_title(to_title const &); to_title const &operator=(to_title const &other); void operator()(std::ostream &out) const; to_title(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,to_title const &obj) { obj(out); return out; } /// /// \brief Output filter escape /// /// Escape text for HTML -- make text safe /// class CPPCMS_API escape { public: escape(); ~escape(); escape(escape const &); escape const &operator=(escape const &other); void operator()(std::ostream &out) const; escape(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,escape const &obj) { obj(out); return out; } /// /// \brief Output filter escape /// /// Escape text for JavaScript string -- make text safe to include between quotes in the JavaScript or JSON code /// /// \ver{v1_2} class CPPCMS_API jsescape { public: jsescape(); ~jsescape(); jsescape(jsescape const &); jsescape const &operator=(jsescape const &other); void operator()(std::ostream &out) const; jsescape(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,jsescape const &obj) { obj(out); return out; } /// /// \brief Output filter urlencode /// /// Perform urlencoding(percent encoding) of the text /// class CPPCMS_API urlencode { public: urlencode(); ~urlencode(); urlencode(urlencode const &); urlencode const &operator=(urlencode const &other); void operator()(std::ostream &out) const; urlencode(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,urlencode const &obj) { obj(out); return out; } /// /// \brief Output filter base64_urlencode /// /// Convert text to base64 format that is friendly to URL. /// class CPPCMS_API base64_urlencode { public: base64_urlencode(); ~base64_urlencode(); base64_urlencode(base64_urlencode const &); base64_urlencode const &operator=(base64_urlencode const &other); void operator()(std::ostream &out) const; base64_urlencode(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,base64_urlencode const &obj) { obj(out); return out; } /// /// \brief Output filter raw /// /// Filter that does nothing /// class CPPCMS_API raw { public: raw(); ~raw(); raw(raw const &); raw const &operator=(raw const &other); void operator()(std::ostream &out) const; raw(streamable const &obj); private: streamable obj_; struct _data; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,raw const &obj) { obj(out); return out; } /// /// \brief Formats date to the stream, date is represented as number - POSIX time, a plain number /// class CPPCMS_API date { public: date(); date(date const &other); date const &operator=(date const &other); ~date(); /// /// Create date filter that formats current local-time date using POSIX time representation \a time /// date(streamable const &time); /// /// Create date filter that formats current date using POSIX time representation \a time, /// in a timezone \a timezone /// date(streamable const &time,std::string const &timezone); void operator()(std::ostream &out) const; private: struct _data; streamable time_; std::string tz_; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,date const &obj) { obj(out); return out; } /// /// \brief Format local time to ouput stream /// /// Formats time to the stream, time is represented as number /// class CPPCMS_API time { public: time(); time(time const &other); time const &operator=(time const &other); ~time(); /// /// Create time filter that formats current local-time time using POSIX time representation \a t /// time(streamable const &t); /// /// Create time filter that formats current time using POSIX time representation \a t, /// in a timezone \a timezone /// time(streamable const &time,std::string const &timezone); void operator()(std::ostream &out) const; private: struct _data; streamable time_; std::string tz_; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,time const &obj) { obj(out); return out; } /// /// \brief Format date and time to ouput stream /// /// Formats date and time to the stream, date and time is represented as time_t /// class CPPCMS_API datetime { public: datetime(); datetime(datetime const &other); datetime const &operator=(datetime const &other); ~datetime(); /// /// Create date and time filter that formats current local-time date and time using POSIX time representation \a t /// datetime(streamable const &t); /// /// Create date and time filter that formats current date and time using POSIX time representation \a t, /// in a timezone \a timezone /// datetime(streamable const &time,std::string const &timezone); void operator()(std::ostream &out) const; private: struct _data; streamable time_; std::string tz_; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,datetime const &obj) { obj(out); return out; } /// /// \brief Custom time formating filter /// /// Formats date and time to the stream, date and time is represented as time_t /// class CPPCMS_API strftime { public: strftime(); strftime(strftime const &other); strftime const &operator=(strftime const &other); ~strftime(); /// /// Create date and time filter that formats current local-time date and time using POSIX time representation \a t /// according to strftime like format \a fmt, see booster::locale::as::ftime or cppcms::locale::as::ftime for details /// (depending on your localization backend) /// strftime(streamable const &t,std::string const &fmt); /// /// Create date and time filter that formats current date and time using POSIX time representation \a t, /// in a timezone \a timezone /// according to strftime like format \a fmt, see booster::locale::as::ftime or cppcms::locale::as::ftime for details /// (depending on your localization backend) /// strftime(streamable const &time,std::string const &timezone,std::string const &fmt); void operator()(std::ostream &out) const; private: struct _data; streamable time_; std::string tz_; std::string format_; booster::copy_ptr<_data> d; }; inline std::ostream &operator<<(std::ostream &out,strftime const &obj) { obj(out); return out; } using locale::translate; using locale::format; } /////////////////////////////// } #endif