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