This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch - implementation of stdio_fstream
- From: Robert Schweikert <rjschwei at cox dot net>
- To: gcc-libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: gcc-patch <gcc-patches at gcc dot gnu dot org>, rjschwei at cox dot net
- Date: Sun, 28 Mar 2004 15:18:14 -0500
- Subject: patch - implementation of stdio_fstream
OK,
Here we go the legal stuff shold all be taken care off now. Here is the
patch implementing an extension to hook the stdio_filbuf up with an
stdio_fstream. This allows people to hook streams up to pipes
(initialization with fd) and FILE*. Both use cases are really useful but
no longer supported by the C++ standard.
Application of the patch to the main branch is appreciated.
Thanks,
Robert
*** gcc/libstdc++-v3/ChangeLog Sat Mar 27 09:45:45 2004
--- gccMod/libstdc++-v3/ChangeLog Sun Mar 28 13:04:42 2004
***************
*** 1,3 ****
--- 1,13 ----
+ 2004-03-28 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 providing legacy API. These extensions
+ are provided by Dinkumware and Rogue Wave.
+ * testsuite/ext/stdio_fstream/extFstreamTest.cc: Test case for
+ stdio_fstream functionality.
+
2004-03-27 Paolo Carlini <pcarlini@suse.de>
* include/ext/mt_allocator.h: Uglify consistently names of
*** gcc/libstdc++-v3/include/ext/stdio_filebuf.h Mon Dec 8 23:31:53
2003
--- gccMod/libstdc++-v3/include/ext/stdio_filebuf.h Sun Mar 28 13:06:41
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.
*** gcc/libstdc++-v3/include/ext/stdio_fstream.h Wed Dec 31 19:00:00
1969
--- gccMod/libstdc++-v3/include/ext/stdio_fstream.h Sun Mar 28 13:09:27
2004
***************
*** 0 ****
--- 1,594 ----
+ // 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 s std::string
+ * @param mode Open file in specified mode (see
std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a mode.
+ *
+ */
+ stdio_ifstream(const std::string& __s,
+ std::ios_base::openmode __mode =
std::ios_base::in)
+ : __istream_type(NULL), _M_filebuf()
+ {
+ this->init(&_M_filebuf);
+ this->open(__s.c_str(),__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.
+ *
+ * The input stream is not buffered
+ */
+ stdio_ifstream(std::__c_file* __f)
+ : __istream_type(NULL), _M_filebuf(__f, std::ios_base::in, 0)
+ { 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.
+ *
+ * The input stream is not buffered
+ */
+ stdio_ifstream(int __fd)
+ : __istream_type(NULL), _M_filebuf(__fd, std::ios_base::in, 0)
+ { 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 calling open there is no control over the buffer
size
+ * and thus one ends up with a buffered read which might have
+ * undesired side effects.
+ */
+ 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 s std::string
+ * @param mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a mode.
+ *
+ */
+ stdio_ofstream(const std::string& __s,
+ std::ios_base::openmode __mode =
std::ios_base::out)
+ : __ostream_type(NULL), _M_filebuf()
+ {
+ this->init(&_M_filebuf);
+ this->open(__s.c_str(),__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 s std::string
+ * @param mode Open file in specified mode (see
std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a mode.
+ *
+ */
+ stdio_fstream(const std::string& __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.c_str(),__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
*** 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 Sun
Mar 28 13:11:10 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