/home/ntakagi/work/STLport-5.1.5/src/stdio_streambuf.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 #include "stlport_prefix.h"
00020 #include "stdio_streambuf.h"
00021 // #include "file_streambuf.h"
00022 
00023 #ifdef _STLP_UNIX
00024 #  include <sys/types.h>
00025 #  include <sys/stat.h>
00026 #endif /* __unix */
00027 
00028 #include <fstream>
00029 #include <limits>
00030 #include "fstream_impl.h"
00031 
00032 #if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
00033 #  if defined (__BORLANDC__)
00034 // #  include <cio.h>
00035 #    include <cfcntl.h>
00036 #  else
00037 #    include <io.h>
00038 #    include <fcntl.h>
00039 #  endif
00040 #  include <sys/stat.h>
00041 #endif
00042 
00043 _STLP_BEGIN_NAMESPACE
00044 _STLP_MOVE_TO_PRIV_NAMESPACE
00045 
00046 // Compare with streamoff definition in stl/char_traits.h!
00047 
00048 #ifdef _STLP_USE_DEFAULT_FILE_OFFSET
00049 #  define FSEEK fseek
00050 #  define FTELL ftell
00051 #  define FSTAT fstat
00052 #  define STAT  stat
00053 #  define FSETPOS  fsetpos
00054 #  define FGETPOS  fgetpos
00055 #  define FPOS_T   fpos_t
00056 #elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
00057      /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
00058 #  define FSEEK fseeko64
00059 #  define FTELL ftello64
00060 #  define FSTAT fstat64
00061 #  define STAT  stat64
00062 #  define FSETPOS  fsetpos64
00063 #  define FGETPOS  fgetpos64
00064 #  define FPOS_T   fpos64_t
00065 #else
00066 #  define FSEEK fseek
00067 #  define FTELL ftell
00068 #  define FSTAT fstat
00069 #  define STAT  stat
00070 #  define FSETPOS  fsetpos
00071 #  define FGETPOS  fgetpos
00072 #  define FPOS_T   fpos_t
00073 #endif
00074 
00075 //----------------------------------------------------------------------
00076 // Class stdio_streambuf_base
00077 
00078 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
00079     : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
00080     _M_file(file)
00081 {}
00082 
00083 stdio_streambuf_base::~stdio_streambuf_base() {
00084   _STLP_VENDOR_CSTD::fflush(_M_file);
00085 }
00086 
00087 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
00088 #ifdef _STLP_WCE
00089   // no buffering in windows ce .NET
00090 #else
00091   size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
00092                                                             : __STATIC_CAST(size_t, n);
00093   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
00094 #endif
00095   return this;
00096 }
00097 
00098 stdio_streambuf_base::pos_type
00099 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
00100                               ios_base::openmode /* mode */) {
00101   int whence;
00102   switch (dir) {
00103   case ios_base::beg:
00104     whence = SEEK_SET;
00105     break;
00106   case ios_base::cur:
00107     whence = SEEK_CUR;
00108     break;
00109   case ios_base::end:
00110     whence = SEEK_END;
00111     break;
00112   default:
00113     return pos_type(-1);
00114   }
00115 
00116   if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
00117     FPOS_T pos;
00118     FGETPOS(_M_file, &pos);
00119     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
00120     // of a primitive type
00121 #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
00122     return pos_type((streamoff)pos.__pos);
00123 #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
00124     return pos_type(pos.__fpos_elem[ 0 ]);
00125 #elif defined (__EMX__)
00126     return pos_type((streamoff)pos._pos);
00127 #else
00128     return pos_type(pos);
00129 #endif
00130   }
00131   else
00132     return pos_type(-1);
00133 }
00134 
00135 
00136 stdio_streambuf_base::pos_type
00137 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
00138   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
00139   // of a primitive type
00140 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
00141   FPOS_T p;
00142   p.__pos = pos;
00143 #  ifdef _STLP_USE_UCLIBC
00144 #    ifdef __STDIO_MBSTATE
00145   memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
00146 #    endif
00147 #    ifdef __STDIO_WIDE
00148   p.mblen_pending = 0;
00149 #    endif
00150 #  else
00151   memset( &(p.__state), 0, sizeof(p.__state) );
00152 #  endif
00153 #elif defined (__MVS__) || defined (__OS400__)
00154   FPOS_T p;
00155   p.__fpos_elem[0] = pos;
00156 #elif defined(__EMX__)
00157   FPOS_T p;
00158   p._pos = pos;
00159   memset( &(p._mbstate), 0, sizeof(p._mbstate) );
00160 #else
00161   FPOS_T p(pos);
00162 #endif
00163 
00164   return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
00165 }
00166 
00167 int stdio_streambuf_base::sync() {
00168   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
00169 }
00170 
00171 //----------------------------------------------------------------------
00172 // Class stdio_istreambuf
00173 
00174 stdio_istreambuf::~stdio_istreambuf() {}
00175 
00176 streamsize stdio_istreambuf::showmanyc() {
00177   if (feof(_M_file))
00178     return -1;
00179   else {
00180     int fd = _FILE_fd(_M_file);
00181 #ifdef _STLP_WCE
00182    (fd); // prevent warning about unused variable
00183 // not sure if i can mix win32 io mode with ftell but time will show
00184 // cannot use WIN32_IO implementation since missing stat
00185     streamsize tmp = FTELL(_M_file);
00186     FSEEK(_M_file, 0, SEEK_END);
00187     streamoff size= FTELL(_M_file)-tmp;
00188     FSEEK(_M_file, tmp, SEEK_SET);
00189 #elif defined (_STLP_USE_WIN32_IO)
00190     // in this case, __file_size works with Win32 fh , not libc one
00191     streamoff size;
00192     struct stat buf;
00193     if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
00194       size = ( buf.st_size > 0  ? buf.st_size : 0);
00195     else
00196       size = 0;
00197 #else
00198     streamoff size = __file_size(fd);
00199 #endif
00200     // fbp : we can use ftell as this flavour always use stdio.
00201     streamsize pos = FTELL(_M_file);
00202     return pos >= 0 && size > pos ? size - pos : 0;
00203   }
00204 }
00205 
00206 stdio_istreambuf::int_type stdio_istreambuf::underflow()
00207 {
00208 #ifdef _STLP_WCE
00209   int c = fgetc(_M_file);
00210 #else
00211   int c = getc(_M_file);
00212 #endif
00213   if (c != EOF) {
00214     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
00215     return c;
00216   }
00217   else
00218     return traits_type::eof();
00219 }
00220 
00221 stdio_istreambuf::int_type stdio_istreambuf::uflow() {
00222 #ifdef _STLP_WCE
00223   int c = fgetc(_M_file);
00224 #else
00225   int c = getc(_M_file);
00226 #endif
00227   return c != EOF ? c : traits_type::eof();
00228 }
00229 
00230 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
00231   if (c != traits_type::eof()) {
00232     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
00233     return result != EOF ? result : traits_type::eof();
00234   }
00235   else{
00236     if (this->eback() < this->gptr()) {
00237       this->gbump(-1);
00238       return traits_type::not_eof(c);
00239     }
00240     else
00241       return traits_type::eof();
00242   }
00243 }
00244 
00245 //----------------------------------------------------------------------
00246 // Class stdio_ostreambuf
00247 
00248 stdio_ostreambuf::~stdio_ostreambuf() {}
00249 
00250 streamsize stdio_ostreambuf::showmanyc() {
00251   return -1;
00252 }
00253 
00254 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
00255   // Write the existing buffer, without writing any additional character.
00256   if (c == traits_type::eof()) {
00257     // Do we have a buffer to write?
00258     ptrdiff_t unwritten = this->pptr() - this->pbase();
00259     if (unwritten != 0) {
00260       _STLP_VENDOR_CSTD::fflush(_M_file);
00261       // Test if the write succeeded.
00262       if (this->pptr() - this->pbase() < unwritten)
00263         return traits_type::not_eof(c);
00264       else
00265         return traits_type::eof();
00266     }
00267 
00268     // We always succeed if we don't have to do anything.
00269     else
00270       return traits_type::not_eof(c);
00271   }
00272 
00273   // Write the character c, and whatever else might be in the buffer.
00274   else {
00275 #ifdef _STLP_WCE
00276     int result = fputc(c, _M_file);
00277 #else
00278     int result = putc(c, _M_file);
00279 #endif
00280     return result != EOF ? result : traits_type::eof();
00281   }
00282 }
00283 
00284 _STLP_MOVE_TO_STD_NAMESPACE
00285 _STLP_END_NAMESPACE
00286 
00287 // Local Variables:
00288 // mode:C++
00289 // End:
00290 



Generated on Mon Mar 10 15:32:17 2008 by  doxygen 1.5.1