strstream.cpp revision 232950
159191Skris//===------------------------ strstream.cpp -------------------------------===//
259191Skris//
359191Skris//                     The LLVM Compiler Infrastructure
459191Skris//
559191Skris// This file is dual licensed under the MIT and the University of Illinois Open
659191Skris// Source Licenses. See LICENSE.TXT for details.
759191Skris//
859191Skris//===----------------------------------------------------------------------===//
959191Skris
1059191Skris#include "strstream"
1159191Skris#include "algorithm"
1259191Skris#include "climits"
1359191Skris#include "cstring"
1459191Skris
1559191Skris_LIBCPP_BEGIN_NAMESPACE_STD
1659191Skris
1759191Skrisstrstreambuf::strstreambuf(streamsize __alsize)
1859191Skris    : __strmode_(__dynamic),
1959191Skris      __alsize_(__alsize),
2059191Skris      __palloc_(nullptr),
2159191Skris      __pfree_(nullptr)
2259191Skris{
2359191Skris}
24111147Snectar
2559191Skrisstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
2659191Skris    : __strmode_(__dynamic),
2759191Skris      __alsize_(__default_alsize),
2859191Skris      __palloc_(__palloc),
2959191Skris      __pfree_(__pfree)
3059191Skris{
3159191Skris}
3259191Skris
3359191Skrisvoid
3459191Skrisstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
3559191Skris{
3659191Skris    if (__n == 0)
3759191Skris        __n = static_cast<streamsize>(strlen(__gnext));
3859191Skris    else if (__n < 0)
3959191Skris        __n = INT_MAX;
4059191Skris    if (__pbeg == nullptr)
4159191Skris        setg(__gnext, __gnext, __gnext + __n);
4259191Skris    else
4359191Skris    {
4459191Skris        setg(__gnext, __gnext, __pbeg);
4559191Skris        setp(__pbeg, __pbeg + __n);
4659191Skris    }
4759191Skris}
4859191Skris
4959191Skrisstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
5059191Skris    : __strmode_(),
5159191Skris      __alsize_(__default_alsize),
5259191Skris      __palloc_(nullptr),
5359191Skris      __pfree_(nullptr)
5459191Skris{
5559191Skris    __init(__gnext, __n, __pbeg);
5659191Skris}
5759191Skris
5859191Skrisstrstreambuf::strstreambuf(const char* __gnext, streamsize __n)
5959191Skris    : __strmode_(__constant),
6059191Skris      __alsize_(__default_alsize),
6159191Skris      __palloc_(nullptr),
6259191Skris      __pfree_(nullptr)
6359191Skris{
6459191Skris    __init((char*)__gnext, __n, nullptr);
6559191Skris}
6659191Skris
6759191Skrisstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
6859191Skris    : __strmode_(),
6959191Skris      __alsize_(__default_alsize),
7059191Skris      __palloc_(nullptr),
7159191Skris      __pfree_(nullptr)
7259191Skris{
7359191Skris    __init((char*)__gnext, __n, (char*)__pbeg);
7459191Skris}
7559191Skris
7659191Skrisstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
7759191Skris    : __strmode_(__constant),
7859191Skris      __alsize_(__default_alsize),
7959191Skris      __palloc_(nullptr),
8059191Skris      __pfree_(nullptr)
8159191Skris{
8259191Skris    __init((char*)__gnext, __n, nullptr);
8359191Skris}
8459191Skris
8559191Skrisstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
8659191Skris    : __strmode_(),
8759191Skris      __alsize_(__default_alsize),
8859191Skris      __palloc_(nullptr),
8959191Skris      __pfree_(nullptr)
9059191Skris{
9159191Skris    __init((char*)__gnext, __n, (char*)__pbeg);
9259191Skris}
9359191Skris
9459191Skrisstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
9559191Skris    : __strmode_(__constant),
9659191Skris      __alsize_(__default_alsize),
9759191Skris      __palloc_(nullptr),
9859191Skris      __pfree_(nullptr)
9959191Skris{
10059191Skris    __init((char*)__gnext, __n, nullptr);
10159191Skris}
10259191Skris
10359191Skrisstrstreambuf::~strstreambuf()
10459191Skris{
10559191Skris    if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
10659191Skris    {
10759191Skris        if (__pfree_)
10859191Skris            __pfree_(eback());
10959191Skris        else
11059191Skris            delete [] eback();
11159191Skris    }
11259191Skris}
11359191Skris
11459191Skrisvoid
11559191Skrisstrstreambuf::swap(strstreambuf& __rhs)
11659191Skris{
11759191Skris    streambuf::swap(__rhs);
11859191Skris    _VSTD::swap(__strmode_, __rhs.__strmode_);
11959191Skris    _VSTD::swap(__alsize_, __rhs.__alsize_);
12059191Skris    _VSTD::swap(__palloc_, __rhs.__palloc_);
12159191Skris    _VSTD::swap(__pfree_, __rhs.__pfree_);
12259191Skris}
12359191Skris
12459191Skrisvoid
12559191Skrisstrstreambuf::freeze(bool __freezefl)
126111147Snectar{
127111147Snectar    if (__strmode_ & __dynamic)
128238405Sjkim    {
129111147Snectar        if (__freezefl)
130111147Snectar            __strmode_ |= __frozen;
131111147Snectar        else
132111147Snectar            __strmode_ &= ~__frozen;
13359191Skris    }
13459191Skris}
13559191Skris
13659191Skrischar*
13759191Skrisstrstreambuf::str()
13859191Skris{
13959191Skris    if (__strmode_ & __dynamic)
14059191Skris        __strmode_ |= __frozen;
14159191Skris    return eback();
14259191Skris}
14359191Skris
14459191Skrisint
14559191Skrisstrstreambuf::pcount() const
14659191Skris{
14759191Skris    return static_cast<int>(pptr() - pbase());
14859191Skris}
14959191Skris
15059191Skrisstrstreambuf::int_type
15159191Skrisstrstreambuf::overflow(int_type __c)
15259191Skris{
15359191Skris    if (__c == EOF)
15459191Skris        return int_type(0);
15559191Skris    if (pptr() == epptr())
15659191Skris    {
15759191Skris        if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
15859191Skris            return int_type(EOF);
15959191Skris        streamsize old_size = (epptr() ? epptr() : egptr()) - eback();
16059191Skris        streamsize new_size = max<streamsize>(__alsize_, 2*old_size);
16159191Skris        char* buf = nullptr;
16259191Skris        if (__palloc_)
16359191Skris            buf = static_cast<char*>(__palloc_(static_cast<size_t>(new_size)));
16459191Skris        else
16559191Skris            buf = new char[new_size];
16659191Skris        if (buf == nullptr)
16759191Skris            return int_type(EOF);
16859191Skris        memcpy(buf, eback(), static_cast<size_t>(old_size));
16959191Skris        ptrdiff_t ninp = gptr()  - eback();
17059191Skris        ptrdiff_t einp = egptr() - eback();
17159191Skris        ptrdiff_t nout = pptr()  - pbase();
17259191Skris        ptrdiff_t eout = epptr() - pbase();
17359191Skris        if (__strmode_ & __allocated)
17459191Skris        {
17559191Skris            if (__pfree_)
17659191Skris                __pfree_(eback());
17759191Skris            else
17859191Skris                delete [] eback();
17959191Skris        }
18059191Skris        setg(buf, buf + ninp, buf + einp);
18159191Skris        setp(buf + einp, buf + einp + eout);
18259191Skris        pbump(static_cast<int>(nout));
18359191Skris        __strmode_ |= __allocated;
18459191Skris    }
18559191Skris    *pptr() = static_cast<char>(__c);
18659191Skris    pbump(1);
18759191Skris    return int_type((unsigned char)__c);
18859191Skris}
18959191Skris
19059191Skrisstrstreambuf::int_type
19159191Skrisstrstreambuf::pbackfail(int_type __c)
19259191Skris{
19359191Skris    if (eback() == gptr())
19459191Skris        return EOF;
19559191Skris    if (__c == EOF)
19659191Skris    {
19759191Skris        gbump(-1);
19859191Skris        return int_type(0);
19959191Skris    }
20059191Skris    if (__strmode_ & __constant)
20159191Skris    {
20259191Skris        if (gptr()[-1] == static_cast<char>(__c))
20359191Skris        {
20459191Skris            gbump(-1);
20559191Skris            return __c;
20659191Skris        }
20759191Skris        return EOF;
20859191Skris    }
20959191Skris    gbump(-1);
21059191Skris    *gptr() = static_cast<char>(__c);
21159191Skris    return __c;
21259191Skris}
21359191Skris
21459191Skrisstrstreambuf::int_type
21559191Skrisstrstreambuf::underflow()
21659191Skris{
21759191Skris    if (gptr() == egptr())
21859191Skris    {
21959191Skris        if (egptr() >= pptr())
22059191Skris            return EOF;
22159191Skris        setg(eback(), gptr(), pptr());
22259191Skris    }
22359191Skris    return int_type((unsigned char)*gptr());
22459191Skris}
22559191Skris
22659191Skrisstrstreambuf::pos_type
22759191Skrisstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
22859191Skris{
22959191Skris    off_type __p(-1);
23059191Skris    bool pos_in = __which & ios::in;
23159191Skris    bool pos_out = __which & ios::out;
23259191Skris    bool legal = false;
23359191Skris    switch (__way)
23459191Skris    {
23559191Skris    case ios::beg:
23659191Skris    case ios::end:
23759191Skris        if (pos_in || pos_out)
23859191Skris            legal = true;
23959191Skris        break;
24059191Skris    case ios::cur:
24159191Skris        if (pos_in != pos_out)
24259191Skris            legal = true;
24359191Skris        break;
244    }
245    if (pos_in && gptr() == nullptr)
246        legal = false;
247    if (pos_out && pptr() == nullptr)
248        legal = false;
249    if (legal)
250    {
251        off_type newoff;
252        char* seekhigh = epptr() ? epptr() : egptr();
253        switch (__way)
254        {
255        case ios::beg:
256            newoff = 0;
257            break;
258        case ios::cur:
259            newoff = (pos_in ? gptr() : pptr()) - eback();
260            break;
261        case ios::end:
262            newoff = seekhigh - eback();
263            break;
264        }
265        newoff += __off;
266        if (0 <= newoff && newoff <= seekhigh - eback())
267        {
268            char* newpos = eback() + newoff;
269            if (pos_in)
270                setg(eback(), newpos, _VSTD::max(newpos, egptr()));
271            if (pos_out)
272            {
273                // min(pbase, newpos), newpos, epptr()
274                __off = epptr() - newpos;
275                setp(min(pbase(), newpos), epptr());
276                pbump(static_cast<int>((epptr() - pbase()) - __off));
277            }
278            __p = newoff;
279        }
280    }
281    return pos_type(__p);
282}
283
284strstreambuf::pos_type
285strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
286{
287    off_type __p(-1);
288    bool pos_in = __which & ios::in;
289    bool pos_out = __which & ios::out;
290    if (pos_in || pos_out)
291    {
292        if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
293        {
294            off_type newoff = __sp;
295            char* seekhigh = epptr() ? epptr() : egptr();
296            if (0 <= newoff && newoff <= seekhigh - eback())
297            {
298                char* newpos = eback() + newoff;
299                if (pos_in)
300                    setg(eback(), newpos, _VSTD::max(newpos, egptr()));
301                if (pos_out)
302                {
303                    // min(pbase, newpos), newpos, epptr()
304                    off_type temp = epptr() - newpos;
305                    setp(min(pbase(), newpos), epptr());
306                    pbump(static_cast<int>((epptr() - pbase()) - temp));
307                }
308                __p = newoff;
309            }
310        }
311    }
312    return pos_type(__p);
313}
314
315istrstream::~istrstream()
316{
317}
318
319ostrstream::~ostrstream()
320{
321}
322
323strstream::~strstream()
324{
325}
326
327_LIBCPP_END_NAMESPACE_STD
328