patch - implement stdio_fstream

Robert Schweikert rjschwei@cox.net
Fri Feb 20 02:11:00 GMT 2004


Here is a patch implementing stdio_fstream, and extension that is
usefull for applications requiring legacy APIs or applications wanting
to attach a stream to a pipe or an open file.

I am still waiting for the copyright assignment paper work but thought
I'd post the patch to allow people to comment or let me if I need to
make any corrections.

The patch was created against the latest cvs tree.

Thanks,
Robert

diff -c3p gcc/libstdc++-v3/ChangeLog gccMod/libstdc++-v3/ChangeLog
*** gcc/libstdc++-v3/ChangeLog  Thu Feb 19 17:07:28 2004
--- gccMod/libstdc++-v3/ChangeLog       Thu Feb 19 21:01:46 2004
***************
*** 1,3 ****
--- 1,14 ----
+ 2004-02-19  Robert Schweikert <rjschwei@cox.net>
+
+       * include/ext/stdio_filebuf.h:
+       Add default constructor for deferred initialization.
+       * include/ext/stdio_fstream.h:
+       Implement ifstream, ofstream, and fstream using stdio_filebuf
+       providong legacy API. These extensions are provided by
Dinkumware
+       and Rogue Wave.
+       * testsuite/ext/stdio_fstream/extFstreamTest.cc:
+       Test case for stdio_fstream functionality.
+
  2004-02-19  David Edelsohn  <edelsohn@gnu.org>
    
        * 22_locale/collate/compare/wchar_t/2.cc: Change input-charset
diff -c3pN gcc/libstdc++-v3/include/ext/stdio_filebuf.h
gccMod/libstdc++-v3/include/ext/stdio_filebuf.h
*** gcc/libstdc++-v3/include/ext/stdio_filebuf.h        Mon Dec  8
23:31:53 2003--- gccMod/libstdc++-v3/include/ext/stdio_filebuf.h     Thu
Feb 19 20:41:46 2004*************** namespace __gnu_cxx
*** 63,68 ****
--- 63,73 ----
   
      public:
        /**
+        * deferred initialization
+       */
+       stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {}
+
+       /**
         *  @param  fd  An open file descriptor.
         *  @param  mode  Same meaning as in a standard filebuf.
         *  @param  size  Optimal or preferred size of internal buffer,
in chars.
diff -c3pN gcc/libstdc++-v3/include/ext/stdio_fstream.h
gccMod/libstdc++-v3/include/ext/stdio_fstream.h
*** gcc/libstdc++-v3/include/ext/stdio_fstream.h        Wed Dec 31
19:00:00 1969--- gccMod/libstdc++-v3/include/ext/stdio_fstream.h     Thu
Feb 19 20:42:04 2004***************
*** 0 ****
--- 1,541 ----
+ // File based streams -*- C++ -*-
+
+ // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ // Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License
along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free
software
+ // library without restriction.  Specifically, if other files
instantiate
+ // templates or use macros or inline functions from this file, or you
compile
+ // this file and link it with other files to produce an executable,
this
+ // file does not by itself cause the resulting executable to be
covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be
covered by
+ // the GNU General Public License.
+
+ //
+ // Non standard stream supporting legacy API
+ //
+
+ /** @file stdio_fstream
+  *  This nonstandard implementation of the streams supports the legacy
API
+  *  used by many applications. It is necessary especially since the
+  *  Standard C++ Library does not support connecting a stream to a
pipe
+  *  or open file. This type of extension is also found in most
commercial
+  *  imlpementations of the STL, namely Dinkumware and Rogue Wave.
+ */
+
+ #ifndef _CPP_STDIO_FSTREAM
+ #define _CPP_STDIO_FSTREAM  1
+
+ #pragma GCC system_header
+
+ #include <istream>
+ #include <ostream>
+ #include <ext/stdio_filebuf.h>
+
+ namespace __gnu_cxx
+ {
+   // Template class stdio_ifstream
+   /**
+    *  @brief  Controlling input for files.
+    *
+    *  This class supports reading from files, using the inherited
+    *  functions from std::basic_istream.  To control the associated
+    *  sequence, an instance of __gnu_cxx::stdio_filebuf is used, which
this
+    *  page refers to as @c sb.
+    *  This class also supports legacy APIs such as construction with
+    *  FILE* and fd
+   */
+
+  template<typename _CharT, typename _Traits>
+    class stdio_ifstream : public std::basic_istream<_CharT, _Traits>
+    {
+    public:
+      // Types:
+      typedef _CharT char_type;
+      typedef _Traits traits_type;
+      typedef typename traits_type::int_type int_type;
+      typedef typename traits_type::pos_type pos_type;
+      typedef typename traits_type::off_type off_type;
+
+      typedef stdio_filebuf<char_type, traits_type> __filebuf_type;
+      typedef std::basic_istream<char_type, traits_type>
__istream_type;
+
+    private:
+      /**
+        *  @if maint
+        *  @doctodo
+        *  @endif
+      */
+      __filebuf_type   _M_filebuf;
+
+    public:
+      // Constructors/Destructors:
+      /**
+       *  @brief  Default constructor deferred initialization
+       *
+       *  Initializes @c sb using its default constructor, and passes
+       *  @c &sb to the base class initializer.  Does not open any
files
+      */
+      stdio_ifstream()
+      : __istream_type(NULL), _M_filebuf()
+      { this->init(&_M_filebuf); }
+
+      /**
+       *  @brief  Create an input file stream.
+       *  @param  s  Null terminated string specifying the filename.
+       *  @param  mode  Open file in specified mode (see
std::ios_base).
+       *
+       *  @c ios_base::in is automatically included in @a mode.
+       *
+       *  Tip:  When using std::string to hold the filename, you must
use
+       *  .c_str() before passing it to this constructor.
+      */
+      stdio_ifstream(const char* __s,
+                     std::ios_base::openmode __mode =
std::ios_base::in)
+      : __istream_type(NULL), _M_filebuf()
+      {
+         this->init(&_M_filebuf);
+         this->open(__s,__mode);
+      }
+
+      /**
+       *  @brief  Create an input file stream.
+       *  @param  f  a standard C FILE*
+       *
+       *  @c ios_base::in is automatically included in @a mode.
+       *
+       *  Tip: It is assumed here that the file has read permissions
and
+       *  was opened with "r" or "r+". There are nor checks performed
for
+       *  the mode.
+      */
+      stdio_ifstream(std::__c_file* __f)
+      : __istream_type(NULL), _M_filebuf(__f, std::ios_base::in)
+      { this->init(&_M_filebuf); }
+
+      /**
+       *  @brief  Create an input file stream.
+       *  @param  fd   a file descriptor
+       *
+       *  @c ios_base::in is automatically included in @a mode.
+       *
+       *  Tip: It is assumed here that the file has read permissions
and
+       *  was opened with "r" or "r+". There are nor checks performed
for
+       *  the mode.
+      */
+      stdio_ifstream(int __fd)
+      : __istream_type(NULL), _M_filebuf(__fd, std::ios_base::in)
+      { this->init(&_M_filebuf); }
+
+      /**
+       *  @brief  The destructor does nothing.
+       *
+       *  The file is closed by the filebuf object, not the formatting
+       *  stream.
+      */
+      ~stdio_ifstream()
+      { }
+
+      // Members:
+      /**
+       *  @brief  Accessing the underlying buffer.
+       *  @return  The current stdio_filebuf buffer.
+       *
+       *  This hides both signatures of std::basic_ios::rdbuf().
+      */
+      stdio_filebuf<char_type>*
+      rdbuf() const
+      { return const_cast<stdio_filebuf<char_type>*>(&_M_filebuf); }
+
+      /**
+       *  @brief   Legacy method to access the file decriptor.
+       *  @return  int current file descriptor.
+       *
+       *  This is a wrapper to the @c fd method.
+      */
+      int
+      fd()
+      { return _M_filebuf.fd(); }
+
+      /**
+       *  @brief  Wrapper to test for an open file.
+       *  @return  @c rdbuf()->is_open()
+      */
+      bool
+      is_open()
+      { return _M_filebuf.is_open(); }
+
+      /**
+       *  @brief  Opens an external file.
+       *  @param  s  The name of the file.
+       *  @param  mode  The open mode flags.
+       *
+       *  Calls @c __gnu_cxx::stdio_filebuf::open(s,mode|in).  If that
function+       *  fails, @c failbit is set in the stream's error state.
+       *
+       *  Tip:  When using std::string to hold the filename, you must
use
+       *  .c_str() before passing it to this constructor.
+      */
+      void
+      open(const char* __s, std::ios_base::openmode __mode =
std::ios_base::in)+      {
+         if (! _M_filebuf.open(__s, __mode | std::ios_base::in))
+             this->setstate(std::ios_base::failbit);
+      }
+
+      /**
+       *  @brief  Close the file.
+       *
+       *  Calls @c __gnu_cxx::stdio_filebuf::close().  If that function
+       *  fails, @c failbit is set in the stream's error state.
+      */
+      void
+      close()
+      {
+         if (! _M_filebuf.close())
+             this->setstate(std::ios_base::failbit);
+      }
+    };
+
+   // Template class stdio_ofstream
+   /**
+    *  @brief  Controlling output for files.
+    *
+    *  This class supports writing to files, using the inherited
+    *  functions from std::basic_ostream.  To control the associated
+    *  sequence, an instance of __gnu_cxx::stdio_filebuf is used, which
this
+    *  page refers to as @c sb.
+    *  This class also supports legacy APIs such as construction with
+    *  FILE* and fd
+   */
+   template<typename _CharT, typename _Traits>
+     class stdio_ofstream : public std::basic_ostream<_CharT, _Traits>
+   {
+   public:
+     // Types:
+     typedef _CharT char_type;
+     typedef _Traits traits_type;
+     typedef typename traits_type::int_type int_type;
+     typedef typename traits_type::pos_type pos_type;
+     typedef typename traits_type::off_type off_type;
+
+     typedef stdio_filebuf<char_type, traits_type> __filebuf_type;
+     typedef std::basic_ostream<char_type, traits_type> __ostream_type;
+
+   private:
+     /**
+      *  @if maint
+      *  @doctodo
+      *  @endif
+     */
+     __filebuf_type    _M_filebuf;
+
+   public:
+     // Constructors/Destructors:
+     /**
+      *  @brief  Default constructor deferred initialization
+      *
+      *  Initializes @c sb using its default constructor, and passes
+      *  @c &sb to the base class initializer.  Does not open any files
+     */
+     stdio_ofstream()
+     : __ostream_type(NULL), _M_filebuf()
+     { this->init(&_M_filebuf); }
+
+     /**
+      *  @brief  Create an output file stream.
+      *  @param  s  Null terminated string specifying the filename.
+      *  @param  mode  Open file in specified mode (see std::ios_base).
+      *
+      *  @c ios_base::out is automatically included in @a mode.
+      *
+      *  Tip:  When using std::string to hold the filename, you must
use
+      *  .c_str() before passing it to this constructor.
+     */
+     stdio_ofstream(const char* __s,
+                    std::ios_base::openmode __mode =
std::ios_base::out)
+     : __ostream_type(NULL), _M_filebuf()
+     {
+         this->init(&_M_filebuf);
+         this->open(__s,__mode);
+     }
+
+     /**
+      *  @brief  Create an output file stream.
+      *  @param  f  a standard C FILE*
+      *
+      *  @c ios_base::out is automatically included in @a mode.
+      *
+      *  Tip: It is assumed here that the file has read permissions and
+      *  was opened with "w" or "w+". There are nor checks performed
for
+      *  the mode.
+     */
+     stdio_ofstream(std::__c_file* __f)
+     : __ostream_type(NULL), _M_filebuf(__f, std::ios_base::out)
+     { this->init(&_M_filebuf); }
+
+     /**
+      *  @brief  Create an output file stream.
+      *  @param  fd   a file descriptor
+      *
+      *  @c ios_base::out is automatically included in @a mode.
+      *
+      *  Tip: It is assumed here that the file has read permissions and
+      *  was opened with "w" or "w+". There are nor checks performed
for
+      *  the mode.
+     */
+     stdio_ofstream(int __fd)
+     : __ostream_type(NULL), _M_filebuf(__fd, std::ios_base::out)
+     { this->init(&_M_filebuf); }
+
+     /**
+      *  @brief  The destructor does nothing.
+      *
+      *  The file is closed by the filebuf object, not the formatting
+      *  stream.
+     */
+     ~stdio_ofstream()
+     { }
+
+     // Members:
+     /**
+      *  @brief  Accessing the underlying buffer.
+      *  @return  The current stdio_filebuf buffer.
+      *
+      *  This hides both signatures of std::basic_ios::rdbuf().
+     */
+     stdio_filebuf<char_type>*
+     rdbuf() const
+     { return const_cast<stdio_filebuf<char_type>*>(&_M_filebuf); }
+
+     /**
+      *  @brief   Legacy method to access the file decriptor.
+      *  @return  int current file descriptor.
+      *
+      *  This is a wrapper to the @c fd method.
+     */
+     int
+     fd()
+     { return _M_filebuf.fd(); }
+
+     /**
+      *  @brief  Wrapper to test for an open file.
+      *  @return  @c rdbuf()->is_open()
+     */
+     bool
+     is_open()
+     { return _M_filebuf.is_open(); }
+
+     /**
+      *  @brief  Opens an external file.
+      *  @param  s  The name of the file.
+      *  @param  mode  The open mode flags.
+      *
+      *  Calls @c __gnu_cxx::stdio_filebuf::open(s,mode|out).  If that
function+      *  fails, @c failbit is set in the stream's error state.
+      *
+      *  Tip:  When using std::string to hold the filename, you must
use
+      *  .c_str() before passing it to this constructor.
+     */
+     void
+     open(const char* __s, std::ios_base::openmode __mode =
std::ios_base::out)+     {
+         if (! _M_filebuf.open(__s, __mode | std::ios_base::out))
+             this->setstate(std::ios_base::failbit);
+     }
+
+     /**
+      *  @brief  Close the file.
+      *
+      *  Calls @c __gnu_cxx::stdio_filebuf::close().  If that function
+      *  fails, @c failbit is set in the stream's error state.
+     */
+     void
+     close()
+     {
+         if (! _M_filebuf.close())
+             this->setstate(std::ios_base::failbit);
+     }
+   };
+
+   // Template class stdio_fstream
+   /**
+    *  @brief  Controlling input and output for files.
+    *
+    *  This class supports reading from files, using the inherited
+    *  functions from std::basic_iostream.  To control the associated
+    *  sequence, an instance of __gnu_cxx::stdio_filebuf is used, which
this
+    *  page refers to as @c sb.
+    *  This class also supports legacy APIs such as construction with
+    *  FILE* and fd
+   */
+   template<typename _CharT, typename _Traits>
+     class stdio_fstream : public std::basic_iostream<_CharT, _Traits>
+     {
+     public:
+       // Types:
+       typedef _CharT char_type;
+       typedef _Traits traits_type;
+       typedef typename traits_type::int_type int_type;
+       typedef typename traits_type::pos_type pos_type;
+       typedef typename traits_type::off_type off_type;
+
+       typedef stdio_filebuf<char_type, traits_type> __filebuf_type;
+       typedef std::basic_iostream<char_type, traits_type>
__iostream_type;
+
+     private:
+       /**
+        *  @if maint
+        *  @doctodo
+        *  @endif
+       */
+       __filebuf_type  _M_filebuf;
+
+     public:
+       // Constructors/Destructors:
+       /**
+        *  @brief  Default constructor deferred initialization
+        *
+        *  Initializes @c sb using its default constructor, and passes
+        *  @c &sb to the base class initializer.  Does not open any
files
+       */
+       stdio_fstream() : __iostream_type(NULL), _M_filebuf()
+       { this->init(&_M_filebuf); }
+
+       /**
+        *  @brief  Create an input/output file stream.
+        *  @param  s  Null terminated string specifying the filename.
+        *  @param  mode  Open file in specified mode (see
std::ios_base).
+        *
+        *  @c ios_base::in|ios_base::out is automatically included in
@a mode.
+        *
+        *  Tip:  When using std::string to hold the filename, you must
use
+        *  .c_str() before passing it to this constructor.
+       */
+       stdio_fstream(const char* __s,
+          std::ios_base::openmode __mode =
std::ios_base::in|std::ios_base::out)
+       : __iostream_type(NULL), _M_filebuf()
+       {
+           this->init(&_M_filebuf);
+           this->open(__s, __mode);
+       }
+
+       /**
+        *  @brief  Create an input/output file stream.
+        *  @param  f  a standard C FILE*
+        *
+        *  @c ios_base::in|ios_base::out is automatically included in
@a mode.
+        *
+        *  Tip: It is assumed here that the file has read permissions
and
+        *  was opened with "w+" or "r+". There are nor checks performed
for
+        *  the mode.
+       */
+       stdio_fstream(std::__c_file* __f)
+       : __iostream_type(NULL),
+         _M_filebuf(__f, std::ios_base::in|std::ios_base::out)
+       { this->init(&_M_filebuf); }
+
+       /**
+        *  @brief  Create an input file stream.
+        *  @param  fd   a file descriptor
+        *
+        *  @c ios_base::in|ios_base::out is automatically included in
@a mode.
+        *
+        *  Tip: It is assumed here that the file has read permissions
and
+        *  was opened with "w+" or "r+". There are nor checks performed
for
+        *  the mode.
+       */
+       stdio_fstream(int __fd)
+       : __iostream_type(NULL),
+         _M_filebuf(__fd, std::ios_base::in|std::ios_base::out)
+       { this->init(&_M_filebuf); }
+
+       /**
+        *  @brief  The destructor does nothing.
+        *
+        *  The file is closed by the filebuf object, not the formatting
+        *  stream.
+       */
+       ~stdio_fstream()
+       { }
+
+       // Members:
+       /**
+        *  @brief  Accessing the underlying buffer.
+        *  @return  The current stdio_filebuf buffer.
+        *
+        *  This hides both signatures of std::basic_ios::rdbuf().
+       */
+       stdio_filebuf<char_type>*
+       rdbuf() const
+       { return const_cast<stdio_filebuf<char_type>*>(&_M_filebuf); }
+
+       /**
+        *  @brief   Legacy method to access the file decriptor.
+        *  @return  int current file descriptor.
+        *
+        *  This is a wrapper to the @c fd method.
+       */
+       int
+       fd()
+       { return _M_filebuf.fd(); }
+
+       /**
+        *  @brief  Wrapper to test for an open file.
+        *  @return  @c rdbuf()->is_open()
+       */
+       bool
+       is_open()
+       { return _M_filebuf.is_open(); }
+
+       /**
+        *  @brief  Opens an external file.
+        *  @param  s  The name of the file.
+        *  @param  mode  The open mode flags.
+        *
+        *  Calls @c __gnu_cxx::stdio_filebuf::open(s,mode|in|out).  If
that
+        *  function fails, @c failbit is set in the stream's error
state.
+        *
+        *  Tip:  When using std::string to hold the filename, you must
use
+        *  .c_str() before passing it to this constructor.
+       */
+       void
+       open(const char* __s,
+         std::ios_base::openmode __mode =
std::ios_base::in|std::ios_base::out)+       {
+           if (! _M_filebuf.open(__s, __mode))
+               this->setstate(std::ios_base::failbit);
+       }
+
+       /**
+        *  @brief  Close the file.
+        *
+        *  Calls @c __gnu_cxx::stdio_filebuf::close().  If that
function
+        *  fails, @c failbit is set in the stream's error state.
+       */
+       void
+       close()
+       {
+           if (! _M_filebuf.close())
+               this->setstate(std::ios_base::failbit);
+       }
+     };
+ }  // namespace __gnu_cxx
+
+ #endif
diff -c3pN
gcc/libstdc++-v3/testsuite/ext/stdio_fstream/extFstreamTest.cc
gccMod/libstdc++-v3/testsuite/ext/stdio_fstream/extFstreamTest.cc
*** gcc/libstdc++-v3/testsuite/ext/stdio_fstream/extFstreamTest.cc     
Wed Dec
31 19:00:00 1969
--- gccMod/libstdc++-v3/testsuite/ext/stdio_fstream/extFstreamTest.cc  
Thu Feb
19 20:43:39 2004
***************
*** 0 ****
--- 1,234 ----
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <string.h>
+
+ #include <iostream>
+
+ #include <ext/stdio_fstream.h>
+
+ using namespace std;
+ using namespace __gnu_cxx;
+
+ // Test case for the non standard file stream implementation
+
+ int main()
+ {
+     int success = 1;
+
+     stdio_ofstream<char, std::char_traits<char> >* testOfStream =
NULL;
+     stdio_ifstream<char, std::char_traits<char> >* testIfStream =
NULL;
+     stdio_fstream<char, std::char_traits<char> >* testFStream = NULL;
+
+     // Test 1:
+     // create a file and use the fd to create an ofstream
+     // write to the file
+     int fd = creat("test1.txt", O_CREAT|S_IRUSR|S_IWUSR);
+     testOfStream = new stdio_ofstream<char, std::char_traits<char>
>(fd);
+     *testOfStream << "Hello_world_1" << endl;
+     testOfStream->close();
+     testOfStream = NULL;
+
+     // Test 2:
+     // open an existing file and read the contents
+     fd = open("test1.txt", O_RDONLY);
+     testIfStream = new stdio_ifstream<char, std::char_traits<char>
>(fd);
+     char buf[14];
+     *testIfStream >> buf;
+     if (! strncmp("Hello_world_1", buf, 13))
+     {
+         cerr << "SUCCESS:\tTest 1\t\t" << buf << endl;
+         cerr << "SUCCESS:\tTest 2\t\t" << buf << endl;
+     }
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test1.txt (Test 2)" << endl;
+     }
+
+     // Test 3:
+     // open an existing file by name and write to it
+     testOfStream = new stdio_ofstream<char, std::char_traits<char> >
+         ("test1.txt");
+     if (testOfStream->fail())
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not open test1.txt for writing (Test 3)"
<< endl;
+     }
+     else
+         cerr << "SUCCESS:\tTest 3" << endl;
+
+     *testOfStream << "Hello_world_2" << endl;
+     testOfStream->close();
+     testOfStream = NULL;
+
+     // Test 4:
+     // open an existing file by name and read from it
+     testIfStream = new stdio_ifstream<char, std::char_traits<char> >
+         ("test1.txt");
+     if (testIfStream->fail())
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not open test1.txt for reading (Test 4)"
<< endl;
+     }
+     else
+         cerr << "SUCCESS:\tTest 4 part a" << endl;
+
+     *testIfStream >> buf;
+     if (! strncmp("Hello_world_2", buf, 13))
+         cerr << "SUCCESS:\tTest 4 part b\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test1.txt (Test 4)" << endl;
+     }
+
+     // Test 5:
+     // try to open a non existing file for writing
+     testOfStream = new stdio_ofstream<char, std::char_traits<char> >
+         ("test2.txt");
+     if (testOfStream->fail())
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not open test2.txt for writing (Test 5)"
<< endl;
+     }
+     else
+          cerr << "SUCCESS:\tTest 5" << endl;
+
+     *testOfStream << "Hello_world_3" << endl;
+     testOfStream->close();
+     testOfStream = NULL;
+
+     // Test 6:
+     // try to open a non existing file for reading
+     testIfStream = new stdio_ifstream<char, std::char_traits<char> >
+         ("test2.txt");
+     if (testIfStream->fail())
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not open test2.txt for reading (Test 6)"
<< endl;
+     }
+     else
+         cerr << "SUCCESS:\tTest 6 part a" << endl;
+
+     *testIfStream >> buf;
+     if (! strncmp("Hello_world_3", buf, 13))
+         cerr << "SUCCESS:\tTest 6 part b\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test1.txt (Test 4)" << endl;
+     }
+
+     testIfStream = NULL;
+
+     // Test 7:
+     // open an ofstream with a FILE*
+     FILE* moFile = fopen("test1.txt", "w");
+     testOfStream = new stdio_ofstream<char, std::char_traits<char>
>(moFile);
+     *testOfStream << "Hello_world_4" << endl;
+     testOfStream->close();
+     testOfStream = NULL;
+
+     // Test 8:
+     // open an ifstream with FILE*
+     FILE* miFile = fopen("test1.txt","r");
+     testIfStream = new stdio_ifstream<char, std::char_traits<char>
>(miFile);
+     *testIfStream >> buf;
+     if (! strncmp("Hello_world_4", buf, 13))
+         cerr << "SUCCESS:\tTest 8\t\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test1.txt (Test 8)" << endl;
+     }
+
+     // Test 9:
+     // open an fstream for a non existent file
+     // (the file should not get created)
+     testFStream = new stdio_fstream<char, std::char_traits<char> >
+         ("test3.txt");
+     if (testFStream->fail())
+         cerr << "SUCCESS:\tTest 9" << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tWas able to open non existent file with
fstream"
+              << endl;
+     }
+     testFStream = NULL;
+
+     // Test 10:
+     // create a file and use the fd to create an fstream
+     // write to the file
+     // read from the file
+     fd = open("test3.txt", O_CREAT|O_RDWR,
+               S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+     testFStream = new stdio_fstream<char, std::char_traits<char>
>(fd);
+     *testFStream << "Hello_world_5" << endl;
+     testFStream->flush();
+     testFStream->seekg(0);
+     *testFStream >> buf;
+     if (! strncmp("Hello_world_5", buf, 13))
+         cerr << "SUCCESS:\tTest 10\t\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test3.txt (Test 10)" << endl;
+     }
+     testFStream->close();
+     testFStream = NULL;
+
+     // Test 11:
+     // open and existing file by name
+     // write to the file and read the data back in
+     testFStream = new stdio_fstream<char, std::char_traits<char> >
+         ("test3.txt");
+     if (testFStream->fail())
+     {
+         success = 0;
+         cerr << "FAIL:\tWas unable to open existing file test3.txt "
+              << "with fstream" << endl;
+     }
+     else
+         cerr << "SUCCESS:\tTest 11 part a" << endl;
+     *testFStream << "Hello_world_6" << endl;
+     testFStream->flush();
+     testFStream->seekg(0);
+     *testFStream >> buf;
+     if (! strncmp("Hello_world_6", buf, 13))
+         cerr << "SUCCESS:\tTest 11 part b\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test3.txt (Test 11)" << endl;
+     }
+     testFStream->close();
+     testFStream = NULL;
+
+     // Test 12:
+     // open fstream with FILE*
+     // write to the file and read the data back in
+     FILE* mfile = fopen("test3.txt", "r+");
+     testFStream = new stdio_fstream<char, std::char_traits<char>
>(mfile);
+     *testFStream << "Hello_world_7" << endl;
+     testFStream->flush();
+     testFStream->seekg(0);
+     *testFStream >> buf;
+     if (! strncmp("Hello_world_7", buf, 13))
+         cerr << "SUCCESS:\tTest 12\t\t" << buf << endl;
+     else
+     {
+         success = 0;
+         cerr << "FAIL:\tCould not read test3.txt (Test 12)" << endl;
+     }
+     testFStream->close();
+     testFStream = NULL;
+
+     // Clean up
+     unlink ("test1.txt");
+     unlink ("test2.txt");
+     unlink ("test3.txt");
+
+     return success;
+ }


-- 
Robert Schweikert                   MAY THE SOURCE BE WITH YOU
rjschwei@cox.net                               LINUX




More information about the Libstdc++ mailing list