| /* |
| * Copyright (c) 1999 |
| * Silicon Graphics Computer Systems, Inc. |
| * |
| * Copyright (c) 1999 |
| * Boris Fomitchev |
| * |
| * This material is provided "as is", with absolutely no warranty expressed |
| * or implied. Any use is at your own risk. |
| * |
| * Permission to use or copy this software for any purpose is hereby granted |
| * without fee, provided the above notices are retained on all copies. |
| * Permission to modify the code and to distribute modified code is granted, |
| * provided the above notices are retained, and a notice that the code was |
| * modified is included with the above copyright notice. |
| * |
| */ |
| |
| #include "stlport_prefix.h" |
| #include "stdio_streambuf.h" |
| |
| #ifdef _STLP_UNIX |
| # include <sys/types.h> |
| # include <sys/stat.h> |
| #endif |
| |
| #include <fstream> |
| #include <limits> |
| |
| _STLP_BEGIN_NAMESPACE |
| _STLP_MOVE_TO_PRIV_NAMESPACE |
| |
| // Compare with streamoff definition in stl/char_traits.h! |
| |
| #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ |
| (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE)) |
| # if !defined (_STLP_MSVC) || (_STLP_MSVC < 1400) || defined(_STLP_WCE) |
| # define FSEEK fseek |
| # else |
| # define FSEEK _fseeki64 |
| # endif |
| # define FSETPOS fsetpos |
| # define FGETPOS fgetpos |
| # define FPOS_T fpos_t |
| #else |
| # define FSEEK fseeko64 |
| # define FSETPOS fsetpos64 |
| # define FGETPOS fgetpos64 |
| # define FPOS_T fpos64_t |
| #endif |
| |
| //---------------------------------------------------------------------- |
| // Class stdio_streambuf_base |
| |
| stdio_streambuf_base::stdio_streambuf_base(FILE* file) |
| : /* _STLP_STD::FILE_basic_streambuf(file, 0), */ |
| _M_file(file) |
| {} |
| |
| stdio_streambuf_base::~stdio_streambuf_base() { |
| _STLP_VENDOR_CSTD::fflush(_M_file); |
| } |
| |
| _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) { |
| #ifdef _STLP_WCE |
| // no buffering in windows ce .NET |
| #else |
| size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n)) |
| : __STATIC_CAST(size_t, n); |
| _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t); |
| #endif |
| return this; |
| } |
| |
| stdio_streambuf_base::pos_type |
| stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir, |
| ios_base::openmode /* mode */) { |
| int whence; |
| switch (dir) { |
| case ios_base::beg: |
| whence = SEEK_SET; |
| break; |
| case ios_base::cur: |
| whence = SEEK_CUR; |
| break; |
| case ios_base::end: |
| whence = SEEK_END; |
| break; |
| default: |
| return pos_type(-1); |
| } |
| |
| if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) { |
| FPOS_T pos; |
| FGETPOS(_M_file, &pos); |
| // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
| // of a primitive type |
| #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)))) |
| return pos_type((streamoff)pos.__pos); |
| #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__) |
| return pos_type(pos.__fpos_elem[ 0 ]); |
| #elif defined (__EMX__) |
| return pos_type((streamoff)pos._pos); |
| #else |
| return pos_type(pos); |
| #endif |
| } |
| else |
| return pos_type(-1); |
| } |
| |
| |
| stdio_streambuf_base::pos_type |
| stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) { |
| // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
| // of a primitive type |
| #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) ) |
| FPOS_T p; |
| p.__pos = pos; |
| # ifdef _STLP_USE_UCLIBC |
| # ifdef __STDIO_MBSTATE |
| memset( &(p.__mbstate), 0, sizeof(p.__mbstate) ); |
| # endif |
| # ifdef __STDIO_WIDE |
| p.mblen_pending = 0; |
| # endif |
| # else |
| memset( &(p.__state), 0, sizeof(p.__state) ); |
| # endif |
| #elif defined (__MVS__) || defined (__OS400__) |
| FPOS_T p; |
| p.__fpos_elem[0] = pos; |
| #elif defined (__EMX__) |
| FPOS_T p; |
| p._pos = pos; |
| memset( &(p._mbstate), 0, sizeof(p._mbstate) ); |
| #else |
| FPOS_T p(pos); |
| #endif |
| |
| return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1); |
| } |
| |
| int stdio_streambuf_base::sync() { |
| return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1; |
| } |
| |
| //---------------------------------------------------------------------- |
| // Class stdio_istreambuf |
| |
| stdio_istreambuf::~stdio_istreambuf() {} |
| |
| streamsize stdio_istreambuf::showmanyc() |
| { return 0; } |
| |
| stdio_istreambuf::int_type stdio_istreambuf::underflow() |
| { |
| #ifdef _STLP_WCE |
| int c = fgetc(_M_file); |
| #else |
| int c = getc(_M_file); |
| #endif |
| if (c != EOF) { |
| _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
| return c; |
| } |
| else |
| return traits_type::eof(); |
| } |
| |
| stdio_istreambuf::int_type stdio_istreambuf::uflow() { |
| #ifdef _STLP_WCE |
| int c = fgetc(_M_file); |
| #else |
| int c = getc(_M_file); |
| #endif |
| return c != EOF ? c : traits_type::eof(); |
| } |
| |
| stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) { |
| if (c != traits_type::eof()) { |
| int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
| return result != EOF ? result : traits_type::eof(); |
| } |
| else{ |
| if (this->eback() < this->gptr()) { |
| this->gbump(-1); |
| return traits_type::not_eof(c); |
| } |
| else |
| return traits_type::eof(); |
| } |
| } |
| |
| //---------------------------------------------------------------------- |
| // Class stdio_ostreambuf |
| |
| stdio_ostreambuf::~stdio_ostreambuf() {} |
| |
| streamsize stdio_ostreambuf::showmanyc() |
| { return -1; } |
| |
| stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) { |
| // Write the existing buffer, without writing any additional character. |
| if (c == traits_type::eof()) { |
| // Do we have a buffer to write? |
| ptrdiff_t unwritten = this->pptr() - this->pbase(); |
| if (unwritten != 0) { |
| _STLP_VENDOR_CSTD::fflush(_M_file); |
| // Test if the write succeeded. |
| if (this->pptr() - this->pbase() < unwritten) |
| return traits_type::not_eof(c); |
| else |
| return traits_type::eof(); |
| } |
| |
| // We always succeed if we don't have to do anything. |
| else |
| return traits_type::not_eof(c); |
| } |
| |
| // Write the character c, and whatever else might be in the buffer. |
| else { |
| #ifdef _STLP_WCE |
| int result = fputc(c, _M_file); |
| #else |
| int result = putc(c, _M_file); |
| #endif |
| return result != EOF ? result : traits_type::eof(); |
| } |
| } |
| |
| _STLP_MOVE_TO_STD_NAMESPACE |
| _STLP_END_NAMESPACE |
| |
| // Local Variables: |
| // mode:C++ |
| // End: |
| |