genericopenlibs/cppstdlib/stl/src/stdio_streambuf.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 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 
       
    21 #include "stlport_prefix.h"
       
    22 #include "stdio_streambuf.h"
       
    23 // #include "file_streambuf.h"
       
    24 
       
    25 #ifdef _STLP_UNIX
       
    26 #  include <sys/types.h>
       
    27 #  include <sys/stat.h>
       
    28 #endif /* __unix */
       
    29 
       
    30 #include <fstream>
       
    31 #include <limits>
       
    32 #include "fstream_impl.h"
       
    33 
       
    34 #if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
       
    35 #  if defined (__BORLANDC__)
       
    36 // #  include <cio.h>
       
    37 #    include <cfcntl.h>
       
    38 #  else
       
    39 #    include <io.h>
       
    40 #    include <fcntl.h>
       
    41 #  endif
       
    42 #  include <sys/stat.h>
       
    43 #endif
       
    44 
       
    45 _STLP_BEGIN_NAMESPACE
       
    46 _STLP_MOVE_TO_PRIV_NAMESPACE
       
    47 
       
    48 // Compare with streamoff definition in stl/char_traits.h!
       
    49 
       
    50 #ifdef _STLP_USE_DEFAULT_FILE_OFFSET
       
    51 #  define FSEEK fseek
       
    52 #  define FTELL ftell
       
    53 #  define FSTAT fstat
       
    54 #  define STAT  stat
       
    55 #  define FSETPOS  fsetpos
       
    56 #  define FGETPOS  fgetpos
       
    57 #  define FPOS_T   fpos_t
       
    58 #elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
       
    59      /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
       
    60 #  define FSEEK fseeko64
       
    61 #  define FTELL ftello64
       
    62 #  define FSTAT fstat64
       
    63 #  define STAT  stat64
       
    64 #  define FSETPOS  fsetpos64
       
    65 #  define FGETPOS  fgetpos64
       
    66 #  define FPOS_T   fpos64_t
       
    67 #else
       
    68 #  define FSEEK fseek
       
    69 #  define FTELL ftell
       
    70 #  define FSTAT fstat
       
    71 #  define STAT  stat
       
    72 #  define FSETPOS  fsetpos
       
    73 #  define FGETPOS  fgetpos
       
    74 #  define FPOS_T   fpos_t
       
    75 #endif
       
    76 
       
    77 //----------------------------------------------------------------------
       
    78 // Class stdio_streambuf_base
       
    79 
       
    80 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
       
    81     : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
       
    82     _M_file(file)
       
    83 {}
       
    84 
       
    85 stdio_streambuf_base::~stdio_streambuf_base() {
       
    86   _STLP_VENDOR_CSTD::fflush(_M_file);
       
    87 }
       
    88 
       
    89 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
       
    90 #ifdef _STLP_WCE
       
    91   // no buffering in windows ce .NET
       
    92 #else
       
    93   size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
       
    94                                                             : __STATIC_CAST(size_t, n);
       
    95   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
       
    96 #endif
       
    97   return this;
       
    98 }
       
    99 
       
   100 stdio_streambuf_base::pos_type
       
   101 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
       
   102                               ios_base::openmode /* mode */) {
       
   103   int whence;
       
   104   switch (dir) {
       
   105   case ios_base::beg:
       
   106     whence = SEEK_SET;
       
   107     break;
       
   108   case ios_base::cur:
       
   109     whence = SEEK_CUR;
       
   110     break;
       
   111   case ios_base::end:
       
   112     whence = SEEK_END;
       
   113     break;
       
   114   default:
       
   115     return pos_type(-1);
       
   116   }
       
   117 
       
   118   if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
       
   119     FPOS_T pos;
       
   120     FGETPOS(_M_file, &pos);
       
   121     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
       
   122     // of a primitive type
       
   123 #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
       
   124     return pos_type((streamoff)pos.__pos);
       
   125 #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
       
   126     return pos_type(pos.__fpos_elem[ 0 ]);
       
   127 #elif defined (__EMX__)
       
   128     return pos_type((streamoff)pos._pos);
       
   129 #else
       
   130     return pos_type(pos);
       
   131 #endif
       
   132   }
       
   133   else
       
   134     return pos_type(-1);
       
   135 }
       
   136 
       
   137 
       
   138 stdio_streambuf_base::pos_type
       
   139 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
       
   140   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
       
   141   // of a primitive type
       
   142 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
       
   143   FPOS_T p;
       
   144   p.__pos = pos;
       
   145 #  ifdef _STLP_USE_UCLIBC
       
   146 #    ifdef __STDIO_MBSTATE
       
   147   memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
       
   148 #    endif
       
   149 #    ifdef __STDIO_WIDE
       
   150   p.mblen_pending = 0;
       
   151 #    endif
       
   152 #  else
       
   153   memset( &(p.__state), 0, sizeof(p.__state) );
       
   154 #  endif
       
   155 #elif defined (__MVS__) || defined (__OS400__)
       
   156   FPOS_T p;
       
   157   p.__fpos_elem[0] = pos;
       
   158 #elif defined(__EMX__)
       
   159   FPOS_T p;
       
   160   p._pos = pos;
       
   161   memset( &(p._mbstate), 0, sizeof(p._mbstate) );
       
   162 #else
       
   163   FPOS_T p(pos);
       
   164 #endif
       
   165 
       
   166   return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
       
   167 }
       
   168 
       
   169 int stdio_streambuf_base::sync() {
       
   170   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
       
   171 }
       
   172 
       
   173 //----------------------------------------------------------------------
       
   174 // Class stdio_istreambuf
       
   175 
       
   176 stdio_istreambuf::~stdio_istreambuf() {}
       
   177 
       
   178 streamsize stdio_istreambuf::showmanyc() {
       
   179   if (feof(_M_file))
       
   180     return -1;
       
   181   else {
       
   182 #ifdef __SYMBIAN32__
       
   183 	  int fd = fileno(_M_file);
       
   184 #else
       
   185     int fd = _FILE_fd(_M_file);
       
   186 #endif
       
   187 #ifdef _STLP_WCE
       
   188    (fd); // prevent warning about unused variable
       
   189 // not sure if i can mix win32 io mode with ftell but time will show
       
   190 // cannot use WIN32_IO implementation since missing stat
       
   191     streamsize tmp = FTELL(_M_file);
       
   192     FSEEK(_M_file, 0, SEEK_END);
       
   193     streamoff size= FTELL(_M_file)-tmp;
       
   194     FSEEK(_M_file, tmp, SEEK_SET);
       
   195 #elif defined (_STLP_USE_WIN32_IO)
       
   196     // in this case, __file_size works with Win32 fh , not libc one
       
   197     streamoff size;
       
   198     struct stat buf;
       
   199     if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
       
   200       size = ( buf.st_size > 0  ? buf.st_size : 0);
       
   201     else
       
   202       size = 0;
       
   203 #else
       
   204     streamoff size = __file_size(fd);
       
   205 #endif
       
   206     // fbp : we can use ftell as this flavour always use stdio.
       
   207     streamsize pos = FTELL(_M_file);
       
   208     return pos >= 0 && size > pos ? size - pos : 0;
       
   209   }
       
   210 }
       
   211 
       
   212 stdio_istreambuf::int_type stdio_istreambuf::underflow()
       
   213 {
       
   214 #ifdef _STLP_WCE
       
   215   int c = fgetc(_M_file);
       
   216 #else
       
   217   int c = getc(_M_file);
       
   218 #endif
       
   219   if (c != EOF) {
       
   220     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
       
   221     return c;
       
   222   }
       
   223   else
       
   224     return traits_type::eof();
       
   225 }
       
   226 
       
   227 stdio_istreambuf::int_type stdio_istreambuf::uflow() {
       
   228 #ifdef _STLP_WCE
       
   229   int c = fgetc(_M_file);
       
   230 #else
       
   231   int c = getc(_M_file);
       
   232 #endif
       
   233   return c != EOF ? c : traits_type::eof();
       
   234 }
       
   235 
       
   236 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
       
   237   if (c != traits_type::eof()) {
       
   238     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
       
   239     return result != EOF ? result : traits_type::eof();
       
   240   }
       
   241   else{
       
   242     if (this->eback() < this->gptr()) {
       
   243       this->gbump(-1);
       
   244       return traits_type::not_eof(c);
       
   245     }
       
   246     else
       
   247       return traits_type::eof();
       
   248   }
       
   249 }
       
   250 
       
   251 //----------------------------------------------------------------------
       
   252 // Class stdio_ostreambuf
       
   253 
       
   254 stdio_ostreambuf::~stdio_ostreambuf() {}
       
   255 
       
   256 streamsize stdio_ostreambuf::showmanyc() {
       
   257   return -1;
       
   258 }
       
   259 
       
   260 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
       
   261   // Write the existing buffer, without writing any additional character.
       
   262   if (c == traits_type::eof()) {
       
   263     // Do we have a buffer to write?
       
   264     ptrdiff_t unwritten = this->pptr() - this->pbase();
       
   265     if (unwritten != 0) {
       
   266       _STLP_VENDOR_CSTD::fflush(_M_file);
       
   267       // Test if the write succeeded.
       
   268       if (this->pptr() - this->pbase() < unwritten)
       
   269         return traits_type::not_eof(c);
       
   270       else
       
   271         return traits_type::eof();
       
   272     }
       
   273 
       
   274     // We always succeed if we don't have to do anything.
       
   275     else
       
   276       return traits_type::not_eof(c);
       
   277   }
       
   278 
       
   279   // Write the character c, and whatever else might be in the buffer.
       
   280   else {
       
   281 #ifdef _STLP_WCE
       
   282     int result = fputc(c, _M_file);
       
   283 #else
       
   284     int result = putc(c, _M_file);
       
   285 #endif
       
   286     return result != EOF ? result : traits_type::eof();
       
   287   }
       
   288 }
       
   289 
       
   290 _STLP_MOVE_TO_STD_NAMESPACE
       
   291 _STLP_END_NAMESPACE
       
   292 
       
   293 // Local Variables:
       
   294 // mode:C++
       
   295 // End:
       
   296