stdcpp/src/stdio_streambuf.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999 
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted 
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */ 
       
    20 # include "stlport_prefix.h"
       
    21 #include <stdio_streambuf>
       
    22 
       
    23 #ifdef _STLP_UNIX
       
    24 #include <sys/types.h>
       
    25 #include <sys/stat.h>
       
    26 #endif /* __unix */
       
    27 
       
    28 #include <stl/_fstream.h>
       
    29 #include "fstream_impl.h"
       
    30 
       
    31 # if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WINCE)
       
    32 # if defined (__BORLANDC__)
       
    33 // #  include <cio.h>
       
    34 #  include <cfcntl.h>
       
    35 # else
       
    36 #  include <io.h>
       
    37 #  include <fcntl.h>
       
    38 # endif
       
    39 
       
    40 #  include <sys/stat.h>
       
    41 # endif
       
    42 
       
    43 __SGI_BEGIN_NAMESPACE
       
    44 //----------------------------------------------------------------------
       
    45 // Class stdio_streambuf_base
       
    46 
       
    47 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
       
    48   : _STLP_STD::basic_streambuf<char, _STLP_STD::char_traits<char> >(file, 0),
       
    49     _M_file(file)
       
    50 {}
       
    51 
       
    52 stdio_streambuf_base::~stdio_streambuf_base()
       
    53 {
       
    54   _STLP_VENDOR_CSTD::fflush(_M_file);
       
    55 }
       
    56 
       
    57 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n)
       
    58 {
       
    59   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, n);
       
    60   return this;
       
    61 }
       
    62 
       
    63 stdio_streambuf_base::pos_type
       
    64 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
       
    65                               ios_base::openmode /* mode */)
       
    66 {
       
    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       
       
    82   if (_STLP_VENDOR_CSTD::fseek(_M_file, off, whence) == 0) {
       
    83     fpos_t pos;
       
    84     _STLP_VENDOR_CSTD::fgetpos(_M_file, &pos);
       
    85     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
       
    86     // of a primitive type
       
    87 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
       
    88     return pos_type((streamoff)pos.__pos);
       
    89 #elif defined(__ISCPP__) || defined(__MVS__) || (__OS400__)
       
    90      return pos_type(pos.__fpos_elem[ 0 ]);
       
    91 #elif defined (__EMX__)
       
    92      return pos_type((streamoff)pos._pos);
       
    93 #else
       
    94     return pos_type(pos);
       
    95 #endif
       
    96   }
       
    97   else
       
    98     return pos_type(-1);
       
    99 }
       
   100 
       
   101 
       
   102 stdio_streambuf_base::pos_type
       
   103 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */)   // dwa 4/27/00 - suppress unused parameter warning
       
   104 {
       
   105 
       
   106   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
       
   107   // of a primitive type
       
   108 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
       
   109   fpos_t p;
       
   110   p.__pos = pos;
       
   111   memset( &(p.__state), 0, sizeof(p.__state) );
       
   112 #elif defined(__MVS__) || (__OS400__)
       
   113   fpos_t p;
       
   114   p.__fpos_elem[0] = pos;
       
   115 #elif defined(__EMX__)
       
   116   fpos_t p;
       
   117   p._pos = pos;
       
   118   memset( &(p._mbstate), 0, sizeof(p._mbstate) );
       
   119 #else
       
   120   fpos_t p(pos);
       
   121 #endif
       
   122 
       
   123   if (_STLP_VENDOR_CSTD::fsetpos(_M_file, &p) == 0)
       
   124     return pos;
       
   125   else
       
   126     return pos_type(-1);
       
   127 }
       
   128 
       
   129 int stdio_streambuf_base::sync()
       
   130 {
       
   131   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
       
   132 }
       
   133 
       
   134 //----------------------------------------------------------------------
       
   135 // Class stdio_istreambuf
       
   136 
       
   137 stdio_istreambuf::~stdio_istreambuf() {}
       
   138 
       
   139 _STLP_EXP_DECLSPEC streamsize stdio_istreambuf::showmanyc()
       
   140 {
       
   141   if (feof(_M_file)) 
       
   142     return -1;
       
   143   else {
       
   144     int fd = _FILE_fd(_M_file);
       
   145 # ifdef _STLP_USE_WIN32_IO
       
   146     // in this case, __file_size works with Win32 fh , not libc one
       
   147     streamoff size;
       
   148     struct stat buf;
       
   149 # ifdef __BORLANDC__
       
   150     if(fstat(fd, &buf) == 0 && S_ISREG( buf.st_mode ) )
       
   151 # else
       
   152     if(fstat(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
       
   153 # endif
       
   154       size = ( buf.st_size > 0  ? buf.st_size : 0);
       
   155     else
       
   156       size = 0;
       
   157 # else
       
   158     streamoff size = _SgI::__file_size(fd);
       
   159 # endif
       
   160     // fbp : we can use ftell as this flavour always use stdio.
       
   161     long pos = _STLP_VENDOR_CSTD::ftell(_M_file);
       
   162     return pos >= 0 && size > pos ? size - pos : 0;
       
   163   }
       
   164 }
       
   165 
       
   166 stdio_istreambuf::int_type stdio_istreambuf::underflow()
       
   167 {
       
   168   int c = getc(_M_file);
       
   169   if (c != EOF) {
       
   170     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
       
   171     return c;
       
   172   }
       
   173   else
       
   174     return traits_type::eof();
       
   175 }
       
   176 
       
   177 stdio_istreambuf::int_type stdio_istreambuf::uflow()
       
   178 {
       
   179 #ifdef __SYMBIAN32__
       
   180   const int_type eof = traits_type::eof();
       
   181   return this->underflow() == eof 
       
   182     ? eof
       
   183     : traits_type::to_int_type(_FILE_I_postincr(_M_file));
       
   184 #else
       
   185   int c = getc(_M_file);
       
   186   return c != EOF ? c : traits_type::eof();
       
   187 #endif    
       
   188 }
       
   189 
       
   190 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c)
       
   191 {
       
   192   if (c != traits_type::eof()) {
       
   193     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
       
   194     return result != EOF ? result : traits_type::eof();
       
   195   }
       
   196   else{
       
   197     if (this->eback() < this->gptr()) {
       
   198       this->gbump(-1);
       
   199       return traits_type::not_eof(c);
       
   200     }
       
   201     else
       
   202       return traits_type::eof();
       
   203   }
       
   204 }
       
   205 
       
   206 //----------------------------------------------------------------------
       
   207 // Class stdio_ostreambuf
       
   208 
       
   209 stdio_ostreambuf::~stdio_ostreambuf() {}
       
   210 
       
   211 _STLP_EXP_DECLSPEC streamsize stdio_ostreambuf::showmanyc()
       
   212 {
       
   213   return -1;
       
   214 }
       
   215 
       
   216 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c)
       
   217 {
       
   218   // Write the existing buffer, without writing any additional character.
       
   219   if (c == traits_type::eof()) {
       
   220     // Do we have a buffer to write?
       
   221     ptrdiff_t unwritten = this->pptr() - this->pbase();
       
   222     if (unwritten != 0) {
       
   223       _STLP_VENDOR_CSTD::fflush(_M_file);
       
   224       // Test if the write succeeded.
       
   225       if (this->pptr() - this->pbase() < unwritten)
       
   226         return traits_type::not_eof(c);
       
   227       else
       
   228         return traits_type::eof();
       
   229     }
       
   230 
       
   231     // We always succeed if we don't have to do anything.
       
   232     else
       
   233       return traits_type::not_eof(c);
       
   234   }
       
   235 
       
   236   // Write the character c, and whatever else might be in the buffer.
       
   237   else {
       
   238     int result = putc(c, _M_file);
       
   239     return result != EOF ? result : traits_type::eof();
       
   240   }
       
   241 }
       
   242 
       
   243 __SGI_END_NAMESPACE
       
   244 
       
   245 // Local Variables:
       
   246 // mode:C++
       
   247 // End:
       
   248