1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 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_STREAMBUF 11#define _LIBCPP_STREAMBUF 12 13/* 14 streambuf synopsis 15 16namespace std 17{ 18 19template <class charT, class traits = char_traits<charT> > 20class basic_streambuf 21{ 22public: 23 // types: 24 typedef charT char_type; 25 typedef traits traits_type; 26 typedef typename traits_type::int_type int_type; 27 typedef typename traits_type::pos_type pos_type; 28 typedef typename traits_type::off_type off_type; 29 30 virtual ~basic_streambuf(); 31 32 // 27.6.2.2.1 locales: 33 locale pubimbue(const locale& loc); 34 locale getloc() const; 35 36 // 27.6.2.2.2 buffer and positioning: 37 basic_streambuf* pubsetbuf(char_type* s, streamsize n); 38 pos_type pubseekoff(off_type off, ios_base::seekdir way, 39 ios_base::openmode which = ios_base::in | ios_base::out); 40 pos_type pubseekpos(pos_type sp, 41 ios_base::openmode which = ios_base::in | ios_base::out); 42 int pubsync(); 43 44 // Get and put areas: 45 // 27.6.2.2.3 Get area: 46 streamsize in_avail(); 47 int_type snextc(); 48 int_type sbumpc(); 49 int_type sgetc(); 50 streamsize sgetn(char_type* s, streamsize n); 51 52 // 27.6.2.2.4 Putback: 53 int_type sputbackc(char_type c); 54 int_type sungetc(); 55 56 // 27.6.2.2.5 Put area: 57 int_type sputc(char_type c); 58 streamsize sputn(const char_type* s, streamsize n); 59 60protected: 61 basic_streambuf(); 62 basic_streambuf(const basic_streambuf& rhs); 63 basic_streambuf& operator=(const basic_streambuf& rhs); 64 void swap(basic_streambuf& rhs); 65 66 // 27.6.2.3.2 Get area: 67 char_type* eback() const; 68 char_type* gptr() const; 69 char_type* egptr() const; 70 void gbump(int n); 71 void setg(char_type* gbeg, char_type* gnext, char_type* gend); 72 73 // 27.6.2.3.3 Put area: 74 char_type* pbase() const; 75 char_type* pptr() const; 76 char_type* epptr() const; 77 void pbump(int n); 78 void setp(char_type* pbeg, char_type* pend); 79 80 // 27.6.2.4 virtual functions: 81 // 27.6.2.4.1 Locales: 82 virtual void imbue(const locale& loc); 83 84 // 27.6.2.4.2 Buffer management and positioning: 85 virtual basic_streambuf* setbuf(char_type* s, streamsize n); 86 virtual pos_type seekoff(off_type off, ios_base::seekdir way, 87 ios_base::openmode which = ios_base::in | ios_base::out); 88 virtual pos_type seekpos(pos_type sp, 89 ios_base::openmode which = ios_base::in | ios_base::out); 90 virtual int sync(); 91 92 // 27.6.2.4.3 Get area: 93 virtual streamsize showmanyc(); 94 virtual streamsize xsgetn(char_type* s, streamsize n); 95 virtual int_type underflow(); 96 virtual int_type uflow(); 97 98 // 27.6.2.4.4 Putback: 99 virtual int_type pbackfail(int_type c = traits_type::eof()); 100 101 // 27.6.2.4.5 Put area: 102 virtual streamsize xsputn(const char_type* s, streamsize n); 103 virtual int_type overflow (int_type c = traits_type::eof()); 104}; 105 106} // std 107 108*/ 109 110#include <__config> 111#include <cstdint> 112#include <ios> 113#include <iosfwd> 114#include <version> 115 116#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 117#pragma GCC system_header 118#endif 119 120_LIBCPP_PUSH_MACROS 121#include <__undef_macros> 122 123_LIBCPP_BEGIN_NAMESPACE_STD 124 125template <class _CharT, class _Traits> 126class _LIBCPP_TEMPLATE_VIS basic_streambuf 127{ 128public: 129 // types: 130 typedef _CharT char_type; 131 typedef _Traits traits_type; 132 typedef typename traits_type::int_type int_type; 133 typedef typename traits_type::pos_type pos_type; 134 typedef typename traits_type::off_type off_type; 135 136 static_assert((is_same<_CharT, typename traits_type::char_type>::value), 137 "traits_type::char_type must be the same type as CharT"); 138 139 virtual ~basic_streambuf(); 140 141 // 27.6.2.2.1 locales: 142 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 143 locale pubimbue(const locale& __loc) { 144 imbue(__loc); 145 locale __r = __loc_; 146 __loc_ = __loc; 147 return __r; 148 } 149 150 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 151 locale getloc() const { return __loc_; } 152 153 // 27.6.2.2.2 buffer and positioning: 154 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 155 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) 156 { return setbuf(__s, __n); } 157 158 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 159 pos_type pubseekoff(off_type __off, ios_base::seekdir __way, 160 ios_base::openmode __which = ios_base::in | ios_base::out) 161 { return seekoff(__off, __way, __which); } 162 163 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 164 pos_type pubseekpos(pos_type __sp, 165 ios_base::openmode __which = ios_base::in | ios_base::out) 166 { return seekpos(__sp, __which); } 167 168 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 169 int pubsync() { return sync(); } 170 171 // Get and put areas: 172 // 27.6.2.2.3 Get area: 173 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 174 streamsize in_avail() { 175 if (__ninp_ < __einp_) 176 return static_cast<streamsize>(__einp_ - __ninp_); 177 return showmanyc(); 178 } 179 180 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 181 int_type snextc() { 182 if (sbumpc() == traits_type::eof()) 183 return traits_type::eof(); 184 return sgetc(); 185 } 186 187 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 188 int_type sbumpc() { 189 if (__ninp_ == __einp_) 190 return uflow(); 191 return traits_type::to_int_type(*__ninp_++); 192 } 193 194 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 195 int_type sgetc() { 196 if (__ninp_ == __einp_) 197 return underflow(); 198 return traits_type::to_int_type(*__ninp_); 199 } 200 201 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 202 streamsize sgetn(char_type* __s, streamsize __n) 203 { return xsgetn(__s, __n); } 204 205 // 27.6.2.2.4 Putback: 206 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 207 int_type sputbackc(char_type __c) { 208 if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1])) 209 return pbackfail(traits_type::to_int_type(__c)); 210 return traits_type::to_int_type(*--__ninp_); 211 } 212 213 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 214 int_type sungetc() { 215 if (__binp_ == __ninp_) 216 return pbackfail(); 217 return traits_type::to_int_type(*--__ninp_); 218 } 219 220 // 27.6.2.2.5 Put area: 221 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 222 int_type sputc(char_type __c) { 223 if (__nout_ == __eout_) 224 return overflow(traits_type::to_int_type(__c)); 225 *__nout_++ = __c; 226 return traits_type::to_int_type(__c); 227 } 228 229 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 230 streamsize sputn(const char_type* __s, streamsize __n) 231 { return xsputn(__s, __n); } 232 233protected: 234 basic_streambuf(); 235 basic_streambuf(const basic_streambuf& __rhs); 236 basic_streambuf& operator=(const basic_streambuf& __rhs); 237 void swap(basic_streambuf& __rhs); 238 239 // 27.6.2.3.2 Get area: 240 _LIBCPP_INLINE_VISIBILITY char_type* eback() const {return __binp_;} 241 _LIBCPP_INLINE_VISIBILITY char_type* gptr() const {return __ninp_;} 242 _LIBCPP_INLINE_VISIBILITY char_type* egptr() const {return __einp_;} 243 244 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 245 void gbump(int __n) { __ninp_ += __n; } 246 247 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 248 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) { 249 __binp_ = __gbeg; 250 __ninp_ = __gnext; 251 __einp_ = __gend; 252 } 253 254 // 27.6.2.3.3 Put area: 255 _LIBCPP_INLINE_VISIBILITY char_type* pbase() const {return __bout_;} 256 _LIBCPP_INLINE_VISIBILITY char_type* pptr() const {return __nout_;} 257 _LIBCPP_INLINE_VISIBILITY char_type* epptr() const {return __eout_;} 258 259 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 260 void pbump(int __n) { __nout_ += __n; } 261 262 _LIBCPP_INLINE_VISIBILITY 263 void __pbump(streamsize __n) { __nout_ += __n; } 264 265 inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 266 void setp(char_type* __pbeg, char_type* __pend) { 267 __bout_ = __nout_ = __pbeg; 268 __eout_ = __pend; 269 } 270 271 // 27.6.2.4 virtual functions: 272 // 27.6.2.4.1 Locales: 273 virtual void imbue(const locale& __loc); 274 275 // 27.6.2.4.2 Buffer management and positioning: 276 virtual basic_streambuf* setbuf(char_type* __s, streamsize __n); 277 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 278 ios_base::openmode __which = ios_base::in | ios_base::out); 279 virtual pos_type seekpos(pos_type __sp, 280 ios_base::openmode __which = ios_base::in | ios_base::out); 281 virtual int sync(); 282 283 // 27.6.2.4.3 Get area: 284 virtual streamsize showmanyc(); 285 virtual streamsize xsgetn(char_type* __s, streamsize __n); 286 virtual int_type underflow(); 287 virtual int_type uflow(); 288 289 // 27.6.2.4.4 Putback: 290 virtual int_type pbackfail(int_type __c = traits_type::eof()); 291 292 // 27.6.2.4.5 Put area: 293 virtual streamsize xsputn(const char_type* __s, streamsize __n); 294 virtual int_type overflow(int_type __c = traits_type::eof()); 295 296private: 297 locale __loc_; 298 char_type* __binp_; 299 char_type* __ninp_; 300 char_type* __einp_; 301 char_type* __bout_; 302 char_type* __nout_; 303 char_type* __eout_; 304}; 305 306template <class _CharT, class _Traits> 307basic_streambuf<_CharT, _Traits>::~basic_streambuf() 308{ 309} 310 311template <class _CharT, class _Traits> 312basic_streambuf<_CharT, _Traits>::basic_streambuf() 313 : __binp_(nullptr), 314 __ninp_(nullptr), 315 __einp_(nullptr), 316 __bout_(nullptr), 317 __nout_(nullptr), 318 __eout_(nullptr) 319{ 320} 321 322template <class _CharT, class _Traits> 323basic_streambuf<_CharT, _Traits>::basic_streambuf(const basic_streambuf& __sb) 324 : __loc_(__sb.__loc_), 325 __binp_(__sb.__binp_), 326 __ninp_(__sb.__ninp_), 327 __einp_(__sb.__einp_), 328 __bout_(__sb.__bout_), 329 __nout_(__sb.__nout_), 330 __eout_(__sb.__eout_) 331{ 332} 333 334template <class _CharT, class _Traits> 335basic_streambuf<_CharT, _Traits>& 336basic_streambuf<_CharT, _Traits>::operator=(const basic_streambuf& __sb) 337{ 338 __loc_ = __sb.__loc_; 339 __binp_ = __sb.__binp_; 340 __ninp_ = __sb.__ninp_; 341 __einp_ = __sb.__einp_; 342 __bout_ = __sb.__bout_; 343 __nout_ = __sb.__nout_; 344 __eout_ = __sb.__eout_; 345 return *this; 346} 347 348template <class _CharT, class _Traits> 349void 350basic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb) 351{ 352 _VSTD::swap(__loc_, __sb.__loc_); 353 _VSTD::swap(__binp_, __sb.__binp_); 354 _VSTD::swap(__ninp_, __sb.__ninp_); 355 _VSTD::swap(__einp_, __sb.__einp_); 356 _VSTD::swap(__bout_, __sb.__bout_); 357 _VSTD::swap(__nout_, __sb.__nout_); 358 _VSTD::swap(__eout_, __sb.__eout_); 359} 360 361template <class _CharT, class _Traits> 362void 363basic_streambuf<_CharT, _Traits>::imbue(const locale&) 364{ 365} 366 367template <class _CharT, class _Traits> 368basic_streambuf<_CharT, _Traits>* 369basic_streambuf<_CharT, _Traits>::setbuf(char_type*, streamsize) 370{ 371 return this; 372} 373 374template <class _CharT, class _Traits> 375typename basic_streambuf<_CharT, _Traits>::pos_type 376basic_streambuf<_CharT, _Traits>::seekoff(off_type, ios_base::seekdir, 377 ios_base::openmode) 378{ 379 return pos_type(off_type(-1)); 380} 381 382template <class _CharT, class _Traits> 383typename basic_streambuf<_CharT, _Traits>::pos_type 384basic_streambuf<_CharT, _Traits>::seekpos(pos_type, ios_base::openmode) 385{ 386 return pos_type(off_type(-1)); 387} 388 389template <class _CharT, class _Traits> 390int 391basic_streambuf<_CharT, _Traits>::sync() 392{ 393 return 0; 394} 395 396template <class _CharT, class _Traits> 397streamsize 398basic_streambuf<_CharT, _Traits>::showmanyc() 399{ 400 return 0; 401} 402 403template <class _CharT, class _Traits> 404streamsize 405basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) 406{ 407 const int_type __eof = traits_type::eof(); 408 int_type __c; 409 streamsize __i = 0; 410 while(__i < __n) 411 { 412 if (__ninp_ < __einp_) 413 { 414 const streamsize __len = _VSTD::min(static_cast<streamsize>(INT_MAX), 415 _VSTD::min(__einp_ - __ninp_, __n - __i)); 416 traits_type::copy(__s, __ninp_, __len); 417 __s += __len; 418 __i += __len; 419 this->gbump(__len); 420 } 421 else if ((__c = uflow()) != __eof) 422 { 423 *__s = traits_type::to_char_type(__c); 424 ++__s; 425 ++__i; 426 } 427 else 428 break; 429 } 430 return __i; 431} 432 433template <class _CharT, class _Traits> 434typename basic_streambuf<_CharT, _Traits>::int_type 435basic_streambuf<_CharT, _Traits>::underflow() 436{ 437 return traits_type::eof(); 438} 439 440template <class _CharT, class _Traits> 441typename basic_streambuf<_CharT, _Traits>::int_type 442basic_streambuf<_CharT, _Traits>::uflow() 443{ 444 if (underflow() == traits_type::eof()) 445 return traits_type::eof(); 446 return traits_type::to_int_type(*__ninp_++); 447} 448 449template <class _CharT, class _Traits> 450typename basic_streambuf<_CharT, _Traits>::int_type 451basic_streambuf<_CharT, _Traits>::pbackfail(int_type) 452{ 453 return traits_type::eof(); 454} 455 456template <class _CharT, class _Traits> 457streamsize 458basic_streambuf<_CharT, _Traits>::xsputn(const char_type* __s, streamsize __n) 459{ 460 streamsize __i = 0; 461 int_type __eof = traits_type::eof(); 462 while( __i < __n) 463 { 464 if (__nout_ >= __eout_) 465 { 466 if (overflow(traits_type::to_int_type(*__s)) == __eof) 467 break; 468 ++__s; 469 ++__i; 470 } 471 else 472 { 473 streamsize __chunk_size = _VSTD::min(__eout_ - __nout_, __n - __i); 474 traits_type::copy(__nout_, __s, __chunk_size); 475 __nout_ += __chunk_size; 476 __s += __chunk_size; 477 __i += __chunk_size; 478 } 479 } 480 return __i; 481} 482 483template <class _CharT, class _Traits> 484typename basic_streambuf<_CharT, _Traits>::int_type 485basic_streambuf<_CharT, _Traits>::overflow(int_type) 486{ 487 return traits_type::eof(); 488} 489 490_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>) 491_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>) 492 493_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>) 494_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>) 495 496_LIBCPP_END_NAMESPACE_STD 497 498_LIBCPP_POP_MACROS 499 500#endif // _LIBCPP_STREAMBUF 501