strstream.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. //===------------------------ strstream.cpp -------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // Not SGX compatible.
  10. #include "__config"
  11. #if !defined(_LIBCPP_SGX_CONFIG)
  12. #include "strstream"
  13. #include "algorithm"
  14. #include "climits"
  15. #include "cstring"
  16. #include "__debug"
  17. _LIBCPP_BEGIN_NAMESPACE_STD
  18. strstreambuf::strstreambuf(streamsize __alsize)
  19. : __strmode_(__dynamic),
  20. __alsize_(__alsize),
  21. __palloc_(nullptr),
  22. __pfree_(nullptr)
  23. {
  24. }
  25. strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
  26. : __strmode_(__dynamic),
  27. __alsize_(__default_alsize),
  28. __palloc_(__palloc),
  29. __pfree_(__pfree)
  30. {
  31. }
  32. void
  33. strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
  34. {
  35. if (__n == 0)
  36. __n = static_cast<streamsize>(strlen(__gnext));
  37. else if (__n < 0)
  38. __n = INT_MAX;
  39. if (__pbeg == nullptr)
  40. setg(__gnext, __gnext, __gnext + __n);
  41. else
  42. {
  43. setg(__gnext, __gnext, __pbeg);
  44. setp(__pbeg, __pbeg + __n);
  45. }
  46. }
  47. strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
  48. : __strmode_(),
  49. __alsize_(__default_alsize),
  50. __palloc_(nullptr),
  51. __pfree_(nullptr)
  52. {
  53. __init(__gnext, __n, __pbeg);
  54. }
  55. strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
  56. : __strmode_(__constant),
  57. __alsize_(__default_alsize),
  58. __palloc_(nullptr),
  59. __pfree_(nullptr)
  60. {
  61. __init(const_cast<char *>(__gnext), __n, nullptr);
  62. }
  63. strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
  64. : __strmode_(),
  65. __alsize_(__default_alsize),
  66. __palloc_(nullptr),
  67. __pfree_(nullptr)
  68. {
  69. __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
  70. }
  71. strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
  72. : __strmode_(__constant),
  73. __alsize_(__default_alsize),
  74. __palloc_(nullptr),
  75. __pfree_(nullptr)
  76. {
  77. __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
  78. }
  79. strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
  80. : __strmode_(),
  81. __alsize_(__default_alsize),
  82. __palloc_(nullptr),
  83. __pfree_(nullptr)
  84. {
  85. __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
  86. }
  87. strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
  88. : __strmode_(__constant),
  89. __alsize_(__default_alsize),
  90. __palloc_(nullptr),
  91. __pfree_(nullptr)
  92. {
  93. __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
  94. }
  95. strstreambuf::~strstreambuf()
  96. {
  97. if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
  98. {
  99. if (__pfree_)
  100. __pfree_(eback());
  101. else
  102. delete [] eback();
  103. }
  104. }
  105. void
  106. strstreambuf::swap(strstreambuf& __rhs)
  107. {
  108. streambuf::swap(__rhs);
  109. _VSTD::swap(__strmode_, __rhs.__strmode_);
  110. _VSTD::swap(__alsize_, __rhs.__alsize_);
  111. _VSTD::swap(__palloc_, __rhs.__palloc_);
  112. _VSTD::swap(__pfree_, __rhs.__pfree_);
  113. }
  114. void
  115. strstreambuf::freeze(bool __freezefl)
  116. {
  117. if (__strmode_ & __dynamic)
  118. {
  119. if (__freezefl)
  120. __strmode_ |= __frozen;
  121. else
  122. __strmode_ &= ~__frozen;
  123. }
  124. }
  125. char*
  126. strstreambuf::str()
  127. {
  128. if (__strmode_ & __dynamic)
  129. __strmode_ |= __frozen;
  130. return eback();
  131. }
  132. int
  133. strstreambuf::pcount() const
  134. {
  135. return static_cast<int>(pptr() - pbase());
  136. }
  137. strstreambuf::int_type
  138. strstreambuf::overflow(int_type __c)
  139. {
  140. if (__c == EOF)
  141. return int_type(0);
  142. if (pptr() == epptr())
  143. {
  144. if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
  145. return int_type(EOF);
  146. size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
  147. size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
  148. if (new_size == 0)
  149. new_size = __default_alsize;
  150. char* buf = nullptr;
  151. if (__palloc_)
  152. buf = static_cast<char*>(__palloc_(new_size));
  153. else
  154. buf = new char[new_size];
  155. if (buf == nullptr)
  156. return int_type(EOF);
  157. if (old_size != 0) {
  158. _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
  159. memcpy(buf, eback(), static_cast<size_t>(old_size));
  160. }
  161. ptrdiff_t ninp = gptr() - eback();
  162. ptrdiff_t einp = egptr() - eback();
  163. ptrdiff_t nout = pptr() - pbase();
  164. if (__strmode_ & __allocated)
  165. {
  166. if (__pfree_)
  167. __pfree_(eback());
  168. else
  169. delete [] eback();
  170. }
  171. setg(buf, buf + ninp, buf + einp);
  172. setp(buf + einp, buf + new_size);
  173. pbump(static_cast<int>(nout));
  174. __strmode_ |= __allocated;
  175. }
  176. *pptr() = static_cast<char>(__c);
  177. pbump(1);
  178. return int_type(static_cast<unsigned char>(__c));
  179. }
  180. strstreambuf::int_type
  181. strstreambuf::pbackfail(int_type __c)
  182. {
  183. if (eback() == gptr())
  184. return EOF;
  185. if (__c == EOF)
  186. {
  187. gbump(-1);
  188. return int_type(0);
  189. }
  190. if (__strmode_ & __constant)
  191. {
  192. if (gptr()[-1] == static_cast<char>(__c))
  193. {
  194. gbump(-1);
  195. return __c;
  196. }
  197. return EOF;
  198. }
  199. gbump(-1);
  200. *gptr() = static_cast<char>(__c);
  201. return __c;
  202. }
  203. strstreambuf::int_type
  204. strstreambuf::underflow()
  205. {
  206. if (gptr() == egptr())
  207. {
  208. if (egptr() >= pptr())
  209. return EOF;
  210. setg(eback(), gptr(), pptr());
  211. }
  212. return int_type(static_cast<unsigned char>(*gptr()));
  213. }
  214. strstreambuf::pos_type
  215. strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
  216. {
  217. off_type __p(-1);
  218. bool pos_in = (__which & ios::in) != 0;
  219. bool pos_out = (__which & ios::out) != 0;
  220. bool legal = false;
  221. switch (__way)
  222. {
  223. case ios::beg:
  224. case ios::end:
  225. if (pos_in || pos_out)
  226. legal = true;
  227. break;
  228. case ios::cur:
  229. if (pos_in != pos_out)
  230. legal = true;
  231. break;
  232. }
  233. if (pos_in && gptr() == nullptr)
  234. legal = false;
  235. if (pos_out && pptr() == nullptr)
  236. legal = false;
  237. if (legal)
  238. {
  239. off_type newoff;
  240. char* seekhigh = epptr() ? epptr() : egptr();
  241. switch (__way)
  242. {
  243. case ios::beg:
  244. newoff = 0;
  245. break;
  246. case ios::cur:
  247. newoff = (pos_in ? gptr() : pptr()) - eback();
  248. break;
  249. case ios::end:
  250. newoff = seekhigh - eback();
  251. break;
  252. }
  253. newoff += __off;
  254. if (0 <= newoff && newoff <= seekhigh - eback())
  255. {
  256. char* newpos = eback() + newoff;
  257. if (pos_in)
  258. setg(eback(), newpos, _VSTD::max(newpos, egptr()));
  259. if (pos_out)
  260. {
  261. // min(pbase, newpos), newpos, epptr()
  262. __off = epptr() - newpos;
  263. setp(min(pbase(), newpos), epptr());
  264. pbump(static_cast<int>((epptr() - pbase()) - __off));
  265. }
  266. __p = newoff;
  267. }
  268. }
  269. return pos_type(__p);
  270. }
  271. strstreambuf::pos_type
  272. strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
  273. {
  274. off_type __p(-1);
  275. bool pos_in = (__which & ios::in) != 0;
  276. bool pos_out = (__which & ios::out) != 0;
  277. if (pos_in || pos_out)
  278. {
  279. if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
  280. {
  281. off_type newoff = __sp;
  282. char* seekhigh = epptr() ? epptr() : egptr();
  283. if (0 <= newoff && newoff <= seekhigh - eback())
  284. {
  285. char* newpos = eback() + newoff;
  286. if (pos_in)
  287. setg(eback(), newpos, _VSTD::max(newpos, egptr()));
  288. if (pos_out)
  289. {
  290. // min(pbase, newpos), newpos, epptr()
  291. off_type temp = epptr() - newpos;
  292. setp(min(pbase(), newpos), epptr());
  293. pbump(static_cast<int>((epptr() - pbase()) - temp));
  294. }
  295. __p = newoff;
  296. }
  297. }
  298. }
  299. return pos_type(__p);
  300. }
  301. istrstream::~istrstream()
  302. {
  303. }
  304. ostrstream::~ostrstream()
  305. {
  306. }
  307. strstream::~strstream()
  308. {
  309. }
  310. _LIBCPP_END_NAMESPACE_STD
  311. #endif // !defined(_LIBCPP_SGX_CONFIG)