1// -*- C++ -*-
2//===--------------------------- strstream --------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_STRSTREAM
11#define _LIBCPP_STRSTREAM
12
13/*
14    strstream synopsis
15
16class strstreambuf
17    : public basic_streambuf<char>
18{
19public:
20    explicit strstreambuf(streamsize alsize_arg = 0);
21    strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
22    strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0);
23    strstreambuf(const char* gnext_arg, streamsize n);
24
25    strstreambuf(signed char* gnext_arg, streamsize n, signed char* pbeg_arg = 0);
26    strstreambuf(const signed char* gnext_arg, streamsize n);
27    strstreambuf(unsigned char* gnext_arg, streamsize n, unsigned char* pbeg_arg = 0);
28    strstreambuf(const unsigned char* gnext_arg, streamsize n);
29
30    strstreambuf(strstreambuf&& rhs);
31    strstreambuf& operator=(strstreambuf&& rhs);
32
33    virtual ~strstreambuf();
34
35    void swap(strstreambuf& rhs);
36
37    void freeze(bool freezefl = true);
38    char* str();
39    int pcount() const;
40
41protected:
42    virtual int_type overflow (int_type c = EOF);
43    virtual int_type pbackfail(int_type c = EOF);
44    virtual int_type underflow();
45    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
46                             ios_base::openmode which = ios_base::in | ios_base::out);
47    virtual pos_type seekpos(pos_type sp,
48                             ios_base::openmode which = ios_base::in | ios_base::out);
49    virtual streambuf* setbuf(char* s, streamsize n);
50
51private:
52    typedef T1 strstate;                // exposition only
53    static const strstate allocated;    // exposition only
54    static const strstate constant;     // exposition only
55    static const strstate dynamic;      // exposition only
56    static const strstate frozen;       // exposition only
57    strstate strmode;                   // exposition only
58    streamsize alsize;                  // exposition only
59    void* (*palloc)(size_t);            // exposition only
60    void (*pfree)(void*);               // exposition only
61};
62
63class istrstream
64    : public basic_istream<char>
65{
66public:
67    explicit istrstream(const char* s);
68    explicit istrstream(char* s);
69    istrstream(const char* s, streamsize n);
70    istrstream(char* s, streamsize n);
71
72    virtual ~istrstream();
73
74    strstreambuf* rdbuf() const;
75    char *str();
76
77private:
78    strstreambuf sb; // exposition only
79};
80
81class ostrstream
82    : public basic_ostream<char>
83{
84public:
85    ostrstream();
86    ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);
87
88    virtual ~ostrstream();
89
90    strstreambuf* rdbuf() const;
91    void freeze(bool freezefl = true);
92    char* str();
93    int pcount() const;
94
95private:
96    strstreambuf sb; // exposition only
97};
98
99class strstream
100    : public basic_iostream<char>
101{
102public:
103    // Types
104    typedef char                        char_type;
105    typedef char_traits<char>::int_type int_type;
106    typedef char_traits<char>::pos_type pos_type;
107    typedef char_traits<char>::off_type off_type;
108
109    // constructors/destructor
110    strstream();
111    strstream(char* s, int n, ios_base::openmode mode = ios_base::in | ios_base::out);
112
113    virtual ~strstream();
114
115    // Members:
116    strstreambuf* rdbuf() const;
117    void freeze(bool freezefl = true);
118    int pcount() const;
119    char* str();
120
121private:
122    strstreambuf sb; // exposition only
123};
124
125}  // std
126
127*/
128
129#include <__config>
130#include <ostream>
131#include <istream>
132
133#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
134#pragma GCC system_header
135#endif
136
137_LIBCPP_BEGIN_NAMESPACE_STD
138
139class _LIBCPP_TYPE_VIS strstreambuf
140    : public streambuf
141{
142public:
143    explicit strstreambuf(streamsize __alsize = 0);
144    strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*));
145    strstreambuf(char* __gnext, streamsize __n, char* __pbeg = 0);
146    strstreambuf(const char* __gnext, streamsize __n);
147
148    strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg = 0);
149    strstreambuf(const signed char* __gnext, streamsize __n);
150    strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg = 0);
151    strstreambuf(const unsigned char* __gnext, streamsize __n);
152
153#ifndef _LIBCPP_CXX03_LANG
154    _LIBCPP_INLINE_VISIBILITY
155    strstreambuf(strstreambuf&& __rhs);
156    _LIBCPP_INLINE_VISIBILITY
157    strstreambuf& operator=(strstreambuf&& __rhs);
158#endif  // _LIBCPP_CXX03_LANG
159
160    virtual ~strstreambuf();
161
162    void swap(strstreambuf& __rhs);
163
164    void freeze(bool __freezefl = true);
165    char* str();
166    int pcount() const;
167
168protected:
169    virtual int_type overflow (int_type __c = EOF);
170    virtual int_type pbackfail(int_type __c = EOF);
171    virtual int_type underflow();
172    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
173                             ios_base::openmode __which = ios_base::in | ios_base::out);
174    virtual pos_type seekpos(pos_type __sp,
175                             ios_base::openmode __which = ios_base::in | ios_base::out);
176
177private:
178    typedef unsigned __mode_type;
179    static const __mode_type __allocated = 0x01;
180    static const __mode_type __constant  = 0x02;
181    static const __mode_type __dynamic   = 0x04;
182    static const __mode_type __frozen    = 0x08;
183    static const streamsize    __default_alsize = 4096;
184
185    __mode_type __strmode_;
186    streamsize __alsize_;
187    void* (*__palloc_)(size_t);
188    void (*__pfree_)(void*);
189
190    void __init(char* __gnext, streamsize __n, char* __pbeg);
191};
192
193#ifndef _LIBCPP_CXX03_LANG
194
195inline _LIBCPP_INLINE_VISIBILITY
196strstreambuf::strstreambuf(strstreambuf&& __rhs)
197    : streambuf(__rhs),
198      __strmode_(__rhs.__strmode_),
199      __alsize_(__rhs.__alsize_),
200      __palloc_(__rhs.__palloc_),
201      __pfree_(__rhs.__pfree_)
202{
203    __rhs.setg(nullptr, nullptr, nullptr);
204    __rhs.setp(nullptr, nullptr);
205}
206
207inline _LIBCPP_INLINE_VISIBILITY
208strstreambuf&
209strstreambuf::operator=(strstreambuf&& __rhs)
210{
211    if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
212    {
213        if (__pfree_)
214            __pfree_(eback());
215        else
216            delete [] eback();
217    }
218    streambuf::operator=(__rhs);
219    __strmode_ = __rhs.__strmode_;
220    __alsize_ = __rhs.__alsize_;
221    __palloc_ = __rhs.__palloc_;
222    __pfree_ = __rhs.__pfree_;
223    __rhs.setg(nullptr, nullptr, nullptr);
224    __rhs.setp(nullptr, nullptr);
225    return *this;
226}
227
228#endif  // _LIBCPP_CXX03_LANG
229
230class _LIBCPP_TYPE_VIS istrstream
231    : public istream
232{
233public:
234    _LIBCPP_INLINE_VISIBILITY
235    explicit istrstream(const char* __s)
236        : istream(&__sb_), __sb_(__s, 0) {}
237    _LIBCPP_INLINE_VISIBILITY
238    explicit istrstream(char* __s)
239        : istream(&__sb_), __sb_(__s, 0) {}
240    _LIBCPP_INLINE_VISIBILITY
241    istrstream(const char* __s, streamsize __n)
242        : istream(&__sb_), __sb_(__s, __n) {}
243    _LIBCPP_INLINE_VISIBILITY
244    istrstream(char* __s, streamsize __n)
245        : istream(&__sb_), __sb_(__s, __n) {}
246
247#ifndef _LIBCPP_CXX03_LANG
248    _LIBCPP_INLINE_VISIBILITY
249    istrstream(istrstream&& __rhs)
250        : istream(_VSTD::move(__rhs)),
251          __sb_(_VSTD::move(__rhs.__sb_))
252    {
253        istream::set_rdbuf(&__sb_);
254    }
255
256    _LIBCPP_INLINE_VISIBILITY
257    istrstream& operator=(istrstream&& __rhs)
258    {
259        istream::operator=(_VSTD::move(__rhs));
260        __sb_ = _VSTD::move(__rhs.__sb_);
261        return *this;
262    }
263#endif  // _LIBCPP_CXX03_LANG
264
265    virtual ~istrstream();
266
267    _LIBCPP_INLINE_VISIBILITY
268    void swap(istrstream& __rhs)
269    {
270        istream::swap(__rhs);
271        __sb_.swap(__rhs.__sb_);
272    }
273
274    _LIBCPP_INLINE_VISIBILITY
275    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
276    _LIBCPP_INLINE_VISIBILITY
277    char *str() {return __sb_.str();}
278
279private:
280    strstreambuf __sb_;
281};
282
283class _LIBCPP_TYPE_VIS ostrstream
284    : public ostream
285{
286public:
287    _LIBCPP_INLINE_VISIBILITY
288    ostrstream()
289        : ostream(&__sb_) {}
290    _LIBCPP_INLINE_VISIBILITY
291    ostrstream(char* __s, int __n, ios_base::openmode __mode = ios_base::out)
292        : ostream(&__sb_),
293          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))
294        {}
295
296#ifndef _LIBCPP_CXX03_LANG
297    _LIBCPP_INLINE_VISIBILITY
298    ostrstream(ostrstream&& __rhs)
299        : ostream(_VSTD::move(__rhs)),
300          __sb_(_VSTD::move(__rhs.__sb_))
301    {
302        ostream::set_rdbuf(&__sb_);
303    }
304
305    _LIBCPP_INLINE_VISIBILITY
306    ostrstream& operator=(ostrstream&& __rhs)
307    {
308        ostream::operator=(_VSTD::move(__rhs));
309        __sb_ = _VSTD::move(__rhs.__sb_);
310        return *this;
311    }
312#endif  // _LIBCPP_CXX03_LANG
313
314    virtual ~ostrstream();
315
316    _LIBCPP_INLINE_VISIBILITY
317    void swap(ostrstream& __rhs)
318    {
319        ostream::swap(__rhs);
320        __sb_.swap(__rhs.__sb_);
321    }
322
323    _LIBCPP_INLINE_VISIBILITY
324    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
325    _LIBCPP_INLINE_VISIBILITY
326    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}
327    _LIBCPP_INLINE_VISIBILITY
328    char* str()         {return __sb_.str();}
329    _LIBCPP_INLINE_VISIBILITY
330    int pcount() const  {return __sb_.pcount();}
331
332private:
333    strstreambuf __sb_; // exposition only
334};
335
336class _LIBCPP_TYPE_VIS strstream
337    : public iostream
338{
339public:
340    // Types
341    typedef char                        char_type;
342    typedef char_traits<char>::int_type int_type;
343    typedef char_traits<char>::pos_type pos_type;
344    typedef char_traits<char>::off_type off_type;
345
346    // constructors/destructor
347    _LIBCPP_INLINE_VISIBILITY
348    strstream()
349        : iostream(&__sb_) {}
350    _LIBCPP_INLINE_VISIBILITY
351    strstream(char* __s, int __n, ios_base::openmode __mode = ios_base::in | ios_base::out)
352        : iostream(&__sb_),
353          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))
354        {}
355
356#ifndef _LIBCPP_CXX03_LANG
357    _LIBCPP_INLINE_VISIBILITY
358    strstream(strstream&& __rhs)
359        : iostream(_VSTD::move(__rhs)),
360          __sb_(_VSTD::move(__rhs.__sb_))
361    {
362        iostream::set_rdbuf(&__sb_);
363    }
364
365    _LIBCPP_INLINE_VISIBILITY
366    strstream& operator=(strstream&& __rhs)
367    {
368        iostream::operator=(_VSTD::move(__rhs));
369        __sb_ = _VSTD::move(__rhs.__sb_);
370        return *this;
371    }
372#endif  // _LIBCPP_CXX03_LANG
373
374    virtual ~strstream();
375
376    _LIBCPP_INLINE_VISIBILITY
377    void swap(strstream& __rhs)
378    {
379        iostream::swap(__rhs);
380        __sb_.swap(__rhs.__sb_);
381    }
382
383    // Members:
384    _LIBCPP_INLINE_VISIBILITY
385    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
386    _LIBCPP_INLINE_VISIBILITY
387    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}
388    _LIBCPP_INLINE_VISIBILITY
389    int pcount() const {return __sb_.pcount();}
390    _LIBCPP_INLINE_VISIBILITY
391    char* str()        {return __sb_.str();}
392
393private:
394    strstreambuf __sb_; // exposition only
395};
396
397_LIBCPP_END_NAMESPACE_STD
398
399#endif  // _LIBCPP_STRSTREAM
400