brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 7037419 Raw
259 lines · cpp
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-exception6//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_MACROS18#include <__undef_macros>19 20_LIBCPP_BEGIN_NAMESPACE_STD21 22strstreambuf::strstreambuf(streamsize __alsize)23    : __strmode_(__dynamic), __alsize_(__alsize), __palloc_(nullptr), __pfree_(nullptr) {}24 25strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))26    : __strmode_(__dynamic), __alsize_(__default_alsize), __palloc_(__palloc), __pfree_(__pfree) {}27 28void 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 41strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)42    : __strmode_(), __alsize_(__default_alsize), __palloc_(nullptr), __pfree_(nullptr) {43  __init(__gnext, __n, __pbeg);44}45 46strstreambuf::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 51strstreambuf::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 56strstreambuf::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 61strstreambuf::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 66strstreambuf::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 71strstreambuf::~strstreambuf() {72  if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) {73    if (__pfree_)74      __pfree_(eback());75    else76      delete[] eback();77  }78}79 80void 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 88void strstreambuf::freeze(bool __freezefl) {89  if (__strmode_ & __dynamic) {90    if (__freezefl)91      __strmode_ |= __frozen;92    else93      __strmode_ &= ~__frozen;94  }95}96 97char* strstreambuf::str() {98  if (__strmode_ & __dynamic)99    __strmode_ |= __frozen;100  return eback();101}102 103int strstreambuf::pcount() const { return static_cast<int>(pptr() - pbase()); }104 105strstreambuf::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    else119      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      else133        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 145strstreambuf::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 164strstreambuf::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 173strstreambuf::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 224strstreambuf::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 250istrstream::~istrstream() {}251 252ostrstream::~ostrstream() {}253 254strstream::~strstream() {}255 256_LIBCPP_END_NAMESPACE_STD257 258_LIBCPP_POP_MACROS259