stdio_streambuf.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 1999
  3. * Silicon Graphics Computer Systems, Inc.
  4. *
  5. * Copyright (c) 1999
  6. * Boris Fomitchev
  7. *
  8. * This material is provided "as is", with absolutely no warranty expressed
  9. * or implied. Any use is at your own risk.
  10. *
  11. * Permission to use or copy this software for any purpose is hereby granted
  12. * without fee, provided the above notices are retained on all copies.
  13. * Permission to modify the code and to distribute modified code is granted,
  14. * provided the above notices are retained, and a notice that the code was
  15. * modified is included with the above copyright notice.
  16. *
  17. */
  18. #include "stlport_prefix.h"
  19. #include "stdio_streambuf.h"
  20. #ifdef _STLP_UNIX
  21. # include <sys/types.h>
  22. # include <sys/stat.h>
  23. #endif
  24. #include <fstream>
  25. #include <limits>
  26. _STLP_BEGIN_NAMESPACE
  27. _STLP_MOVE_TO_PRIV_NAMESPACE
  28. // Compare with streamoff definition in stl/char_traits.h!
  29. #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
  30. (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))
  31. # if !defined (_STLP_MSVC) || (_STLP_MSVC < 1400) || defined(_STLP_WCE)
  32. # define FSEEK fseek
  33. # else
  34. # define FSEEK _fseeki64
  35. # endif
  36. # define FSETPOS fsetpos
  37. # define FGETPOS fgetpos
  38. # define FPOS_T fpos_t
  39. #else
  40. # define FSEEK fseeko64
  41. # define FSETPOS fsetpos64
  42. # define FGETPOS fgetpos64
  43. # define FPOS_T fpos64_t
  44. #endif
  45. //----------------------------------------------------------------------
  46. // Class stdio_streambuf_base
  47. stdio_streambuf_base::stdio_streambuf_base(FILE* file)
  48. : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
  49. _M_file(file)
  50. {}
  51. stdio_streambuf_base::~stdio_streambuf_base() {
  52. _STLP_VENDOR_CSTD::fflush(_M_file);
  53. }
  54. _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
  55. #ifdef _STLP_WCE
  56. // no buffering in windows ce .NET
  57. #else
  58. size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
  59. : __STATIC_CAST(size_t, n);
  60. _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
  61. #endif
  62. return this;
  63. }
  64. stdio_streambuf_base::pos_type
  65. stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
  66. ios_base::openmode /* mode */) {
  67. int whence;
  68. switch (dir) {
  69. case ios_base::beg:
  70. whence = SEEK_SET;
  71. break;
  72. case ios_base::cur:
  73. whence = SEEK_CUR;
  74. break;
  75. case ios_base::end:
  76. whence = SEEK_END;
  77. break;
  78. default:
  79. return pos_type(-1);
  80. }
  81. if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
  82. FPOS_T pos;
  83. FGETPOS(_M_file, &pos);
  84. // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
  85. // of a primitive type
  86. #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
  87. return pos_type((streamoff)pos.__pos);
  88. #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
  89. return pos_type(pos.__fpos_elem[ 0 ]);
  90. #elif defined (__EMX__)
  91. return pos_type((streamoff)pos._pos);
  92. #else
  93. return pos_type(pos);
  94. #endif
  95. }
  96. else
  97. return pos_type(-1);
  98. }
  99. stdio_streambuf_base::pos_type
  100. stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
  101. // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
  102. // of a primitive type
  103. #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
  104. FPOS_T p;
  105. p.__pos = pos;
  106. # ifdef _STLP_USE_UCLIBC
  107. # ifdef __STDIO_MBSTATE
  108. memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
  109. # endif
  110. # ifdef __STDIO_WIDE
  111. p.mblen_pending = 0;
  112. # endif
  113. # else
  114. memset( &(p.__state), 0, sizeof(p.__state) );
  115. # endif
  116. #elif defined (__MVS__) || defined (__OS400__)
  117. FPOS_T p;
  118. p.__fpos_elem[0] = pos;
  119. #elif defined (__EMX__)
  120. FPOS_T p;
  121. p._pos = pos;
  122. memset( &(p._mbstate), 0, sizeof(p._mbstate) );
  123. #else
  124. FPOS_T p(pos);
  125. #endif
  126. return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
  127. }
  128. int stdio_streambuf_base::sync() {
  129. return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
  130. }
  131. //----------------------------------------------------------------------
  132. // Class stdio_istreambuf
  133. stdio_istreambuf::~stdio_istreambuf() {}
  134. streamsize stdio_istreambuf::showmanyc()
  135. { return 0; }
  136. stdio_istreambuf::int_type stdio_istreambuf::underflow()
  137. {
  138. #ifdef _STLP_WCE
  139. int c = fgetc(_M_file);
  140. #else
  141. int c = getc(_M_file);
  142. #endif
  143. if (c != EOF) {
  144. _STLP_VENDOR_CSTD::ungetc(c, _M_file);
  145. return c;
  146. }
  147. else
  148. return traits_type::eof();
  149. }
  150. stdio_istreambuf::int_type stdio_istreambuf::uflow() {
  151. #ifdef _STLP_WCE
  152. int c = fgetc(_M_file);
  153. #else
  154. int c = getc(_M_file);
  155. #endif
  156. return c != EOF ? c : traits_type::eof();
  157. }
  158. stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
  159. if (c != traits_type::eof()) {
  160. int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
  161. return result != EOF ? result : traits_type::eof();
  162. }
  163. else{
  164. if (this->eback() < this->gptr()) {
  165. this->gbump(-1);
  166. return traits_type::not_eof(c);
  167. }
  168. else
  169. return traits_type::eof();
  170. }
  171. }
  172. //----------------------------------------------------------------------
  173. // Class stdio_ostreambuf
  174. stdio_ostreambuf::~stdio_ostreambuf() {}
  175. streamsize stdio_ostreambuf::showmanyc()
  176. { return -1; }
  177. stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
  178. // Write the existing buffer, without writing any additional character.
  179. if (c == traits_type::eof()) {
  180. // Do we have a buffer to write?
  181. ptrdiff_t unwritten = this->pptr() - this->pbase();
  182. if (unwritten != 0) {
  183. _STLP_VENDOR_CSTD::fflush(_M_file);
  184. // Test if the write succeeded.
  185. if (this->pptr() - this->pbase() < unwritten)
  186. return traits_type::not_eof(c);
  187. else
  188. return traits_type::eof();
  189. }
  190. // We always succeed if we don't have to do anything.
  191. else
  192. return traits_type::not_eof(c);
  193. }
  194. // Write the character c, and whatever else might be in the buffer.
  195. else {
  196. #ifdef _STLP_WCE
  197. int result = fputc(c, _M_file);
  198. #else
  199. int result = putc(c, _M_file);
  200. #endif
  201. return result != EOF ? result : traits_type::eof();
  202. }
  203. }
  204. _STLP_MOVE_TO_STD_NAMESPACE
  205. _STLP_END_NAMESPACE
  206. // Local Variables:
  207. // mode:C++
  208. // End: