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).
29template <class Char>
30static 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.
72template <class Char, class Str>
73static 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
124char* _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
134ptrdiff_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
141void _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)
148ptrdiff_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
156void _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)
169template class _STLP_CLASS_DECLSPEC ostreambuf_iterator<char, char_traits<char> >;
170// template class num_put<char, char*>;
171template class num_put<char, ostreambuf_iterator<char, char_traits<char> > >;
172# ifndef _STLP_NO_WCHAR_T
173template class ostreambuf_iterator<wchar_t, char_traits<wchar_t> >;
174template 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