diff -r e20de85af2ee -r ce057bb09d0b genericopenlibs/cppstdlib/stl/src/stdio_streambuf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cppstdlib/stl/src/stdio_streambuf.cpp Fri Jun 04 16:20:51 2010 +0100 @@ -0,0 +1,296 @@ +/* + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. + * + * 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" +// #include "file_streambuf.h" + +#ifdef _STLP_UNIX +# include +# include +#endif /* __unix */ + +#include +#include +#include "fstream_impl.h" + +#if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE) +# if defined (__BORLANDC__) +// # include +# include +# else +# include +# include +# endif +# include +#endif + +_STLP_BEGIN_NAMESPACE +_STLP_MOVE_TO_PRIV_NAMESPACE + +// Compare with streamoff definition in stl/char_traits.h! + +#ifdef _STLP_USE_DEFAULT_FILE_OFFSET +# define FSEEK fseek +# define FTELL ftell +# define FSTAT fstat +# define STAT stat +# define FSETPOS fsetpos +# define FGETPOS fgetpos +# define FPOS_T fpos_t +#elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \ + /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */ +# define FSEEK fseeko64 +# define FTELL ftello64 +# define FSTAT fstat64 +# define STAT stat64 +# define FSETPOS fsetpos64 +# define FGETPOS fgetpos64 +# define FPOS_T fpos64_t +#else +# define FSEEK fseek +# define FTELL ftell +# define FSTAT fstat +# define STAT stat +# define FSETPOS fsetpos +# define FGETPOS fgetpos +# define FPOS_T fpos_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::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::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() { + if (feof(_M_file)) + return -1; + else { +#ifdef __SYMBIAN32__ + int fd = fileno(_M_file); +#else + int fd = _FILE_fd(_M_file); +#endif +#ifdef _STLP_WCE + (fd); // prevent warning about unused variable +// not sure if i can mix win32 io mode with ftell but time will show +// cannot use WIN32_IO implementation since missing stat + streamsize tmp = FTELL(_M_file); + FSEEK(_M_file, 0, SEEK_END); + streamoff size= FTELL(_M_file)-tmp; + FSEEK(_M_file, tmp, SEEK_SET); +#elif defined (_STLP_USE_WIN32_IO) + // in this case, __file_size works with Win32 fh , not libc one + streamoff size; + struct stat buf; + if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) ) + size = ( buf.st_size > 0 ? buf.st_size : 0); + else + size = 0; +#else + streamoff size = __file_size(fd); +#endif + // fbp : we can use ftell as this flavour always use stdio. + streamsize pos = FTELL(_M_file); + return pos >= 0 && size > pos ? size - pos : 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: +