Home | History | Annotate | Download | only in src
      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 
     19 #include "stlport_prefix.h"
     20 
     21 #include <locale>
     22 #include <ostream>
     23 
     24 _STLP_BEGIN_NAMESPACE
     25 
     26 // Note that grouping[0] is the number of digits in the *rightmost* group.
     27 // We assume, without checking, that *last is null and that there is enough
     28 // space in the buffer to extend the number past [first, last).
     29 template <class Char>
     30 static ptrdiff_t
     31 __insert_grouping_aux(Char* first, Char* last, const string& grouping,
     32                       Char separator, Char Plus, Char Minus,
     33                       int basechars) {
     34   typedef string::size_type str_size;
     35 
     36   if (first == last)
     37     return 0;
     38 
     39   int sign = 0;
     40 
     41   if (*first == Plus || *first == Minus) {
     42     sign = 1;
     43     ++first;
     44   }
     45 
     46   first += basechars;
     47   Char* cur_group = last; // Points immediately beyond the rightmost
     48                           // digit of the current group.
     49   int groupsize = 0; // Size of the current group (if grouping.size() == 0, size
     50                      // of group unlimited: we force condition (groupsize <= 0))
     51 
     52   for ( str_size n = 0; ; ) { // Index of the current group
     53     if ( n < grouping.size() ) {
     54       groupsize = __STATIC_CAST(int, grouping[n++] );
     55     }
     56 
     57     if ((groupsize <= 0) || (groupsize >= cur_group - first) || (groupsize == CHAR_MAX)) {
     58       break;
     59     }
     60 
     61     // Insert a separator character just before position cur_group - groupsize
     62     cur_group -= groupsize;
     63     ++last;
     64     copy_backward(cur_group, last, last + 1);
     65     *cur_group = separator;
     66   }
     67 
     68   return (last - first) + sign + basechars;
     69 }
     70 
     71 //Dynamic output buffer version.
     72 template <class Char, class Str>
     73 static void
     74 __insert_grouping_aux( /* __basic_iostring<Char> */ Str& iostr, size_t __group_pos,
     75                       const string& grouping,
     76                       Char separator, Char Plus, Char Minus,
     77                       int basechars) {
     78   typedef string::size_type str_size;
     79 
     80   if (iostr.size() < __group_pos)
     81     return;
     82 
     83   int __first_pos = 0;
     84   Char __first = *iostr.begin();
     85 
     86   if (__first == Plus || __first == Minus) {
     87     ++__first_pos;
     88   }
     89 
     90   __first_pos += basechars;
     91 
     92   typename Str::iterator cur_group(iostr.begin() + __group_pos);    // Points immediately beyond the rightmost
     93                                                                     // digit of the current group.
     94   int groupsize = 0; // Size of the current group (if grouping.size() == 0, size
     95                      // of group unlimited: we force condition (groupsize <= 0))
     96 
     97   for ( str_size n = 0; ; ) { // Index of the current group
     98     if ( n < grouping.size() ) {
     99       groupsize = __STATIC_CAST( int, grouping[n++] );
    100     }
    101 
    102     if ( (groupsize <= 0) || (groupsize >= ((cur_group - iostr.begin()) - __first_pos)) ||
    103          (groupsize == CHAR_MAX)) {
    104       break;
    105     }
    106 
    107     // Insert a separator character just before position cur_group - groupsize
    108     cur_group -= groupsize;
    109     cur_group = iostr.insert(cur_group, separator);
    110   }
    111 }
    112 
    113 //----------------------------------------------------------------------
    114 // num_put
    115 
    116 _STLP_MOVE_TO_PRIV_NAMESPACE
    117 
    118 _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_lo()
    119 { return "0123456789abcdefx"; }
    120 
    121 _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_hi()
    122 { return "0123456789ABCDEFX"; }
    123 
    124 char* _STLP_CALL
    125 __write_integer(char* buf, ios_base::fmtflags flags, long x) {
    126   char tmp[64];
    127   char* bufend = tmp+64;
    128   char* beg = __write_integer_backward(bufend, flags, x);
    129   return copy(beg, bufend, buf);
    130 }
    131 
    132 ///-------------------------------------
    133 
    134 ptrdiff_t _STLP_CALL
    135 __insert_grouping(char * first, char * last, const string& grouping,
    136                   char separator, char Plus, char Minus, int basechars) {
    137   return __insert_grouping_aux(first, last, grouping,
    138                                separator, Plus, Minus, basechars);
    139 }
    140 
    141 void _STLP_CALL
    142 __insert_grouping(__iostring &str, size_t group_pos, const string& grouping,
    143                   char separator, char Plus, char Minus, int basechars) {
    144   __insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars);
    145 }
    146 
    147 #if !defined (_STLP_NO_WCHAR_T)
    148 ptrdiff_t _STLP_CALL
    149 __insert_grouping(wchar_t* first, wchar_t* last, const string& grouping,
    150                   wchar_t separator, wchar_t Plus, wchar_t Minus,
    151                   int basechars) {
    152   return __insert_grouping_aux(first, last, grouping, separator,
    153                                Plus, Minus, basechars);
    154 }
    155 
    156 void _STLP_CALL
    157 __insert_grouping(__iowstring &str, size_t group_pos, const string& grouping,
    158                   wchar_t separator, wchar_t Plus, wchar_t Minus,
    159                   int basechars) {
    160   __insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars);
    161 }
    162 #endif
    163 
    164 _STLP_MOVE_TO_STD_NAMESPACE
    165 
    166 //----------------------------------------------------------------------
    167 // Force instantiation of num_put<>
    168 #if !defined(_STLP_NO_FORCE_INSTANTIATE)
    169 template class _STLP_CLASS_DECLSPEC ostreambuf_iterator<char, char_traits<char> >;
    170 // template class num_put<char, char*>;
    171 template class num_put<char, ostreambuf_iterator<char, char_traits<char> > >;
    172 # ifndef _STLP_NO_WCHAR_T
    173 template class ostreambuf_iterator<wchar_t, char_traits<wchar_t> >;
    174 template class num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
    175 // template class num_put<wchar_t, wchar_t*>;
    176 # endif /* INSTANTIATE_WIDE_STREAMS */
    177 #endif
    178 
    179 _STLP_END_NAMESPACE
    180 
    181 // Local Variables:
    182 // mode:C++
    183 // End:
    184