stdcpp/src/stdio_streambuf.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stdcpp/src/stdio_streambuf.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,248 @@
+/*
+ * © Portions copyright (c) 2006-2007 Nokia Corporation.  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>
+
+#ifdef _STLP_UNIX
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif /* __unix */
+
+#include <stl/_fstream.h>
+#include "fstream_impl.h"
+
+# if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WINCE)
+# if defined (__BORLANDC__)
+// #  include <cio.h>
+#  include <cfcntl.h>
+# else
+#  include <io.h>
+#  include <fcntl.h>
+# endif
+
+#  include <sys/stat.h>
+# endif
+
+__SGI_BEGIN_NAMESPACE
+//----------------------------------------------------------------------
+// Class stdio_streambuf_base
+
+stdio_streambuf_base::stdio_streambuf_base(FILE* file)
+  : _STLP_STD::basic_streambuf<char, _STLP_STD::char_traits<char> >(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)
+{
+  _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, n);
+  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 (_STLP_VENDOR_CSTD::fseek(_M_file, off, whence) == 0) {
+    fpos_t pos;
+    _STLP_VENDOR_CSTD::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__) || (__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 */)   // dwa 4/27/00 - suppress unused parameter warning
+{
+
+  // 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;
+  memset( &(p.__state), 0, sizeof(p.__state) );
+#elif defined(__MVS__) || (__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
+
+  if (_STLP_VENDOR_CSTD::fsetpos(_M_file, &p) == 0)
+    return pos;
+  else
+    return 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() {}
+
+_STLP_EXP_DECLSPEC streamsize stdio_istreambuf::showmanyc()
+{
+  if (feof(_M_file)) 
+    return -1;
+  else {
+    int fd = _FILE_fd(_M_file);
+# ifdef _STLP_USE_WIN32_IO
+    // in this case, __file_size works with Win32 fh , not libc one
+    streamoff size;
+    struct stat buf;
+# ifdef __BORLANDC__
+    if(fstat(fd, &buf) == 0 && S_ISREG( buf.st_mode ) )
+# else
+    if(fstat(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
+# endif
+      size = ( buf.st_size > 0  ? buf.st_size : 0);
+    else
+      size = 0;
+# else
+    streamoff size = _SgI::__file_size(fd);
+# endif
+    // fbp : we can use ftell as this flavour always use stdio.
+    long pos = _STLP_VENDOR_CSTD::ftell(_M_file);
+    return pos >= 0 && size > pos ? size - pos : 0;
+  }
+}
+
+stdio_istreambuf::int_type stdio_istreambuf::underflow()
+{
+  int c = getc(_M_file);
+  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 __SYMBIAN32__
+  const int_type eof = traits_type::eof();
+  return this->underflow() == eof 
+    ? eof
+    : traits_type::to_int_type(_FILE_I_postincr(_M_file));
+#else
+  int c = getc(_M_file);
+  return c != EOF ? c : traits_type::eof();
+#endif    
+}
+
+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() {}
+
+_STLP_EXP_DECLSPEC 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 {
+    int result = putc(c, _M_file);
+    return result != EOF ? result : traits_type::eof();
+  }
+}
+
+__SGI_END_NAMESPACE
+
+// Local Variables:
+// mode:C++
+// End:
+