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