14684ddb6SLionel Sambuc //===------------------------ strstream.cpp -------------------------------===//
24684ddb6SLionel Sambuc //
34684ddb6SLionel Sambuc // The LLVM Compiler Infrastructure
44684ddb6SLionel Sambuc //
54684ddb6SLionel Sambuc // This file is dual licensed under the MIT and the University of Illinois Open
64684ddb6SLionel Sambuc // Source Licenses. See LICENSE.TXT for details.
74684ddb6SLionel Sambuc //
84684ddb6SLionel Sambuc //===----------------------------------------------------------------------===//
94684ddb6SLionel Sambuc
104684ddb6SLionel Sambuc #include "strstream"
114684ddb6SLionel Sambuc #include "algorithm"
124684ddb6SLionel Sambuc #include "climits"
134684ddb6SLionel Sambuc #include "cstring"
144684ddb6SLionel Sambuc
154684ddb6SLionel Sambuc _LIBCPP_BEGIN_NAMESPACE_STD
164684ddb6SLionel Sambuc
strstreambuf(streamsize __alsize)174684ddb6SLionel Sambuc strstreambuf::strstreambuf(streamsize __alsize)
184684ddb6SLionel Sambuc : __strmode_(__dynamic),
194684ddb6SLionel Sambuc __alsize_(__alsize),
204684ddb6SLionel Sambuc __palloc_(nullptr),
214684ddb6SLionel Sambuc __pfree_(nullptr)
224684ddb6SLionel Sambuc {
234684ddb6SLionel Sambuc }
244684ddb6SLionel Sambuc
strstreambuf(void * (* __palloc)(size_t),void (* __pfree)(void *))254684ddb6SLionel Sambuc strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
264684ddb6SLionel Sambuc : __strmode_(__dynamic),
274684ddb6SLionel Sambuc __alsize_(__default_alsize),
284684ddb6SLionel Sambuc __palloc_(__palloc),
294684ddb6SLionel Sambuc __pfree_(__pfree)
304684ddb6SLionel Sambuc {
314684ddb6SLionel Sambuc }
324684ddb6SLionel Sambuc
334684ddb6SLionel Sambuc void
__init(char * __gnext,streamsize __n,char * __pbeg)344684ddb6SLionel Sambuc strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
354684ddb6SLionel Sambuc {
364684ddb6SLionel Sambuc if (__n == 0)
374684ddb6SLionel Sambuc __n = static_cast<streamsize>(strlen(__gnext));
384684ddb6SLionel Sambuc else if (__n < 0)
394684ddb6SLionel Sambuc __n = INT_MAX;
404684ddb6SLionel Sambuc if (__pbeg == nullptr)
414684ddb6SLionel Sambuc setg(__gnext, __gnext, __gnext + __n);
424684ddb6SLionel Sambuc else
434684ddb6SLionel Sambuc {
444684ddb6SLionel Sambuc setg(__gnext, __gnext, __pbeg);
454684ddb6SLionel Sambuc setp(__pbeg, __pbeg + __n);
464684ddb6SLionel Sambuc }
474684ddb6SLionel Sambuc }
484684ddb6SLionel Sambuc
strstreambuf(char * __gnext,streamsize __n,char * __pbeg)494684ddb6SLionel Sambuc strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
504684ddb6SLionel Sambuc : __strmode_(),
514684ddb6SLionel Sambuc __alsize_(__default_alsize),
524684ddb6SLionel Sambuc __palloc_(nullptr),
534684ddb6SLionel Sambuc __pfree_(nullptr)
544684ddb6SLionel Sambuc {
554684ddb6SLionel Sambuc __init(__gnext, __n, __pbeg);
564684ddb6SLionel Sambuc }
574684ddb6SLionel Sambuc
strstreambuf(const char * __gnext,streamsize __n)584684ddb6SLionel Sambuc strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
594684ddb6SLionel Sambuc : __strmode_(__constant),
604684ddb6SLionel Sambuc __alsize_(__default_alsize),
614684ddb6SLionel Sambuc __palloc_(nullptr),
624684ddb6SLionel Sambuc __pfree_(nullptr)
634684ddb6SLionel Sambuc {
64*0a6a1f1dSLionel Sambuc __init(const_cast<char *>(__gnext), __n, nullptr);
654684ddb6SLionel Sambuc }
664684ddb6SLionel Sambuc
strstreambuf(signed char * __gnext,streamsize __n,signed char * __pbeg)674684ddb6SLionel Sambuc strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
684684ddb6SLionel Sambuc : __strmode_(),
694684ddb6SLionel Sambuc __alsize_(__default_alsize),
704684ddb6SLionel Sambuc __palloc_(nullptr),
714684ddb6SLionel Sambuc __pfree_(nullptr)
724684ddb6SLionel Sambuc {
73*0a6a1f1dSLionel Sambuc __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
744684ddb6SLionel Sambuc }
754684ddb6SLionel Sambuc
strstreambuf(const signed char * __gnext,streamsize __n)764684ddb6SLionel Sambuc strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
774684ddb6SLionel Sambuc : __strmode_(__constant),
784684ddb6SLionel Sambuc __alsize_(__default_alsize),
794684ddb6SLionel Sambuc __palloc_(nullptr),
804684ddb6SLionel Sambuc __pfree_(nullptr)
814684ddb6SLionel Sambuc {
82*0a6a1f1dSLionel Sambuc __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
834684ddb6SLionel Sambuc }
844684ddb6SLionel Sambuc
strstreambuf(unsigned char * __gnext,streamsize __n,unsigned char * __pbeg)854684ddb6SLionel Sambuc strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
864684ddb6SLionel Sambuc : __strmode_(),
874684ddb6SLionel Sambuc __alsize_(__default_alsize),
884684ddb6SLionel Sambuc __palloc_(nullptr),
894684ddb6SLionel Sambuc __pfree_(nullptr)
904684ddb6SLionel Sambuc {
91*0a6a1f1dSLionel Sambuc __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
924684ddb6SLionel Sambuc }
934684ddb6SLionel Sambuc
strstreambuf(const unsigned char * __gnext,streamsize __n)944684ddb6SLionel Sambuc strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
954684ddb6SLionel Sambuc : __strmode_(__constant),
964684ddb6SLionel Sambuc __alsize_(__default_alsize),
974684ddb6SLionel Sambuc __palloc_(nullptr),
984684ddb6SLionel Sambuc __pfree_(nullptr)
994684ddb6SLionel Sambuc {
100*0a6a1f1dSLionel Sambuc __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
1014684ddb6SLionel Sambuc }
1024684ddb6SLionel Sambuc
~strstreambuf()1034684ddb6SLionel Sambuc strstreambuf::~strstreambuf()
1044684ddb6SLionel Sambuc {
1054684ddb6SLionel Sambuc if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
1064684ddb6SLionel Sambuc {
1074684ddb6SLionel Sambuc if (__pfree_)
1084684ddb6SLionel Sambuc __pfree_(eback());
1094684ddb6SLionel Sambuc else
1104684ddb6SLionel Sambuc delete [] eback();
1114684ddb6SLionel Sambuc }
1124684ddb6SLionel Sambuc }
1134684ddb6SLionel Sambuc
1144684ddb6SLionel Sambuc void
swap(strstreambuf & __rhs)1154684ddb6SLionel Sambuc strstreambuf::swap(strstreambuf& __rhs)
1164684ddb6SLionel Sambuc {
1174684ddb6SLionel Sambuc streambuf::swap(__rhs);
1184684ddb6SLionel Sambuc _VSTD::swap(__strmode_, __rhs.__strmode_);
1194684ddb6SLionel Sambuc _VSTD::swap(__alsize_, __rhs.__alsize_);
1204684ddb6SLionel Sambuc _VSTD::swap(__palloc_, __rhs.__palloc_);
1214684ddb6SLionel Sambuc _VSTD::swap(__pfree_, __rhs.__pfree_);
1224684ddb6SLionel Sambuc }
1234684ddb6SLionel Sambuc
1244684ddb6SLionel Sambuc void
freeze(bool __freezefl)1254684ddb6SLionel Sambuc strstreambuf::freeze(bool __freezefl)
1264684ddb6SLionel Sambuc {
1274684ddb6SLionel Sambuc if (__strmode_ & __dynamic)
1284684ddb6SLionel Sambuc {
1294684ddb6SLionel Sambuc if (__freezefl)
1304684ddb6SLionel Sambuc __strmode_ |= __frozen;
1314684ddb6SLionel Sambuc else
1324684ddb6SLionel Sambuc __strmode_ &= ~__frozen;
1334684ddb6SLionel Sambuc }
1344684ddb6SLionel Sambuc }
1354684ddb6SLionel Sambuc
1364684ddb6SLionel Sambuc char*
str()1374684ddb6SLionel Sambuc strstreambuf::str()
1384684ddb6SLionel Sambuc {
1394684ddb6SLionel Sambuc if (__strmode_ & __dynamic)
1404684ddb6SLionel Sambuc __strmode_ |= __frozen;
1414684ddb6SLionel Sambuc return eback();
1424684ddb6SLionel Sambuc }
1434684ddb6SLionel Sambuc
1444684ddb6SLionel Sambuc int
pcount() const1454684ddb6SLionel Sambuc strstreambuf::pcount() const
1464684ddb6SLionel Sambuc {
1474684ddb6SLionel Sambuc return static_cast<int>(pptr() - pbase());
1484684ddb6SLionel Sambuc }
1494684ddb6SLionel Sambuc
1504684ddb6SLionel Sambuc strstreambuf::int_type
overflow(int_type __c)1514684ddb6SLionel Sambuc strstreambuf::overflow(int_type __c)
1524684ddb6SLionel Sambuc {
1534684ddb6SLionel Sambuc if (__c == EOF)
1544684ddb6SLionel Sambuc return int_type(0);
1554684ddb6SLionel Sambuc if (pptr() == epptr())
1564684ddb6SLionel Sambuc {
1574684ddb6SLionel Sambuc if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
1584684ddb6SLionel Sambuc return int_type(EOF);
1594684ddb6SLionel Sambuc size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
1604684ddb6SLionel Sambuc size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
1614684ddb6SLionel Sambuc if (new_size == 0)
1624684ddb6SLionel Sambuc new_size = __default_alsize;
1634684ddb6SLionel Sambuc char* buf = nullptr;
1644684ddb6SLionel Sambuc if (__palloc_)
1654684ddb6SLionel Sambuc buf = static_cast<char*>(__palloc_(new_size));
1664684ddb6SLionel Sambuc else
1674684ddb6SLionel Sambuc buf = new char[new_size];
1684684ddb6SLionel Sambuc if (buf == nullptr)
1694684ddb6SLionel Sambuc return int_type(EOF);
1704684ddb6SLionel Sambuc memcpy(buf, eback(), static_cast<size_t>(old_size));
1714684ddb6SLionel Sambuc ptrdiff_t ninp = gptr() - eback();
1724684ddb6SLionel Sambuc ptrdiff_t einp = egptr() - eback();
1734684ddb6SLionel Sambuc ptrdiff_t nout = pptr() - pbase();
1744684ddb6SLionel Sambuc ptrdiff_t eout = epptr() - pbase();
1754684ddb6SLionel Sambuc if (__strmode_ & __allocated)
1764684ddb6SLionel Sambuc {
1774684ddb6SLionel Sambuc if (__pfree_)
1784684ddb6SLionel Sambuc __pfree_(eback());
1794684ddb6SLionel Sambuc else
1804684ddb6SLionel Sambuc delete [] eback();
1814684ddb6SLionel Sambuc }
1824684ddb6SLionel Sambuc setg(buf, buf + ninp, buf + einp);
1834684ddb6SLionel Sambuc setp(buf + einp, buf + einp + eout);
1844684ddb6SLionel Sambuc pbump(static_cast<int>(nout));
1854684ddb6SLionel Sambuc __strmode_ |= __allocated;
1864684ddb6SLionel Sambuc }
1874684ddb6SLionel Sambuc *pptr() = static_cast<char>(__c);
1884684ddb6SLionel Sambuc pbump(1);
189*0a6a1f1dSLionel Sambuc return int_type(static_cast<unsigned char>(__c));
1904684ddb6SLionel Sambuc }
1914684ddb6SLionel Sambuc
1924684ddb6SLionel Sambuc strstreambuf::int_type
pbackfail(int_type __c)1934684ddb6SLionel Sambuc strstreambuf::pbackfail(int_type __c)
1944684ddb6SLionel Sambuc {
1954684ddb6SLionel Sambuc if (eback() == gptr())
1964684ddb6SLionel Sambuc return EOF;
1974684ddb6SLionel Sambuc if (__c == EOF)
1984684ddb6SLionel Sambuc {
1994684ddb6SLionel Sambuc gbump(-1);
2004684ddb6SLionel Sambuc return int_type(0);
2014684ddb6SLionel Sambuc }
2024684ddb6SLionel Sambuc if (__strmode_ & __constant)
2034684ddb6SLionel Sambuc {
2044684ddb6SLionel Sambuc if (gptr()[-1] == static_cast<char>(__c))
2054684ddb6SLionel Sambuc {
2064684ddb6SLionel Sambuc gbump(-1);
2074684ddb6SLionel Sambuc return __c;
2084684ddb6SLionel Sambuc }
2094684ddb6SLionel Sambuc return EOF;
2104684ddb6SLionel Sambuc }
2114684ddb6SLionel Sambuc gbump(-1);
2124684ddb6SLionel Sambuc *gptr() = static_cast<char>(__c);
2134684ddb6SLionel Sambuc return __c;
2144684ddb6SLionel Sambuc }
2154684ddb6SLionel Sambuc
2164684ddb6SLionel Sambuc strstreambuf::int_type
underflow()2174684ddb6SLionel Sambuc strstreambuf::underflow()
2184684ddb6SLionel Sambuc {
2194684ddb6SLionel Sambuc if (gptr() == egptr())
2204684ddb6SLionel Sambuc {
2214684ddb6SLionel Sambuc if (egptr() >= pptr())
2224684ddb6SLionel Sambuc return EOF;
2234684ddb6SLionel Sambuc setg(eback(), gptr(), pptr());
2244684ddb6SLionel Sambuc }
225*0a6a1f1dSLionel Sambuc return int_type(static_cast<unsigned char>(*gptr()));
2264684ddb6SLionel Sambuc }
2274684ddb6SLionel Sambuc
2284684ddb6SLionel Sambuc strstreambuf::pos_type
seekoff(off_type __off,ios_base::seekdir __way,ios_base::openmode __which)2294684ddb6SLionel Sambuc strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
2304684ddb6SLionel Sambuc {
2314684ddb6SLionel Sambuc off_type __p(-1);
2324684ddb6SLionel Sambuc bool pos_in = (__which & ios::in) != 0;
2334684ddb6SLionel Sambuc bool pos_out = (__which & ios::out) != 0;
2344684ddb6SLionel Sambuc bool legal = false;
2354684ddb6SLionel Sambuc switch (__way)
2364684ddb6SLionel Sambuc {
2374684ddb6SLionel Sambuc case ios::beg:
2384684ddb6SLionel Sambuc case ios::end:
2394684ddb6SLionel Sambuc if (pos_in || pos_out)
2404684ddb6SLionel Sambuc legal = true;
2414684ddb6SLionel Sambuc break;
2424684ddb6SLionel Sambuc case ios::cur:
2434684ddb6SLionel Sambuc if (pos_in != pos_out)
2444684ddb6SLionel Sambuc legal = true;
2454684ddb6SLionel Sambuc break;
2464684ddb6SLionel Sambuc }
2474684ddb6SLionel Sambuc if (pos_in && gptr() == nullptr)
2484684ddb6SLionel Sambuc legal = false;
2494684ddb6SLionel Sambuc if (pos_out && pptr() == nullptr)
2504684ddb6SLionel Sambuc legal = false;
2514684ddb6SLionel Sambuc if (legal)
2524684ddb6SLionel Sambuc {
2534684ddb6SLionel Sambuc off_type newoff;
2544684ddb6SLionel Sambuc char* seekhigh = epptr() ? epptr() : egptr();
2554684ddb6SLionel Sambuc switch (__way)
2564684ddb6SLionel Sambuc {
2574684ddb6SLionel Sambuc case ios::beg:
2584684ddb6SLionel Sambuc newoff = 0;
2594684ddb6SLionel Sambuc break;
2604684ddb6SLionel Sambuc case ios::cur:
2614684ddb6SLionel Sambuc newoff = (pos_in ? gptr() : pptr()) - eback();
2624684ddb6SLionel Sambuc break;
2634684ddb6SLionel Sambuc case ios::end:
2644684ddb6SLionel Sambuc newoff = seekhigh - eback();
2654684ddb6SLionel Sambuc break;
2664684ddb6SLionel Sambuc }
2674684ddb6SLionel Sambuc newoff += __off;
2684684ddb6SLionel Sambuc if (0 <= newoff && newoff <= seekhigh - eback())
2694684ddb6SLionel Sambuc {
2704684ddb6SLionel Sambuc char* newpos = eback() + newoff;
2714684ddb6SLionel Sambuc if (pos_in)
2724684ddb6SLionel Sambuc setg(eback(), newpos, _VSTD::max(newpos, egptr()));
2734684ddb6SLionel Sambuc if (pos_out)
2744684ddb6SLionel Sambuc {
2754684ddb6SLionel Sambuc // min(pbase, newpos), newpos, epptr()
2764684ddb6SLionel Sambuc __off = epptr() - newpos;
2774684ddb6SLionel Sambuc setp(min(pbase(), newpos), epptr());
2784684ddb6SLionel Sambuc pbump(static_cast<int>((epptr() - pbase()) - __off));
2794684ddb6SLionel Sambuc }
2804684ddb6SLionel Sambuc __p = newoff;
2814684ddb6SLionel Sambuc }
2824684ddb6SLionel Sambuc }
2834684ddb6SLionel Sambuc return pos_type(__p);
2844684ddb6SLionel Sambuc }
2854684ddb6SLionel Sambuc
2864684ddb6SLionel Sambuc strstreambuf::pos_type
seekpos(pos_type __sp,ios_base::openmode __which)2874684ddb6SLionel Sambuc strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
2884684ddb6SLionel Sambuc {
2894684ddb6SLionel Sambuc off_type __p(-1);
2904684ddb6SLionel Sambuc bool pos_in = (__which & ios::in) != 0;
2914684ddb6SLionel Sambuc bool pos_out = (__which & ios::out) != 0;
2924684ddb6SLionel Sambuc if (pos_in || pos_out)
2934684ddb6SLionel Sambuc {
2944684ddb6SLionel Sambuc if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
2954684ddb6SLionel Sambuc {
2964684ddb6SLionel Sambuc off_type newoff = __sp;
2974684ddb6SLionel Sambuc char* seekhigh = epptr() ? epptr() : egptr();
2984684ddb6SLionel Sambuc if (0 <= newoff && newoff <= seekhigh - eback())
2994684ddb6SLionel Sambuc {
3004684ddb6SLionel Sambuc char* newpos = eback() + newoff;
3014684ddb6SLionel Sambuc if (pos_in)
3024684ddb6SLionel Sambuc setg(eback(), newpos, _VSTD::max(newpos, egptr()));
3034684ddb6SLionel Sambuc if (pos_out)
3044684ddb6SLionel Sambuc {
3054684ddb6SLionel Sambuc // min(pbase, newpos), newpos, epptr()
3064684ddb6SLionel Sambuc off_type temp = epptr() - newpos;
3074684ddb6SLionel Sambuc setp(min(pbase(), newpos), epptr());
3084684ddb6SLionel Sambuc pbump(static_cast<int>((epptr() - pbase()) - temp));
3094684ddb6SLionel Sambuc }
3104684ddb6SLionel Sambuc __p = newoff;
3114684ddb6SLionel Sambuc }
3124684ddb6SLionel Sambuc }
3134684ddb6SLionel Sambuc }
3144684ddb6SLionel Sambuc return pos_type(__p);
3154684ddb6SLionel Sambuc }
3164684ddb6SLionel Sambuc
~istrstream()3174684ddb6SLionel Sambuc istrstream::~istrstream()
3184684ddb6SLionel Sambuc {
3194684ddb6SLionel Sambuc }
3204684ddb6SLionel Sambuc
~ostrstream()3214684ddb6SLionel Sambuc ostrstream::~ostrstream()
3224684ddb6SLionel Sambuc {
3234684ddb6SLionel Sambuc }
3244684ddb6SLionel Sambuc
~strstream()3254684ddb6SLionel Sambuc strstream::~strstream()
3264684ddb6SLionel Sambuc {
3274684ddb6SLionel Sambuc }
3284684ddb6SLionel Sambuc
3294684ddb6SLionel Sambuc _LIBCPP_END_NAMESPACE_STD
330