ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

530 lines
13 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_FILTERS_H
  9. #define CPPCMS_FILTERS_H
  10. #include <locale>
  11. #include <typeinfo>
  12. #include <sstream>
  13. #include <vector>
  14. #include <iostream>
  15. #include <cppcms/defs.h>
  16. #include <booster/copy_ptr.h>
  17. #include <booster/hold_ptr.h>
  18. #include <booster/noncopyable.h>
  19. #include <cppcms/localization.h>
  20. namespace cppcms {
  21. ///
  22. /// \brief set gettext domain id withing specific scope
  23. ///
  24. /// \ver{v1_2}
  25. class CPPCMS_API translation_domain_scope : public booster::noncopyable {
  26. public:
  27. ///
  28. /// Get numeric id for the domain
  29. ///
  30. static int domain_id(std::ostream &out,std::string const &domain);
  31. ///
  32. /// Set domain id on the stream and save previous one to restore in the destructor
  33. ///
  34. translation_domain_scope(std::ostream &output,int domain_id);
  35. ///
  36. /// Set domain on the stream and save previous one to restore in the destructor
  37. ///
  38. translation_domain_scope(std::ostream &output,std::string const &domain);
  39. ///
  40. /// Restrore domain
  41. ///
  42. ~translation_domain_scope();
  43. private:
  44. void set_and_save(int id);
  45. struct _data;
  46. booster::hold_ptr<_data> d;
  47. std::ostream *output_;
  48. int prev_id_;
  49. };
  50. ///
  51. ///
  52. /// \brief This namespace various filters that can be used in templates for filtering data
  53. ///
  54. ///
  55. namespace filters {
  56. ///
  57. /// \brief A special proxy object for writing any object to a std::ostream
  58. ///
  59. /// This is special object that is used to store a reference to any other object
  60. /// that can be written to std::ostream, giving as easy way to write a filter for
  61. /// any object that can be written to stream
  62. ///
  63. class CPPCMS_API streamable {
  64. public:
  65. /// \cond INTERNAL
  66. typedef void (*to_stream_type)(std::ostream &,void const *ptr);
  67. typedef std::string (*to_string_type)(std::ios &,void const *ptr);
  68. /// \endcond
  69. streamable();
  70. ~streamable();
  71. streamable(streamable const &other);
  72. streamable const &operator=(streamable const &other);
  73. ///
  74. /// Create a streamable object from arbitrary object that can be written to stream
  75. ///
  76. template<typename S>
  77. streamable(S const &ptr)
  78. {
  79. void const *p=&ptr;
  80. to_stream_type s1=&to_stream<S>;
  81. to_string_type s2=&to_string<S>;
  82. std::type_info const *info=&typeid(S);
  83. set(p,s1,s2,info);
  84. }
  85. ///
  86. /// Get the reference to "streamed object", throws std::bad_cast if the type is wrong
  87. ///
  88. template<typename T>
  89. T const &get() const
  90. {
  91. if(typeid(T) != type())
  92. throw std::bad_cast();
  93. T const *object=reinterpret_cast<T const *>(ptr_);
  94. return *object;
  95. }
  96. ///
  97. /// Create a streamable object from C string
  98. ///
  99. streamable(char const *ptr);
  100. ///
  101. /// Write the object to output stream
  102. ///
  103. void operator()(std::ostream &output) const;
  104. ///
  105. /// Convert the object to string using settings and locale in ios class
  106. ///
  107. std::string get(std::ios &ios) const;
  108. private:
  109. void set(void const *ptr,to_stream_type f1,to_string_type f2,std::type_info const *type);
  110. template<typename T>
  111. static void to_stream(std::ostream &out,void const *ptr)
  112. {
  113. T const *object=reinterpret_cast<T const *>(ptr);
  114. out << *object;
  115. }
  116. template<typename T>
  117. static std::string to_string(std::ios &out,void const *ptr)
  118. {
  119. T const *object=reinterpret_cast<T const *>(ptr);
  120. std::ostringstream oss;
  121. oss.copyfmt(out);
  122. oss << *object;
  123. return oss.str();
  124. }
  125. std::type_info const &type() const;
  126. private:
  127. void const *ptr_;
  128. to_stream_type to_stream_;
  129. to_string_type to_string_;
  130. std::type_info const *type_;
  131. };
  132. ///
  133. /// \brief we can specialize for string because std::string get(ios &) const may be much more
  134. /// efficient.
  135. ///
  136. template<>
  137. CPPCMS_API streamable::streamable(std::string const &str);
  138. ///
  139. /// \brief Output filter to_upper
  140. ///
  141. /// Convert text to upper case according to locale
  142. ///
  143. class CPPCMS_API to_upper {
  144. public:
  145. to_upper();
  146. ~to_upper();
  147. to_upper(to_upper const &);
  148. to_upper const &operator=(to_upper const &other);
  149. void operator()(std::ostream &out) const;
  150. to_upper(streamable const &obj);
  151. private:
  152. streamable obj_;
  153. struct _data;
  154. booster::copy_ptr<_data> d;
  155. };
  156. inline std::ostream &operator<<(std::ostream &out,to_upper const &obj)
  157. {
  158. obj(out);
  159. return out;
  160. }
  161. ///
  162. /// \brief Output filter to_lower
  163. ///
  164. /// Convert text to lower case according to locale
  165. ///
  166. class CPPCMS_API to_lower {
  167. public:
  168. to_lower();
  169. ~to_lower();
  170. to_lower(to_lower const &);
  171. to_lower const &operator=(to_lower const &other);
  172. void operator()(std::ostream &out) const;
  173. to_lower(streamable const &obj);
  174. private:
  175. streamable obj_;
  176. struct _data;
  177. booster::copy_ptr<_data> d;
  178. };
  179. inline std::ostream &operator<<(std::ostream &out,to_lower const &obj)
  180. {
  181. obj(out);
  182. return out;
  183. }
  184. ///
  185. /// \brief Output filter to_title
  186. ///
  187. /// Convert text to title case according to locale
  188. ///
  189. class CPPCMS_API to_title {
  190. public:
  191. to_title();
  192. ~to_title();
  193. to_title(to_title const &);
  194. to_title const &operator=(to_title const &other);
  195. void operator()(std::ostream &out) const;
  196. to_title(streamable const &obj);
  197. private:
  198. streamable obj_;
  199. struct _data;
  200. booster::copy_ptr<_data> d;
  201. };
  202. inline std::ostream &operator<<(std::ostream &out,to_title const &obj)
  203. {
  204. obj(out);
  205. return out;
  206. }
  207. ///
  208. /// \brief Output filter escape
  209. ///
  210. /// Escape text for HTML -- make text safe
  211. ///
  212. class CPPCMS_API escape {
  213. public:
  214. escape();
  215. ~escape();
  216. escape(escape const &);
  217. escape const &operator=(escape const &other);
  218. void operator()(std::ostream &out) const;
  219. escape(streamable const &obj);
  220. private:
  221. streamable obj_;
  222. struct _data;
  223. booster::copy_ptr<_data> d;
  224. };
  225. inline std::ostream &operator<<(std::ostream &out,escape const &obj)
  226. {
  227. obj(out);
  228. return out;
  229. }
  230. ///
  231. /// \brief Output filter escape
  232. ///
  233. /// Escape text for JavaScript string -- make text safe to include between quotes in the JavaScript or JSON code
  234. ///
  235. /// \ver{v1_2}
  236. class CPPCMS_API jsescape {
  237. public:
  238. jsescape();
  239. ~jsescape();
  240. jsescape(jsescape const &);
  241. jsescape const &operator=(jsescape const &other);
  242. void operator()(std::ostream &out) const;
  243. jsescape(streamable const &obj);
  244. private:
  245. streamable obj_;
  246. struct _data;
  247. booster::copy_ptr<_data> d;
  248. };
  249. inline std::ostream &operator<<(std::ostream &out,jsescape const &obj)
  250. {
  251. obj(out);
  252. return out;
  253. }
  254. ///
  255. /// \brief Output filter urlencode
  256. ///
  257. /// Perform urlencoding(percent encoding) of the text
  258. ///
  259. class CPPCMS_API urlencode {
  260. public:
  261. urlencode();
  262. ~urlencode();
  263. urlencode(urlencode const &);
  264. urlencode const &operator=(urlencode const &other);
  265. void operator()(std::ostream &out) const;
  266. urlencode(streamable const &obj);
  267. private:
  268. streamable obj_;
  269. struct _data;
  270. booster::copy_ptr<_data> d;
  271. };
  272. inline std::ostream &operator<<(std::ostream &out,urlencode const &obj)
  273. {
  274. obj(out);
  275. return out;
  276. }
  277. ///
  278. /// \brief Output filter base64_urlencode
  279. ///
  280. /// Convert text to base64 format that is friendly to URL.
  281. ///
  282. class CPPCMS_API base64_urlencode {
  283. public:
  284. base64_urlencode();
  285. ~base64_urlencode();
  286. base64_urlencode(base64_urlencode const &);
  287. base64_urlencode const &operator=(base64_urlencode const &other);
  288. void operator()(std::ostream &out) const;
  289. base64_urlencode(streamable const &obj);
  290. private:
  291. streamable obj_;
  292. struct _data;
  293. booster::copy_ptr<_data> d;
  294. };
  295. inline std::ostream &operator<<(std::ostream &out,base64_urlencode const &obj)
  296. {
  297. obj(out);
  298. return out;
  299. }
  300. ///
  301. /// \brief Output filter raw
  302. ///
  303. /// Filter that does nothing
  304. ///
  305. class CPPCMS_API raw {
  306. public:
  307. raw();
  308. ~raw();
  309. raw(raw const &);
  310. raw const &operator=(raw const &other);
  311. void operator()(std::ostream &out) const;
  312. raw(streamable const &obj);
  313. private:
  314. streamable obj_;
  315. struct _data;
  316. booster::copy_ptr<_data> d;
  317. };
  318. inline std::ostream &operator<<(std::ostream &out,raw const &obj)
  319. {
  320. obj(out);
  321. return out;
  322. }
  323. ///
  324. /// \brief Formats date to the stream, date is represented as number - POSIX time, a plain number
  325. ///
  326. class CPPCMS_API date {
  327. public:
  328. date();
  329. date(date const &other);
  330. date const &operator=(date const &other);
  331. ~date();
  332. ///
  333. /// Create date filter that formats current local-time date using POSIX time representation \a time
  334. ///
  335. date(streamable const &time);
  336. ///
  337. /// Create date filter that formats current date using POSIX time representation \a time,
  338. /// in a timezone \a timezone
  339. ///
  340. date(streamable const &time,std::string const &timezone);
  341. void operator()(std::ostream &out) const;
  342. private:
  343. struct _data;
  344. streamable time_;
  345. std::string tz_;
  346. booster::copy_ptr<_data> d;
  347. };
  348. inline std::ostream &operator<<(std::ostream &out,date const &obj)
  349. {
  350. obj(out);
  351. return out;
  352. }
  353. ///
  354. /// \brief Format local time to ouput stream
  355. ///
  356. /// Formats time to the stream, time is represented as number
  357. ///
  358. class CPPCMS_API time {
  359. public:
  360. time();
  361. time(time const &other);
  362. time const &operator=(time const &other);
  363. ~time();
  364. ///
  365. /// Create time filter that formats current local-time time using POSIX time representation \a t
  366. ///
  367. time(streamable const &t);
  368. ///
  369. /// Create time filter that formats current time using POSIX time representation \a t,
  370. /// in a timezone \a timezone
  371. ///
  372. time(streamable const &time,std::string const &timezone);
  373. void operator()(std::ostream &out) const;
  374. private:
  375. struct _data;
  376. streamable time_;
  377. std::string tz_;
  378. booster::copy_ptr<_data> d;
  379. };
  380. inline std::ostream &operator<<(std::ostream &out,time const &obj)
  381. {
  382. obj(out);
  383. return out;
  384. }
  385. ///
  386. /// \brief Format date and time to ouput stream
  387. ///
  388. /// Formats date and time to the stream, date and time is represented as time_t
  389. ///
  390. class CPPCMS_API datetime {
  391. public:
  392. datetime();
  393. datetime(datetime const &other);
  394. datetime const &operator=(datetime const &other);
  395. ~datetime();
  396. ///
  397. /// Create date and time filter that formats current local-time date and time using POSIX time representation \a t
  398. ///
  399. datetime(streamable const &t);
  400. ///
  401. /// Create date and time filter that formats current date and time using POSIX time representation \a t,
  402. /// in a timezone \a timezone
  403. ///
  404. datetime(streamable const &time,std::string const &timezone);
  405. void operator()(std::ostream &out) const;
  406. private:
  407. struct _data;
  408. streamable time_;
  409. std::string tz_;
  410. booster::copy_ptr<_data> d;
  411. };
  412. inline std::ostream &operator<<(std::ostream &out,datetime const &obj)
  413. {
  414. obj(out);
  415. return out;
  416. }
  417. ///
  418. /// \brief Custom time formating filter
  419. ///
  420. /// Formats date and time to the stream, date and time is represented as time_t
  421. ///
  422. class CPPCMS_API strftime {
  423. public:
  424. strftime();
  425. strftime(strftime const &other);
  426. strftime const &operator=(strftime const &other);
  427. ~strftime();
  428. ///
  429. /// Create date and time filter that formats current local-time date and time using POSIX time representation \a t
  430. /// according to strftime like format \a fmt, see booster::locale::as::ftime or cppcms::locale::as::ftime for details
  431. /// (depending on your localization backend)
  432. ///
  433. strftime(streamable const &t,std::string const &fmt);
  434. ///
  435. /// Create date and time filter that formats current date and time using POSIX time representation \a t,
  436. /// in a timezone \a timezone
  437. /// according to strftime like format \a fmt, see booster::locale::as::ftime or cppcms::locale::as::ftime for details
  438. /// (depending on your localization backend)
  439. ///
  440. strftime(streamable const &time,std::string const &timezone,std::string const &fmt);
  441. void operator()(std::ostream &out) const;
  442. private:
  443. struct _data;
  444. streamable time_;
  445. std::string tz_;
  446. std::string format_;
  447. booster::copy_ptr<_data> d;
  448. };
  449. inline std::ostream &operator<<(std::ostream &out,strftime const &obj)
  450. {
  451. obj(out);
  452. return out;
  453. }
  454. using locale::translate;
  455. using locale::format;
  456. }
  457. ///////////////////////////////
  458. }
  459. #endif