home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / stdio_streambuf.cpp < prev    next >
C/C++ Source or Header  |  2002-01-10  |  6KB  |  234 lines

  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>
  20.  
  21. #ifdef _STLP_UNIX
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #endif /* __unix */
  25.  
  26. #include <stl/_fstream.h>
  27. #include "fstream_impl.h"
  28.  
  29. # if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WINCE)
  30. # if defined (__BORLANDC__)
  31. // #  include <cio.h>
  32. #  include <cfcntl.h>
  33. # else
  34. #  include <io.h>
  35. #  include <fcntl.h>
  36. # endif
  37.  
  38. #  include <sys/stat.h>
  39. # endif
  40.  
  41. __SGI_BEGIN_NAMESPACE
  42. //----------------------------------------------------------------------
  43. // Class stdio_streambuf_base
  44.  
  45. stdio_streambuf_base::stdio_streambuf_base(FILE* file)
  46.   : _STLP_STD::basic_streambuf<char, _STLP_STD::char_traits<char> >(file, 0),
  47.     _M_file(file)
  48. {}
  49.  
  50. stdio_streambuf_base::~stdio_streambuf_base()
  51. {
  52.   _STLP_VENDOR_CSTD::fflush(_M_file);
  53. }
  54.  
  55. _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n)
  56. {
  57.   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, n);
  58.   return this;
  59. }
  60.  
  61. stdio_streambuf_base::pos_type
  62. stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
  63.                               ios_base::openmode /* mode */)
  64. {
  65.   int whence;
  66.   switch(dir) {
  67.   case ios_base::beg:
  68.     whence = SEEK_SET;
  69.     break;
  70.   case ios_base::cur:
  71.     whence = SEEK_CUR;
  72.     break;
  73.   case ios_base::end:
  74.     whence = SEEK_END;
  75.     break;
  76.   default:
  77.     return pos_type(-1);
  78.   }
  79.       
  80.   if (_STLP_VENDOR_CSTD::fseek(_M_file, off, whence) == 0) {
  81.     fpos_t pos;
  82.     _STLP_VENDOR_CSTD::fgetpos(_M_file, &pos);
  83.     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
  84.     // of a primitive type
  85. #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
  86.     return pos_type((streamoff)pos.__pos);
  87. #elif defined(__ISCPP__) || defined(__MVS__) || (__OS400__)
  88.      return pos_type(pos.__fpos_elem[ 0 ]);
  89. #else
  90.     return pos_type(pos);
  91. #endif
  92.   }
  93.   else
  94.     return pos_type(-1);
  95. }
  96.  
  97.  
  98. stdio_streambuf_base::pos_type
  99. stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */)   // dwa 4/27/00 - suppress unused parameter warning
  100. {
  101.  
  102.   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
  103.   // of a primitive type
  104. #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
  105.   fpos_t p;
  106.   p.__pos = pos;
  107.   memset( &(p.__state), 0, sizeof(p.__state) );
  108. #elif defined(__MVS__) || (__OS400__)
  109.   fpos_t p;
  110.   p.__fpos_elem[0] = pos;
  111. #else
  112.   fpos_t p(pos);
  113. #endif
  114.  
  115.   if (_STLP_VENDOR_CSTD::fsetpos(_M_file, &p) == 0)
  116.     return pos;
  117.   else
  118.     return pos_type(-1);
  119. }
  120.  
  121. int stdio_streambuf_base::sync()
  122. {
  123.   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
  124. }
  125.  
  126. //----------------------------------------------------------------------
  127. // Class stdio_istreambuf
  128.  
  129. stdio_istreambuf::~stdio_istreambuf() {}
  130.  
  131. streamsize stdio_istreambuf::showmanyc()
  132. {
  133.   if (feof(_M_file)) 
  134.     return -1;
  135.   else {
  136.     int fd = _FILE_fd(_M_file);
  137. # ifdef _STLP_USE_WIN32_IO
  138.     // in this case, __file_size works with Win32 fh , not libc one
  139.     streamoff size;
  140.     struct stat buf;
  141. # ifdef __BORLANDC__
  142.     if(fstat(fd, &buf) == 0 && S_ISREG( buf.st_mode ) )
  143. # else
  144.     if(fstat(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
  145. # endif
  146.       size = ( buf.st_size > 0  ? buf.st_size : 0);
  147.     else
  148.       size = 0;
  149. # else
  150.     streamoff size = _SgI::__file_size(fd);
  151. # endif
  152.     // fbp : we can use ftell as this flavour always use stdio.
  153.     long pos = _STLP_VENDOR_CSTD::ftell(_M_file);
  154.     return pos >= 0 && size > pos ? size - pos : 0;
  155.   }
  156. }
  157.  
  158. stdio_istreambuf::int_type stdio_istreambuf::underflow()
  159. {
  160.   int c = getc(_M_file);
  161.   if (c != EOF) {
  162.     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
  163.     return c;
  164.   }
  165.   else
  166.     return traits_type::eof();
  167. }
  168.  
  169. stdio_istreambuf::int_type stdio_istreambuf::uflow()
  170. {
  171.   int c = getc(_M_file);
  172.   return c != EOF ? c : traits_type::eof();
  173. }
  174.  
  175. stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c)
  176. {
  177.   if (c != traits_type::eof()) {
  178.     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
  179.     return result != EOF ? result : traits_type::eof();
  180.   }
  181.   else{
  182.     if (this->eback() < this->gptr()) {
  183.       this->gbump(-1);
  184.       return traits_type::not_eof(c);
  185.     }
  186.     else
  187.       return traits_type::eof();
  188.   }
  189. }
  190.  
  191. //----------------------------------------------------------------------
  192. // Class stdio_ostreambuf
  193.  
  194. stdio_ostreambuf::~stdio_ostreambuf() {}
  195.  
  196. streamsize stdio_ostreambuf::showmanyc()
  197. {
  198.   return -1;
  199. }
  200.  
  201. stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c)
  202. {
  203.   // Write the existing buffer, without writing any additional character.
  204.   if (c == traits_type::eof()) {
  205.     // Do we have a buffer to write?
  206.     ptrdiff_t unwritten = this->pptr() - this->pbase();
  207.     if (unwritten != 0) {
  208.       _STLP_VENDOR_CSTD::fflush(_M_file);
  209.       // Test if the write succeeded.
  210.       if (this->pptr() - this->pbase() < unwritten)
  211.         return traits_type::not_eof(c);
  212.       else
  213.         return traits_type::eof();
  214.     }
  215.  
  216.     // We always succeed if we don't have to do anything.
  217.     else
  218.       return traits_type::not_eof(c);
  219.   }
  220.  
  221.   // Write the character c, and whatever else might be in the buffer.
  222.   else {
  223.     int result = putc(c, _M_file);
  224.     return result != EOF ? result : traits_type::eof();
  225.   }
  226. }
  227.  
  228. __SGI_END_NAMESPACE
  229.  
  230. // Local Variables:
  231. // mode:C++
  232. // End:
  233.  
  234.