|
1 /* |
|
2 * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
3 * |
|
4 * Copyright (c) 1999 |
|
5 * Silicon Graphics Computer Systems, Inc. |
|
6 * |
|
7 * Copyright (c) 1999 |
|
8 * Boris Fomitchev |
|
9 * |
|
10 * This material is provided "as is", with absolutely no warranty expressed |
|
11 * or implied. Any use is at your own risk. |
|
12 * |
|
13 * Permission to use or copy this software for any purpose is hereby granted |
|
14 * without fee, provided the above notices are retained on all copies. |
|
15 * Permission to modify the code and to distribute modified code is granted, |
|
16 * provided the above notices are retained, and a notice that the code was |
|
17 * modified is included with the above copyright notice. |
|
18 * |
|
19 */ |
|
20 |
|
21 // Implementation of the classes in header <strstream>. |
|
22 // WARNING: The classes defined in <strstream> are DEPRECATED. This |
|
23 // header is defined in section D.7.1 of the C++ standard, and it |
|
24 // MAY BE REMOVED in a future standard revision. You should use the |
|
25 // header <sstream> instead. |
|
26 |
|
27 #include "stlport_prefix.h" |
|
28 |
|
29 #include <strstream> |
|
30 #include <algorithm> |
|
31 #include <limits> |
|
32 |
|
33 _STLP_BEGIN_NAMESPACE |
|
34 |
|
35 // strstreambuf constructor, destructor. |
|
36 _STLP_DECLSPEC strstreambuf::strstreambuf(streamsize initial_capacity) |
|
37 : _M_alloc_fun(0), _M_free_fun(0), |
|
38 _M_dynamic(true), _M_frozen(false), _M_constant(false) { |
|
39 size_t n = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), |
|
40 (max)(initial_capacity, streamsize(16)))) |
|
41 : __STATIC_CAST(size_t, (max)(initial_capacity, streamsize(16))); |
|
42 |
|
43 char* buf = _M_alloc(n); |
|
44 if (buf) { |
|
45 setp(buf, buf + n); |
|
46 setg(buf, buf, buf); |
|
47 } |
|
48 } |
|
49 |
|
50 _STLP_DECLSPEC strstreambuf::strstreambuf(__alloc_fn alloc_f, __free_fn free_f) |
|
51 : _M_alloc_fun(alloc_f), _M_free_fun(free_f), |
|
52 _M_dynamic(true), _M_frozen(false), _M_constant(false) { |
|
53 size_t n = 16; |
|
54 |
|
55 char* buf = _M_alloc(n); |
|
56 if (buf) { |
|
57 setp(buf, buf + n); |
|
58 setg(buf, buf, buf); |
|
59 } |
|
60 } |
|
61 |
|
62 _STLP_DECLSPEC strstreambuf::strstreambuf(char* get, streamsize n, char* put) |
|
63 : _M_alloc_fun(0), _M_free_fun(0), |
|
64 _M_dynamic(false), _M_frozen(false), _M_constant(false) { |
|
65 _M_setup(get, put, n); |
|
66 } |
|
67 |
|
68 _STLP_DECLSPEC strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put) |
|
69 : _M_alloc_fun(0), _M_free_fun(0), |
|
70 _M_dynamic(false), _M_frozen(false), _M_constant(false) { |
|
71 _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n); |
|
72 } |
|
73 |
|
74 _STLP_DECLSPEC strstreambuf::strstreambuf(unsigned char* get, streamsize n, |
|
75 unsigned char* put) |
|
76 : _M_alloc_fun(0), _M_free_fun(0), |
|
77 _M_dynamic(false), _M_frozen(false), _M_constant(false) { |
|
78 _M_setup(__REINTERPRET_CAST(char*,get), __REINTERPRET_CAST(char*,put), n); |
|
79 } |
|
80 |
|
81 _STLP_DECLSPEC strstreambuf::strstreambuf(const char* get, streamsize n) |
|
82 : _M_alloc_fun(0), _M_free_fun(0), |
|
83 _M_dynamic(false), _M_frozen(false), _M_constant(true) { |
|
84 _M_setup(__CONST_CAST(char*,get), 0, n); |
|
85 } |
|
86 |
|
87 _STLP_DECLSPEC strstreambuf::strstreambuf(const signed char* get, streamsize n) |
|
88 : _M_alloc_fun(0), _M_free_fun(0), |
|
89 _M_dynamic(false), _M_frozen(false), _M_constant(true) { |
|
90 _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(signed char*,get)), 0, n); |
|
91 } |
|
92 |
|
93 _STLP_DECLSPEC strstreambuf::strstreambuf(const unsigned char* get, streamsize n) |
|
94 : _M_alloc_fun(0), _M_free_fun(0), |
|
95 _M_dynamic(false), _M_frozen(false), _M_constant(true) { |
|
96 _M_setup(__REINTERPRET_CAST(char*, __CONST_CAST(unsigned char*,get)), 0, n); |
|
97 } |
|
98 |
|
99 _STLP_DECLSPEC strstreambuf::~strstreambuf() { |
|
100 if (_M_dynamic && !_M_frozen) |
|
101 _M_free(eback()); |
|
102 } |
|
103 |
|
104 _STLP_DECLSPEC void strstreambuf::freeze(bool frozenflag) { |
|
105 if (_M_dynamic) |
|
106 _M_frozen = frozenflag; |
|
107 } |
|
108 |
|
109 _STLP_DECLSPEC char* strstreambuf::str() { |
|
110 freeze(true); |
|
111 return eback(); |
|
112 } |
|
113 |
|
114 _STLP_DECLSPEC int strstreambuf::pcount() const { |
|
115 return int(pptr() ? pptr() - pbase() : 0); |
|
116 } |
|
117 |
|
118 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::overflow(int_type c) { |
|
119 if (c == traits_type::eof()) |
|
120 return traits_type::not_eof(c); |
|
121 |
|
122 // Try to expand the buffer. |
|
123 if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) { |
|
124 ptrdiff_t old_size = epptr() - pbase(); |
|
125 ptrdiff_t new_size = (max)(2 * old_size, ptrdiff_t(1)); |
|
126 |
|
127 char* buf = _M_alloc(new_size); |
|
128 if (buf) { |
|
129 memcpy(buf, pbase(), old_size); |
|
130 |
|
131 char* old_buffer = pbase(); |
|
132 bool reposition_get = false; |
|
133 ptrdiff_t old_get_offset; |
|
134 if (gptr() != 0) { |
|
135 reposition_get = true; |
|
136 old_get_offset = gptr() - eback(); |
|
137 } |
|
138 |
|
139 setp(buf, buf + new_size); |
|
140 pbump((int)old_size); |
|
141 |
|
142 if (reposition_get) |
|
143 setg(buf, buf + old_get_offset, buf + (max)(old_get_offset, old_size)); |
|
144 |
|
145 _M_free(old_buffer); |
|
146 } |
|
147 } |
|
148 |
|
149 if (pptr() != epptr()) { |
|
150 *pptr() = traits_type::to_char_type(c); |
|
151 pbump(1); |
|
152 return c; |
|
153 } |
|
154 else |
|
155 return traits_type::eof(); |
|
156 } |
|
157 |
|
158 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::pbackfail(int_type c) { |
|
159 if (gptr() != eback()) { |
|
160 if (c == traits_type::eof()) { |
|
161 gbump(-1); |
|
162 return traits_type::not_eof(c); |
|
163 } |
|
164 else if (c == gptr()[-1]) { |
|
165 gbump(-1); |
|
166 return c; |
|
167 } |
|
168 else if (!_M_constant) { |
|
169 gbump(-1); |
|
170 *gptr() = traits_type::to_char_type(c); |
|
171 return c; |
|
172 } |
|
173 } |
|
174 |
|
175 return traits_type::eof(); |
|
176 } |
|
177 |
|
178 _STLP_DECLSPEC strstreambuf::int_type strstreambuf::underflow() { |
|
179 if (gptr() == egptr() && pptr() && pptr() > egptr()) |
|
180 setg(eback(), gptr(), pptr()); |
|
181 |
|
182 if (gptr() != egptr()) |
|
183 return (unsigned char) *gptr(); |
|
184 else |
|
185 return _Traits::eof(); |
|
186 } |
|
187 |
|
188 _STLP_DECLSPEC basic_streambuf<char, char_traits<char> >* |
|
189 strstreambuf::setbuf(char*, streamsize) { |
|
190 return this; |
|
191 } |
|
192 |
|
193 _STLP_DECLSPEC strstreambuf::pos_type |
|
194 strstreambuf::seekoff(off_type off, |
|
195 ios_base::seekdir dir, ios_base::openmode mode) { |
|
196 bool do_get = false; |
|
197 bool do_put = false; |
|
198 |
|
199 if ((mode & (ios_base::in | ios_base::out)) == |
|
200 (ios_base::in | ios_base::out) && |
|
201 (dir == ios_base::beg || dir == ios_base::end)) |
|
202 do_get = do_put = true; |
|
203 else if (mode & ios_base::in) |
|
204 do_get = true; |
|
205 else if (mode & ios_base::out) |
|
206 do_put = true; |
|
207 |
|
208 // !gptr() is here because, according to D.7.1 paragraph 4, the seekable |
|
209 // area is undefined if there is no get area. |
|
210 if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr()) |
|
211 return pos_type(off_type(-1)); |
|
212 |
|
213 char* seeklow = eback(); |
|
214 char* seekhigh = epptr() ? epptr() : egptr(); |
|
215 |
|
216 off_type newoff; |
|
217 switch(dir) { |
|
218 case ios_base::beg: |
|
219 newoff = 0; |
|
220 break; |
|
221 case ios_base::end: |
|
222 newoff = seekhigh - seeklow; |
|
223 break; |
|
224 case ios_base::cur: |
|
225 newoff = do_put ? pptr() - seeklow : gptr() - seeklow; |
|
226 break; |
|
227 default: |
|
228 return pos_type(off_type(-1)); |
|
229 } |
|
230 |
|
231 off += newoff; |
|
232 if (off < 0 || off > seekhigh - seeklow) |
|
233 return pos_type(off_type(-1)); |
|
234 |
|
235 if (do_put) { |
|
236 if (seeklow + __STATIC_CAST(ptrdiff_t, off) < pbase()) { |
|
237 setp(seeklow, epptr()); |
|
238 pbump((int)off); |
|
239 } |
|
240 else { |
|
241 setp(pbase(), epptr()); |
|
242 pbump((int)(off - (pbase() - seeklow))); |
|
243 } |
|
244 } |
|
245 if (do_get) { |
|
246 if (off <= egptr() - seeklow) |
|
247 setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), egptr()); |
|
248 else if (off <= pptr() - seeklow) |
|
249 setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), pptr()); |
|
250 else |
|
251 setg(seeklow, seeklow + __STATIC_CAST(ptrdiff_t, off), epptr()); |
|
252 } |
|
253 |
|
254 return pos_type(newoff); |
|
255 } |
|
256 |
|
257 _STLP_DECLSPEC strstreambuf::pos_type |
|
258 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode) { |
|
259 return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); |
|
260 } |
|
261 |
|
262 |
|
263 char* strstreambuf::_M_alloc(size_t n) { |
|
264 if (_M_alloc_fun) |
|
265 return __STATIC_CAST(char*,_M_alloc_fun(n)); |
|
266 else |
|
267 return new char[n]; |
|
268 } |
|
269 |
|
270 void strstreambuf::_M_free(char* p) { |
|
271 if (p) |
|
272 if (_M_free_fun) |
|
273 _M_free_fun(p); |
|
274 else |
|
275 delete[] p; |
|
276 } |
|
277 |
|
278 void strstreambuf::_M_setup(char* get, char* put, streamsize n) { |
|
279 if (get) { |
|
280 size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX); |
|
281 |
|
282 if (put) { |
|
283 setg(get, get, get + N); |
|
284 setp(put, put + N); |
|
285 } |
|
286 else { |
|
287 setg(get, get, get + N); |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 //---------------------------------------------------------------------- |
|
293 // Class istrstream |
|
294 |
|
295 _STLP_DECLSPEC istrstream::istrstream(char* s) |
|
296 : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0) { |
|
297 this->init(&_M_buf); |
|
298 } |
|
299 |
|
300 _STLP_DECLSPEC istrstream::istrstream(const char* s) |
|
301 : basic_istream<char, char_traits<char> >(0), _M_buf(s, 0) { |
|
302 this->init(&_M_buf); |
|
303 } |
|
304 |
|
305 _STLP_DECLSPEC istrstream::istrstream(char* s, streamsize n) |
|
306 : basic_istream<char, char_traits<char> >(0), _M_buf(s, n) { |
|
307 this->init(&_M_buf); |
|
308 } |
|
309 |
|
310 _STLP_DECLSPEC istrstream::istrstream(const char* s, streamsize n) |
|
311 : basic_istream<char, char_traits<char> >(0), _M_buf(s, n) { |
|
312 this->init(&_M_buf); |
|
313 } |
|
314 |
|
315 _STLP_DECLSPEC istrstream::~istrstream() {} |
|
316 |
|
317 _STLP_DECLSPEC strstreambuf* istrstream::rdbuf() const { |
|
318 return __CONST_CAST(strstreambuf*,&_M_buf); |
|
319 } |
|
320 |
|
321 _STLP_DECLSPEC char* istrstream::str() { return _M_buf.str(); } |
|
322 |
|
323 //---------------------------------------------------------------------- |
|
324 // Class ostrstream |
|
325 |
|
326 _STLP_DECLSPEC ostrstream::ostrstream() |
|
327 : basic_ostream<char, char_traits<char> >(0), _M_buf() { |
|
328 basic_ios<char, char_traits<char> >::init(&_M_buf); |
|
329 } |
|
330 |
|
331 _STLP_DECLSPEC ostrstream::ostrstream(char* s, int n, ios_base::openmode mode) |
|
332 : basic_ostream<char, char_traits<char> >(0), |
|
333 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) { |
|
334 basic_ios<char, char_traits<char> >::init(&_M_buf); |
|
335 } |
|
336 |
|
337 _STLP_DECLSPEC ostrstream::~ostrstream() {} |
|
338 |
|
339 _STLP_DECLSPEC strstreambuf* ostrstream::rdbuf() const { |
|
340 return __CONST_CAST(strstreambuf*,&_M_buf); |
|
341 } |
|
342 |
|
343 _STLP_DECLSPEC void ostrstream::freeze(bool freezeflag) { |
|
344 _M_buf.freeze(freezeflag); |
|
345 } |
|
346 |
|
347 _STLP_DECLSPEC char* ostrstream::str() { |
|
348 return _M_buf.str(); |
|
349 } |
|
350 |
|
351 _STLP_DECLSPEC int ostrstream::pcount() const { |
|
352 return _M_buf.pcount(); |
|
353 } |
|
354 |
|
355 |
|
356 //---------------------------------------------------------------------- |
|
357 // Class strstream |
|
358 |
|
359 _STLP_DECLSPEC strstream::strstream() |
|
360 : basic_iostream<char, char_traits<char> >(0), _M_buf() { |
|
361 basic_ios<char, char_traits<char> >::init(&_M_buf); |
|
362 } |
|
363 |
|
364 _STLP_DECLSPEC strstream::strstream(char* s, int n, ios_base::openmode mode) |
|
365 : basic_iostream<char, char_traits<char> >(0), |
|
366 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) { |
|
367 basic_ios<char, char_traits<char> >::init(&_M_buf); |
|
368 } |
|
369 |
|
370 _STLP_DECLSPEC strstream::~strstream() {} |
|
371 |
|
372 _STLP_DECLSPEC strstreambuf* strstream::rdbuf() const { |
|
373 return __CONST_CAST(strstreambuf*,&_M_buf); |
|
374 } |
|
375 |
|
376 _STLP_DECLSPEC void strstream::freeze(bool freezeflag) { |
|
377 _M_buf.freeze(freezeflag); |
|
378 } |
|
379 |
|
380 _STLP_DECLSPEC int strstream::pcount() const { |
|
381 return _M_buf.pcount(); |
|
382 } |
|
383 |
|
384 _STLP_DECLSPEC char* strstream::str() { |
|
385 return _M_buf.str(); |
|
386 } |
|
387 |
|
388 _STLP_END_NAMESPACE |
|
389 |
|
390 // Local Variables: |
|
391 // mode:C++ |
|
392 // End: |