Hi,

first of all, I want to thank Beman Dawes and all others that
contributed with the design and development of the Filesystem library. It's a wonderful piece of work.

I just would like to propose a couple of additions that I believe are very useful. Both features regard temporary files.

First proposal: I propose to add a function with a signature of this kind:

path generate_path_for_temp_file();

the effect would be to generate a new (potentially unique) path suitable to be used for a temporary files. A sample POSIX implementation could be as simple as:

#include <cstdio>
path generate_path_for_temp_file()
{
char tmp_name[L_tmpnam];
return path(tmpname(tmp_name), native);
}

but there could also be platform-specific implementations. For example, a Win32 sample implementation could use the GetTempPath/GetTempFileName to create the path in the correct directory as in:

#include <windows.h>
path generate_path_for_temp_file()
{
char tmp_dir_path[MAX_PATH];
char tmp_name[MAX_PATH];

if(GetTempPathA(sizeof(tmp_dir_path), tmp_dir_path) == 0
|| GetTempFileNameA(tmp_dir_path, "$$$", 0, tmp_name) == 0)
{
boost::throw_exception(
filesystem_error("unable to generate path for temporary file", system_error));
}

return path(tmp_name, native);
}

Open issues (to be discussed):

1) on Win32, GetTempFileName also create an empty file with the returned name. Other platforms also have functions that atomically generates the name *and* creates a file with such name. Should there be a postcondition about the existence (or non-existence) of such a file?

2) Another useful signature could be:

path generate_path_for_temp_file(const path& location_hint)

that would use the specified path as a hint (in an unspecified platform-dependent way) to generate the path. For example, one may want to generate a temporary file in a specified directory or physical drive, overriding the system default, if any. On Win32 such a function could be implemented as:

#include <windows.h>
path generate_path_for_temp_file(const path& hint)
{
char tmp_name[MAX_PATH];

if(GetTempFileNameA(hint.native_directory_string().c_str(), "$$$", 0, tmp_name) == 0)
{
boost::throw_exception(
filesystem_error("unable to generate path for temporary file", system_error));
}

return path(tmp_name, native);
}


Second proposal: a stream class that encapsulates a temporary file, that is a stream based on a file that is automatically deleted in the stream's destructor. I am attaching a sample implementation. It's implemented as a simple wrapper around fs::basic_fstream and generate_path_for_temp() above.

Cheers,

Alberto
#ifndef BOOST_FILESYSTEM_TEMPSTREAM_HPP
#define BOOST_FILESYSTEM_TEMPSTREAM_HPP

#include <boost/filesystem/fstream.hpp>

namespace boost
{
  namespace filesystem
  {
    path generate_path_for_temp_file();
    path generate_path_for_temp_file(const path& hint);

    template < class charT, class traits = std::char_traits<charT> >
    class basic_tempstream : public basic_fstream<charT, traits>
    {
    public:
      // ctor always opens file
      explicit basic_tempstream(std::ios_base::openmode mode = 
std::ios_base::in|std::ios_base::out)
        : m_path(generate_path_for_temp_file())
      {
        basic_fstream<charT, traits>::open(m_path, mode);
      }

      explicit basic_tempstream(const path& hint,
          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out)
        : m_path(generate_path_for_temp_file(hint))
      {
        basic_fstream<charT, traits>::open(m_path, mode);
      }

      virtual ~basic_tempstream()
      {
        remove(m_path);
      }

      // intentionally hide inherited open()
      void open(std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out)
      {
        basic_fstream<charT, traits>::open(m_path, mode);
      }

      const path& path() const
      {
        return m_path;
      }

    private:
      filesystem::path m_path;
    };
 
    typedef basic_tempstream<char> tempstream;
#   ifndef BOOST_NO_STD_WSTRING
    typedef basic_tempstream<wchar_t> wtempstream;
#   endif

  } // namespace filesystem

} // namespace boost

#endif  // BOOST_FILESYSTEM_TEMPSTREAM_HPP
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to