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