/project/jni/stlport/stlport/stl/_monetary.c

https://github.com/aichunyu/FFPlayer · C · 604 lines · 457 code · 86 blank · 61 comment · 137 complexity · d40149182efdb79c33f770da546d18eb MD5 · raw file

  1. /*
  2. * Copyright (c) 1999
  3. * Silicon Graphics Computer Systems, Inc.
  4. *
  5. * Copyright (c) 1999
  6. * Boris Fomitchev
  7. *
  8. * This material is provided "as is", with absolutely no warranty expressed
  9. * or implied. Any use is at your own risk.
  10. *
  11. * Permission to use or copy this software for any purpose is hereby granted
  12. * without fee, provided the above notices are retained on all copies.
  13. * Permission to modify the code and to distribute modified code is granted,
  14. * provided the above notices are retained, and a notice that the code was
  15. * modified is included with the above copyright notice.
  16. *
  17. */
  18. #ifndef _STLP_MONETARY_C
  19. #define _STLP_MONETARY_C
  20. # ifndef _STLP_INTERNAL_MONETARY_H
  21. # include <stl/_monetary.h>
  22. # endif
  23. #ifndef _STLP_INTERNAL_IOS_H
  24. # include <stl/_ios.h>
  25. #endif
  26. #ifndef _STLP_INTERNAL_NUM_PUT_H
  27. # include <stl/_num_put.h>
  28. #endif
  29. #ifndef _STLP_INTERNAL_NUM_GET_H
  30. # include <stl/_num_get.h>
  31. #endif
  32. _STLP_BEGIN_NAMESPACE
  33. #if (_STLP_STATIC_TEMPLATE_DATA > 0)
  34. # if !defined (__BORLANDC__)
  35. template <class _CharT, class _InputIterator>
  36. locale::id money_get<_CharT, _InputIterator>::id;
  37. template <class _CharT, class _OutputIterator>
  38. locale::id money_put<_CharT, _OutputIterator>::id;
  39. # endif
  40. # if (defined (__CYGWIN__) || defined (__MINGW32__)) && \
  41. defined (_STLP_USE_DYNAMIC_LIB) && !defined (__BUILDING_STLPORT)
  42. /*
  43. * Under cygwin, when STLport is used as a shared library, the id needs
  44. * to be specified as imported otherwise they will be duplicated in the
  45. * calling executable.
  46. */
  47. template <>
  48. _STLP_DECLSPEC locale::id money_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
  49. /*
  50. template <>
  51. _STLP_DECLSPEC locale::id money_get<char, const char*>::id;
  52. */
  53. template <>
  54. _STLP_DECLSPEC locale::id money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
  55. template <>
  56. _STLP_DECLSPEC locale::id money_put<char, char*>::id;
  57. # if !defined (_STLP_NO_WCHAR_T)
  58. template <>
  59. _STLP_DECLSPEC locale::id money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  60. template <>
  61. _STLP_DECLSPEC locale::id money_get<wchar_t, const wchar_t*>::id;
  62. template <>
  63. _STLP_DECLSPEC locale::id money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
  64. template <>
  65. _STLP_DECLSPEC locale::id money_put<wchar_t, wchar_t*>::id;
  66. # endif
  67. # endif
  68. #else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  69. //typedef money_get<char, const char*> money_get_char;
  70. //typedef money_put<char, char*> money_put_char;
  71. typedef money_get<char, istreambuf_iterator<char, char_traits<char> > > money_get_char_2;
  72. typedef money_put<char, ostreambuf_iterator<char, char_traits<char> > > money_put_char_2;
  73. //__DECLARE_INSTANCE(locale::id, money_get_char::id, );
  74. //__DECLARE_INSTANCE(locale::id, money_put_char::id, );
  75. __DECLARE_INSTANCE(locale::id, money_get_char_2::id, );
  76. __DECLARE_INSTANCE(locale::id, money_put_char_2::id, );
  77. # ifndef _STLP_NO_WCHAR_T
  78. //typedef money_get<wchar_t, const wchar_t*> money_get_wchar_t;
  79. //typedef money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > money_get_wchar_t_2;
  80. typedef money_put<wchar_t, wchar_t*> money_put_wchar_t;
  81. typedef money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > money_put_wchar_t_2;
  82. //__DECLARE_INSTANCE(locale::id, money_get_wchar_t::id, );
  83. //__DECLARE_INSTANCE(locale::id, money_put_wchar_t::id, );
  84. __DECLARE_INSTANCE(locale::id, money_get_wchar_t_2::id, );
  85. __DECLARE_INSTANCE(locale::id, money_put_wchar_t_2::id, );
  86. # endif
  87. #endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  88. // money_get facets
  89. _STLP_MOVE_TO_PRIV_NAMESPACE
  90. // helper functions for do_get
  91. template <class _InIt1, class _InIt2>
  92. pair<_InIt1, bool> __get_string( _InIt1 __first, _InIt1 __last,
  93. _InIt2 __str_first, _InIt2 __str_last) {
  94. while ( __first != __last && __str_first != __str_last && *__first == *__str_first ) {
  95. ++__first;
  96. ++__str_first;
  97. }
  98. return make_pair(__first, __str_first == __str_last);
  99. }
  100. template <class _InIt, class _OuIt, class _CharT>
  101. bool
  102. __get_monetary_value(_InIt& __first, _InIt __last, _OuIt __out_ite,
  103. const ctype<_CharT>& _c_type,
  104. _CharT __point, int __frac_digits, _CharT __sep,
  105. const string& __grouping, bool &__syntax_ok) {
  106. if (__first == __last || !_c_type.is(ctype_base::digit, *__first))
  107. return false;
  108. char __group_sizes[128];
  109. char* __group_sizes_end = __grouping.empty()? 0 : __group_sizes;
  110. char __current_group_size = 0;
  111. while (__first != __last) {
  112. if (_c_type.is(ctype_base::digit, *__first)) {
  113. ++__current_group_size;
  114. *__out_ite++ = *__first++;
  115. }
  116. else if (__group_sizes_end) {
  117. if (*__first == __sep) {
  118. *__group_sizes_end++ = __current_group_size;
  119. __current_group_size = 0;
  120. ++__first;
  121. }
  122. else break;
  123. }
  124. else
  125. break;
  126. }
  127. if (__grouping.empty())
  128. __syntax_ok = true;
  129. else {
  130. if (__group_sizes_end != __group_sizes)
  131. *__group_sizes_end++ = __current_group_size;
  132. __syntax_ok = __valid_grouping(__group_sizes, __group_sizes_end,
  133. __grouping.data(), __grouping.data()+ __grouping.size());
  134. if (__first == __last || *__first != __point) {
  135. for (int __digits = 0; __digits != __frac_digits; ++__digits)
  136. *__out_ite++ = _CharT('0');
  137. return true; // OK not to have decimal point
  138. }
  139. }
  140. ++__first;
  141. int __digits = 0;
  142. while (__first != __last && _c_type.is(ctype_base::digit, *__first)) {
  143. *__out_ite++ = *__first++;
  144. ++__digits;
  145. }
  146. __syntax_ok = __syntax_ok && (__digits == __frac_digits);
  147. return true;
  148. }
  149. template <class _CharT, class _InputIter, class _StrType>
  150. _InputIter __money_do_get(_InputIter __s, _InputIter __end, bool __intl,
  151. ios_base& __str, ios_base::iostate& __err,
  152. _StrType& __digits, bool &__is_positive, _CharT* /*__dummy*/) {
  153. if (__s == __end) {
  154. __err |= ios_base::eofbit;
  155. return __s;
  156. }
  157. typedef _CharT char_type;
  158. typedef _StrType string_type;
  159. typedef _InputIter iter_type;
  160. typedef moneypunct<char_type, false> _Punct;
  161. typedef moneypunct<char_type, true> _Punct_intl;
  162. typedef ctype<char_type> _Ctype;
  163. locale __loc = __str.getloc();
  164. const _Punct& __punct = use_facet<_Punct>(__loc) ;
  165. const _Punct_intl& __punct_intl = use_facet<_Punct_intl>(__loc) ;
  166. const _Ctype& __c_type = use_facet<_Ctype>(__loc) ;
  167. money_base::pattern __format = __intl ? __punct_intl.neg_format()
  168. : __punct.neg_format();
  169. string_type __ns = __intl ? __punct_intl.negative_sign()
  170. : __punct.negative_sign();
  171. string_type __ps = __intl ? __punct_intl.positive_sign()
  172. : __punct.positive_sign();
  173. int __i;
  174. bool __symbol_required = (__str.flags() & ios_base::showbase) != 0;
  175. string_type __buf;
  176. back_insert_iterator<string_type> __out_ite(__buf);
  177. for (__i = 0; __i < 4; ++__i) {
  178. switch (__format.field[__i]) {
  179. case money_base::none:
  180. if (__i == 3) {
  181. if (__c_type.is(ctype_base::space, *__s)) {
  182. __err = ios_base::failbit;
  183. return __s;
  184. }
  185. break;
  186. }
  187. while (__s != __end && __c_type.is(ctype_base::space, *__s))
  188. ++__s;
  189. break;
  190. case money_base::space:
  191. if (!__c_type.is(ctype_base::space, *__s)) {
  192. __err = ios_base::failbit;
  193. return __s;
  194. }
  195. ++__s;
  196. while (__s != __end && __c_type.is(ctype_base::space, *__s))
  197. ++__s;
  198. break;
  199. case money_base::symbol: {
  200. string_type __curs = __intl ? __punct_intl.curr_symbol()
  201. : __punct.curr_symbol();
  202. pair<iter_type, bool>
  203. __result = __get_string(__s, __end, __curs.begin(), __curs.end());
  204. if (!__result.second && __symbol_required)
  205. __err = ios_base::failbit;
  206. __s = __result.first;
  207. break;
  208. }
  209. case money_base::sign: {
  210. if (__s == __end) {
  211. if (__ps.empty())
  212. break;
  213. if (__ns.empty()) {
  214. __is_positive = false;
  215. break;
  216. }
  217. __err = ios_base::failbit;
  218. return __s;
  219. }
  220. else {
  221. if (__ps.empty()) {
  222. if (__ns.empty())
  223. break;
  224. if (*__s == __ns[0]) {
  225. ++__s;
  226. __is_positive = false;
  227. }
  228. break;
  229. }
  230. else {
  231. if (*__s == __ps[0]) {
  232. ++__s;
  233. break;
  234. }
  235. if (__ns.empty())
  236. break;
  237. if (*__s == __ns[0]) {
  238. ++__s;
  239. __is_positive = false;
  240. break;
  241. }
  242. __err = ios_base::failbit;
  243. }
  244. }
  245. return __s;
  246. }
  247. case money_base::value: {
  248. char_type __point = __intl ? __punct_intl.decimal_point()
  249. : __punct.decimal_point();
  250. int __frac_digits = __intl ? __punct_intl.frac_digits()
  251. : __punct.frac_digits();
  252. string __grouping = __intl ? __punct_intl.grouping()
  253. : __punct.grouping();
  254. bool __syntax_ok = true;
  255. bool __result;
  256. char_type __sep = __grouping.empty() ? char_type() :
  257. __intl ? __punct_intl.thousands_sep() : __punct.thousands_sep();
  258. __result = __get_monetary_value(__s, __end, __out_ite, __c_type,
  259. __point, __frac_digits,
  260. __sep,
  261. __grouping, __syntax_ok);
  262. if (!__syntax_ok)
  263. __err |= ios_base::failbit;
  264. if (!__result) {
  265. __err = ios_base::failbit;
  266. return __s;
  267. }
  268. break;
  269. } // Close money_base::value case
  270. } // Close switch statement
  271. } // Close for loop
  272. if (__is_positive) {
  273. if (__ps.size() > 1) {
  274. pair<_InputIter, bool>
  275. __result = __get_string(__s, __end, __ps.begin() + 1, __ps.end());
  276. __s = __result.first;
  277. if (!__result.second)
  278. __err |= ios::failbit;
  279. }
  280. if (!(__err & ios_base::failbit))
  281. __digits = __buf;
  282. }
  283. else {
  284. if (__ns.size() > 1) {
  285. pair<_InputIter, bool>
  286. __result = __get_string(__s, __end, __ns.begin() + 1, __ns.end());
  287. __s = __result.first;
  288. if (!__result.second)
  289. __err |= ios::failbit;
  290. }
  291. if (!(__err & ios::failbit)) {
  292. __digits = __c_type.widen('-');
  293. __digits += __buf;
  294. }
  295. }
  296. if (__s == __end)
  297. __err |= ios::eofbit;
  298. return __s;
  299. }
  300. _STLP_MOVE_TO_STD_NAMESPACE
  301. //===== methods ======
  302. template <class _CharT, class _InputIter>
  303. _InputIter
  304. money_get<_CharT, _InputIter>::do_get(_InputIter __s, _InputIter __end, bool __intl,
  305. ios_base& __str, ios_base::iostate& __err,
  306. _STLP_LONGEST_FLOAT_TYPE& __units) const {
  307. string_type __buf;
  308. bool __is_positive = true;
  309. __s = _STLP_PRIV __money_do_get(__s, __end, __intl, __str, __err, __buf, __is_positive, (_CharT*)0);
  310. if (__err == ios_base::goodbit || __err == ios_base::eofbit) {
  311. typename string_type::iterator __b = __buf.begin(), __e = __buf.end();
  312. if (!__is_positive) ++__b;
  313. // Can't use atold, since it might be wchar_t. Don't get confused by name below :
  314. // it's perfectly capable of reading long double.
  315. _STLP_PRIV __get_decimal_integer(__b, __e, __units, (_CharT*)0);
  316. if (!__is_positive) {
  317. __units = -__units;
  318. }
  319. }
  320. return __s;
  321. }
  322. template <class _CharT, class _InputIter>
  323. _InputIter
  324. money_get<_CharT, _InputIter>::do_get(iter_type __s, iter_type __end, bool __intl,
  325. ios_base& __str, ios_base::iostate& __err,
  326. string_type& __digits) const {
  327. bool __is_positive = true;
  328. return _STLP_PRIV __money_do_get(__s, __end, __intl, __str, __err, __digits, __is_positive, (_CharT*)0);
  329. }
  330. // money_put facets
  331. _STLP_MOVE_TO_PRIV_NAMESPACE
  332. template <class _CharT, class _OutputIter, class _Str_Type, class _Str>
  333. _OutputIter __money_do_put(_OutputIter __s, bool __intl, ios_base& __str,
  334. _CharT __fill, const _Str& __digits, bool __check_digits,
  335. _Str_Type * /*__dummy*/) {
  336. typedef _CharT char_type;
  337. typedef _Str_Type string_type;
  338. typedef ctype<char_type> _Ctype;
  339. typedef moneypunct<char_type, false> _Punct;
  340. typedef moneypunct<char_type, true> _Punct_intl;
  341. locale __loc = __str.getloc();
  342. const _Ctype& __c_type = use_facet<_Ctype>(__loc) ;
  343. const _Punct& __punct = use_facet<_Punct>(__loc) ;
  344. const _Punct_intl& __punct_intl = use_facet<_Punct_intl>(__loc) ;
  345. // some special characters
  346. char_type __minus = __c_type.widen('-');
  347. char_type __plus = __c_type.widen('+');
  348. char_type __space = __c_type.widen(' ');
  349. char_type __zero = __c_type.widen('0');
  350. char_type __point = __intl ? __punct_intl.decimal_point()
  351. : __punct.decimal_point();
  352. char_type __sep = __intl ? __punct_intl.thousands_sep()
  353. : __punct.thousands_sep();
  354. string __grouping = __intl ? __punct_intl.grouping()
  355. : __punct.grouping();
  356. int __frac_digits = __intl ? __punct_intl.frac_digits()
  357. : __punct.frac_digits();
  358. string_type __curr_sym = __intl ? __punct_intl.curr_symbol()
  359. : __punct.curr_symbol();
  360. // if there are no digits we are going to return __s. If there
  361. // are digits, but not enough to fill the frac_digits, we are
  362. // going to add zeros. I don't know whether this is right or
  363. // not.
  364. if (__digits.empty())
  365. return __s;
  366. typename string_type::const_iterator __digits_first = __digits.begin();
  367. typename string_type::const_iterator __digits_last = __digits.end();
  368. bool __is_negative = *__digits_first == __minus;
  369. if (__is_negative)
  370. ++__digits_first;
  371. #if !defined (__BORLANDC__)
  372. string_type __sign = __intl ? __is_negative ? __punct_intl.negative_sign()
  373. : __punct_intl.positive_sign()
  374. : __is_negative ? __punct.negative_sign()
  375. : __punct.positive_sign();
  376. #else
  377. string_type __sign;
  378. if (__intl) {
  379. if (__is_negative)
  380. __sign = __punct_intl.negative_sign();
  381. else
  382. __sign = __punct_intl.positive_sign();
  383. }
  384. else {
  385. if (__is_negative)
  386. __sign = __punct.negative_sign();
  387. else
  388. __sign = __punct.positive_sign();
  389. }
  390. #endif
  391. if (__check_digits) {
  392. typename string_type::const_iterator __cp = __digits_first;
  393. while (__cp != __digits_last && __c_type.is(ctype_base::digit, *__cp))
  394. ++__cp;
  395. if (__cp == __digits_first)
  396. return __s;
  397. __digits_last = __cp;
  398. }
  399. // If grouping is required, we make a copy of __digits and
  400. // insert the grouping.
  401. _STLP_BASIC_IOSTRING(char_type) __new_digits;
  402. if (!__grouping.empty()) {
  403. __new_digits.assign(__digits_first, __digits_last);
  404. __insert_grouping(__new_digits,
  405. __new_digits.size() - __frac_digits,
  406. __grouping,
  407. __sep, __plus, __minus, 0);
  408. __digits_first = __new_digits.begin(); // <<--
  409. __digits_last = __new_digits.end(); // <<--
  410. }
  411. // Determine the amount of padding required, if any.
  412. streamsize __width = __str.width();
  413. #if defined (_STLP_DEBUG) && (defined(__HP_aCC) && (__HP_aCC <= 1))
  414. size_t __value_length = operator -(__digits_last, __digits_first);
  415. #else
  416. size_t __value_length = __digits_last - __digits_first;
  417. #endif
  418. size_t __length = __value_length + __sign.size();
  419. if (__frac_digits != 0)
  420. ++__length;
  421. bool __generate_curr = (__str.flags() & ios_base::showbase) !=0;
  422. if (__generate_curr)
  423. __length += __curr_sym.size();
  424. money_base::pattern __format = __intl ? (__is_negative ? __punct_intl.neg_format()
  425. : __punct_intl.pos_format())
  426. : (__is_negative ? __punct.neg_format()
  427. : __punct.pos_format());
  428. {
  429. //For the moment the following is commented for decoding reason.
  430. //No reason to add a space last if the money symbol do not have to be display
  431. //if (__format.field[3] == (char) money_base::symbol && !__generate_curr) {
  432. // if (__format.field[2] == (char) money_base::space) {
  433. // __format.field[2] = (char) money_base::none;
  434. // }
  435. //}
  436. //space can only be second or third and only once (22.2.6.3-1):
  437. if ((__format.field[1] == (char) money_base::space) ||
  438. (__format.field[2] == (char) money_base::space))
  439. ++__length;
  440. }
  441. const bool __need_fill = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __length) < __width)) ||
  442. ((sizeof(streamsize) <= sizeof(size_t)) && (__length < __STATIC_CAST(size_t, __width))));
  443. streamsize __fill_amt = __need_fill ? __width - __length : 0;
  444. ios_base::fmtflags __fill_pos = __str.flags() & ios_base::adjustfield;
  445. if (__fill_amt != 0 &&
  446. !(__fill_pos & (ios_base::left | ios_base::internal)))
  447. __s = __fill_n(__s, __fill_amt, __fill);
  448. for (int __i = 0; __i < 4; ++__i) {
  449. char __ffield = __format.field[__i];
  450. switch (__ffield) {
  451. case money_base::none:
  452. if (__fill_amt != 0 && __fill_pos == ios_base::internal)
  453. __s = __fill_n(__s, __fill_amt, __fill);
  454. break;
  455. case money_base::space:
  456. *__s++ = __space;
  457. if (__fill_amt != 0 && __fill_pos == ios_base::internal)
  458. __s = __fill_n(__s, __fill_amt, __fill);
  459. break;
  460. case money_base::symbol:
  461. if (__generate_curr)
  462. __s = copy(__curr_sym.begin(), __curr_sym.end(), __s);
  463. break;
  464. case money_base::sign:
  465. if (!__sign.empty())
  466. *__s++ = __sign[0];
  467. break;
  468. case money_base::value:
  469. if (__frac_digits == 0) {
  470. __s = copy(__digits_first, __digits_last, __s);
  471. } else {
  472. if ((int)__value_length <= __frac_digits) {
  473. // if we see '9' here, we should out 0.09
  474. *__s++ = __zero; // integer part is zero
  475. *__s++ = __point; // decimal point
  476. __s = __fill_n(__s, __frac_digits - __value_length, __zero); // zeros
  477. __s = copy(__digits_first, __digits_last, __s); // digits
  478. } else {
  479. __s = copy(__digits_first, __digits_last - __frac_digits, __s);
  480. if (__frac_digits != 0) {
  481. *__s++ = __point;
  482. __s = copy(__digits_last - __frac_digits, __digits_last, __s);
  483. }
  484. }
  485. }
  486. break;
  487. } //Close for switch
  488. } // Close for loop
  489. // Ouput rest of sign if necessary.
  490. if (__sign.size() > 1)
  491. __s = copy(__sign.begin() + 1, __sign.end(), __s);
  492. if (__fill_amt != 0 &&
  493. !(__fill_pos & (ios_base::right | ios_base::internal)))
  494. __s = __fill_n(__s, __fill_amt, __fill);
  495. return __s;
  496. }
  497. _STLP_MOVE_TO_STD_NAMESPACE
  498. template <class _CharT, class _OutputIter>
  499. _OutputIter
  500. money_put<_CharT, _OutputIter>
  501. ::do_put(_OutputIter __s, bool __intl, ios_base& __str,
  502. char_type __fill, _STLP_LONGEST_FLOAT_TYPE __units) const {
  503. _STLP_BASIC_IOSTRING(char_type) __digits;
  504. _STLP_PRIV __get_money_digits(__digits, __str, __units);
  505. return _STLP_PRIV __money_do_put(__s, __intl, __str, __fill, __digits, false, __STATIC_CAST(string_type*, 0));
  506. }
  507. template <class _CharT, class _OutputIter>
  508. _OutputIter
  509. money_put<_CharT, _OutputIter>
  510. ::do_put(_OutputIter __s, bool __intl, ios_base& __str,
  511. char_type __fill, const string_type& __digits) const {
  512. return _STLP_PRIV __money_do_put(__s, __intl, __str, __fill, __digits, true, __STATIC_CAST(string_type*, 0));
  513. }
  514. _STLP_END_NAMESPACE
  515. #endif /* _STLP_MONETARY_C */
  516. // Local Variables:
  517. // mode:C++
  518. // End: