Home | History | Annotate | Download | only in src
      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 
     19 #include "stlport_prefix.h"
     20 #include "stdio_streambuf.h"
     21 
     22 #ifdef _STLP_UNIX
     23 #  include <sys/types.h>
     24 #  include <sys/stat.h>
     25 #endif
     26 
     27 #include <fstream>
     28 #include <limits>
     29 
     30 _STLP_BEGIN_NAMESPACE
     31 _STLP_MOVE_TO_PRIV_NAMESPACE
     32 
     33 // Compare with streamoff definition in stl/char_traits.h!
     34 
     35 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
     36     (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))
     37 #  if !defined (_STLP_MSVC) || (_STLP_MSVC < 1400) || defined(_STLP_WCE)
     38 #    define FSEEK fseek
     39 #  else
     40 #    define FSEEK _fseeki64
     41 #  endif
     42 #  define FSETPOS  fsetpos
     43 #  define FGETPOS  fgetpos
     44 #  define FPOS_T   fpos_t
     45 #else
     46 #  define FSEEK fseeko64
     47 #  define FSETPOS  fsetpos64
     48 #  define FGETPOS  fgetpos64
     49 #  define FPOS_T   fpos64_t
     50 #endif
     51 
     52 //----------------------------------------------------------------------
     53 // Class stdio_streambuf_base
     54 
     55 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
     56     : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
     57     _M_file(file)
     58 {}
     59 
     60 stdio_streambuf_base::~stdio_streambuf_base() {
     61   _STLP_VENDOR_CSTD::fflush(_M_file);
     62 }
     63 
     64 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
     65 #ifdef _STLP_WCE
     66   // no buffering in windows ce .NET
     67 #else
     68   size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
     69                                                             : __STATIC_CAST(size_t, n);
     70   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
     71 #endif
     72   return this;
     73 }
     74 
     75 stdio_streambuf_base::pos_type
     76 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
     77                               ios_base::openmode /* mode */) {
     78   int whence;
     79   switch (dir) {
     80   case ios_base::beg:
     81     whence = SEEK_SET;
     82     break;
     83   case ios_base::cur:
     84     whence = SEEK_CUR;
     85     break;
     86   case ios_base::end:
     87     whence = SEEK_END;
     88     break;
     89   default:
     90     return pos_type(-1);
     91   }
     92 
     93   if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
     94     FPOS_T pos;
     95     FGETPOS(_M_file, &pos);
     96     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
     97     // of a primitive type
     98 #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
     99     return pos_type((streamoff)pos.__pos);
    100 #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
    101     return pos_type(pos.__fpos_elem[ 0 ]);
    102 #elif defined (__EMX__)
    103     return pos_type((streamoff)pos._pos);
    104 #else
    105     return pos_type(pos);
    106 #endif
    107   }
    108   else
    109     return pos_type(-1);
    110 }
    111 
    112 
    113 stdio_streambuf_base::pos_type
    114 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
    115   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
    116   // of a primitive type
    117 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
    118   FPOS_T p;
    119   p.__pos = pos;
    120 #  ifdef _STLP_USE_UCLIBC
    121 #    ifdef __STDIO_MBSTATE
    122   memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
    123 #    endif
    124 #    ifdef __STDIO_WIDE
    125   p.mblen_pending = 0;
    126 #    endif
    127 #  else
    128   memset( &(p.__state), 0, sizeof(p.__state) );
    129 #  endif
    130 #elif defined (__MVS__) || defined (__OS400__)
    131   FPOS_T p;
    132   p.__fpos_elem[0] = pos;
    133 #elif defined (__EMX__)
    134   FPOS_T p;
    135   p._pos = pos;
    136   memset( &(p._mbstate), 0, sizeof(p._mbstate) );
    137 #else
    138   FPOS_T p(pos);
    139 #endif
    140 
    141   return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
    142 }
    143 
    144 int stdio_streambuf_base::sync() {
    145   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
    146 }
    147 
    148 //----------------------------------------------------------------------
    149 // Class stdio_istreambuf
    150 
    151 stdio_istreambuf::~stdio_istreambuf() {}
    152 
    153 streamsize stdio_istreambuf::showmanyc()
    154 { return 0; }
    155 
    156 stdio_istreambuf::int_type stdio_istreambuf::underflow()
    157 {
    158 #ifdef _STLP_WCE
    159   int c = fgetc(_M_file);
    160 #else
    161   int c = getc(_M_file);
    162 #endif
    163   if (c != EOF) {
    164     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
    165     return c;
    166   }
    167   else
    168     return traits_type::eof();
    169 }
    170 
    171 stdio_istreambuf::int_type stdio_istreambuf::uflow() {
    172 #ifdef _STLP_WCE
    173   int c = fgetc(_M_file);
    174 #else
    175   int c = getc(_M_file);
    176 #endif
    177   return c != EOF ? c : traits_type::eof();
    178 }
    179 
    180 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
    181   if (c != traits_type::eof()) {
    182     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
    183     return result != EOF ? result : traits_type::eof();
    184   }
    185   else{
    186     if (this->eback() < this->gptr()) {
    187       this->gbump(-1);
    188       return traits_type::not_eof(c);
    189     }
    190     else
    191       return traits_type::eof();
    192   }
    193 }
    194 
    195 //----------------------------------------------------------------------
    196 // Class stdio_ostreambuf
    197 
    198 stdio_ostreambuf::~stdio_ostreambuf() {}
    199 
    200 streamsize stdio_ostreambuf::showmanyc()
    201 { return -1; }
    202 
    203 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
    204   // Write the existing buffer, without writing any additional character.
    205   if (c == traits_type::eof()) {
    206     // Do we have a buffer to write?
    207     ptrdiff_t unwritten = this->pptr() - this->pbase();
    208     if (unwritten != 0) {
    209       _STLP_VENDOR_CSTD::fflush(_M_file);
    210       // Test if the write succeeded.
    211       if (this->pptr() - this->pbase() < unwritten)
    212         return traits_type::not_eof(c);
    213       else
    214         return traits_type::eof();
    215     }
    216 
    217     // We always succeed if we don't have to do anything.
    218     else
    219       return traits_type::not_eof(c);
    220   }
    221 
    222   // Write the character c, and whatever else might be in the buffer.
    223   else {
    224 #ifdef _STLP_WCE
    225     int result = fputc(c, _M_file);
    226 #else
    227     int result = putc(c, _M_file);
    228 #endif
    229     return result != EOF ? result : traits_type::eof();
    230   }
    231 }
    232 
    233 _STLP_MOVE_TO_STD_NAMESPACE
    234 _STLP_END_NAMESPACE
    235 
    236 // Local Variables:
    237 // mode:C++
    238 // End:
    239 
    240