Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/src/strstream.cpp
35154 views
1
//===----------------------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include <__assert>
10
#include <__utility/unreachable.h>
11
#include <algorithm>
12
#include <climits>
13
#include <cstdlib>
14
#include <cstring>
15
#include <strstream>
16
17
_LIBCPP_PUSH_MACROS
18
#include <__undef_macros>
19
20
_LIBCPP_BEGIN_NAMESPACE_STD
21
22
strstreambuf::strstreambuf(streamsize __alsize)
23
: __strmode_(__dynamic), __alsize_(__alsize), __palloc_(nullptr), __pfree_(nullptr) {}
24
25
strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
26
: __strmode_(__dynamic), __alsize_(__default_alsize), __palloc_(__palloc), __pfree_(__pfree) {}
27
28
void strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) {
29
if (__n == 0)
30
__n = static_cast<streamsize>(strlen(__gnext));
31
else if (__n < 0)
32
__n = INT_MAX;
33
if (__pbeg == nullptr)
34
setg(__gnext, __gnext, __gnext + __n);
35
else {
36
setg(__gnext, __gnext, __pbeg);
37
setp(__pbeg, __pbeg + __n);
38
}
39
}
40
41
strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
42
: __strmode_(), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
43
__init(__gnext, __n, __pbeg);
44
}
45
46
strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
47
: __strmode_(__constant), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
48
__init(const_cast<char*>(__gnext), __n, nullptr);
49
}
50
51
strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
52
: __strmode_(), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
53
__init(const_cast<char*>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
54
}
55
56
strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
57
: __strmode_(__constant), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
58
__init(const_cast<char*>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
59
}
60
61
strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
62
: __strmode_(), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
63
__init(const_cast<char*>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
64
}
65
66
strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
67
: __strmode_(__constant), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {
68
__init(const_cast<char*>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
69
}
70
71
strstreambuf::~strstreambuf() {
72
if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) {
73
if (__pfree_)
74
__pfree_(eback());
75
else
76
delete[] eback();
77
}
78
}
79
80
void strstreambuf::swap(strstreambuf& __rhs) {
81
streambuf::swap(__rhs);
82
std::swap(__strmode_, __rhs.__strmode_);
83
std::swap(__alsize_, __rhs.__alsize_);
84
std::swap(__palloc_, __rhs.__palloc_);
85
std::swap(__pfree_, __rhs.__pfree_);
86
}
87
88
void strstreambuf::freeze(bool __freezefl) {
89
if (__strmode_ & __dynamic) {
90
if (__freezefl)
91
__strmode_ |= __frozen;
92
else
93
__strmode_ &= ~__frozen;
94
}
95
}
96
97
char* strstreambuf::str() {
98
if (__strmode_ & __dynamic)
99
__strmode_ |= __frozen;
100
return eback();
101
}
102
103
int strstreambuf::pcount() const { return static_cast<int>(pptr() - pbase()); }
104
105
strstreambuf::int_type strstreambuf::overflow(int_type __c) {
106
if (__c == EOF)
107
return int_type(0);
108
if (pptr() == epptr()) {
109
if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
110
return int_type(EOF);
111
size_t old_size = static_cast<size_t>((epptr() ? epptr() : egptr()) - eback());
112
size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2 * old_size);
113
if (new_size == 0)
114
new_size = __default_alsize;
115
char* buf = nullptr;
116
if (__palloc_)
117
buf = static_cast<char*>(__palloc_(new_size));
118
else
119
buf = new char[new_size];
120
if (buf == nullptr)
121
return int_type(EOF);
122
if (old_size != 0) {
123
_LIBCPP_ASSERT_INTERNAL(eback(), "strstreambuf::overflow reallocating but the get area is a null pointer");
124
memcpy(buf, eback(), static_cast<size_t>(old_size));
125
}
126
ptrdiff_t ninp = gptr() - eback();
127
ptrdiff_t einp = egptr() - eback();
128
ptrdiff_t nout = pptr() - pbase();
129
if (__strmode_ & __allocated) {
130
if (__pfree_)
131
__pfree_(eback());
132
else
133
delete[] eback();
134
}
135
setg(buf, buf + ninp, buf + einp);
136
setp(buf + einp, buf + new_size);
137
__pbump(nout);
138
__strmode_ |= __allocated;
139
}
140
*pptr() = static_cast<char>(__c);
141
pbump(1);
142
return int_type(static_cast<unsigned char>(__c));
143
}
144
145
strstreambuf::int_type strstreambuf::pbackfail(int_type __c) {
146
if (eback() == gptr())
147
return EOF;
148
if (__c == EOF) {
149
gbump(-1);
150
return int_type(0);
151
}
152
if (__strmode_ & __constant) {
153
if (gptr()[-1] == static_cast<char>(__c)) {
154
gbump(-1);
155
return __c;
156
}
157
return EOF;
158
}
159
gbump(-1);
160
*gptr() = static_cast<char>(__c);
161
return __c;
162
}
163
164
strstreambuf::int_type strstreambuf::underflow() {
165
if (gptr() == egptr()) {
166
if (egptr() >= pptr())
167
return EOF;
168
setg(eback(), gptr(), pptr());
169
}
170
return int_type(static_cast<unsigned char>(*gptr()));
171
}
172
173
strstreambuf::pos_type strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) {
174
bool pos_in = (__which & ios::in) != 0;
175
bool pos_out = (__which & ios::out) != 0;
176
switch (__way) {
177
case ios::beg:
178
case ios::end:
179
if (!pos_in && !pos_out)
180
return pos_type(off_type(-1));
181
break;
182
case ios::cur:
183
if (pos_in == pos_out)
184
return pos_type(off_type(-1));
185
break;
186
}
187
188
if (pos_in && gptr() == nullptr)
189
return pos_type(off_type(-1));
190
if (pos_out && pptr() == nullptr)
191
return pos_type(off_type(-1));
192
193
off_type newoff;
194
char* seekhigh = epptr() ? epptr() : egptr();
195
switch (__way) {
196
case ios::beg:
197
newoff = 0;
198
break;
199
case ios::cur:
200
newoff = (pos_in ? gptr() : pptr()) - eback();
201
break;
202
case ios::end:
203
newoff = seekhigh - eback();
204
break;
205
default:
206
__libcpp_unreachable();
207
}
208
newoff += __off;
209
if (newoff < 0 || newoff > seekhigh - eback())
210
return pos_type(off_type(-1));
211
212
char* newpos = eback() + newoff;
213
if (pos_in)
214
setg(eback(), newpos, std::max(newpos, egptr()));
215
if (pos_out) {
216
// min(pbase, newpos), newpos, epptr()
217
__off = epptr() - newpos;
218
setp(min(pbase(), newpos), epptr());
219
__pbump((epptr() - pbase()) - __off);
220
}
221
return pos_type(newoff);
222
}
223
224
strstreambuf::pos_type strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) {
225
bool pos_in = (__which & ios::in) != 0;
226
bool pos_out = (__which & ios::out) != 0;
227
if (!pos_in && !pos_out)
228
return pos_type(off_type(-1));
229
230
if ((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))
231
return pos_type(off_type(-1));
232
233
off_type newoff = __sp;
234
char* seekhigh = epptr() ? epptr() : egptr();
235
if (newoff < 0 || newoff > seekhigh - eback())
236
return pos_type(off_type(-1));
237
238
char* newpos = eback() + newoff;
239
if (pos_in)
240
setg(eback(), newpos, std::max(newpos, egptr()));
241
if (pos_out) {
242
// min(pbase, newpos), newpos, epptr()
243
off_type temp = epptr() - newpos;
244
setp(min(pbase(), newpos), epptr());
245
__pbump((epptr() - pbase()) - temp);
246
}
247
return pos_type(newoff);
248
}
249
250
istrstream::~istrstream() {}
251
252
ostrstream::~ostrstream() {}
253
254
strstream::~strstream() {}
255
256
_LIBCPP_END_NAMESPACE_STD
257
258
_LIBCPP_POP_MACROS
259
260