From 23bd4d6ae3b3a7f326ea36c5716d9d660ac70da8 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 9 Jun 2009 20:30:58 +0000 Subject: [PATCH] define FileStream::attach() --- dtool/src/dtoolutil/pandaFileStream.I | 132 +++++++++++++++++++++ dtool/src/dtoolutil/pandaFileStream.h | 27 +++++ dtool/src/dtoolutil/pandaFileStreamBuf.cxx | 72 ++++++++++- dtool/src/dtoolutil/pandaFileStreamBuf.h | 6 + 4 files changed, 236 insertions(+), 1 deletion(-) diff --git a/dtool/src/dtoolutil/pandaFileStream.I b/dtool/src/dtoolutil/pandaFileStream.I index 31f658dfb1..794908d06e 100644 --- a/dtool/src/dtoolutil/pandaFileStream.I +++ b/dtool/src/dtoolutil/pandaFileStream.I @@ -56,6 +56,50 @@ open(const char *filename, ios::openmode mode) { } } +#ifdef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Windows-specific variant. +//////////////////////////////////////////////////////////////////// +void IFileStream:: +attach(const char *filename, HANDLE handle, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + +#ifndef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Posix-specific variant. +//////////////////////////////////////////////////////////////////// +void IFileStream:: +attach(const char *filename, int fd, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + //////////////////////////////////////////////////////////////////// // Function: IFileStream::close // Access: Published @@ -109,6 +153,50 @@ open(const char *filename, ios::openmode mode) { } } +#ifdef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Windows-specific variant. +//////////////////////////////////////////////////////////////////// +void OFileStream:: +attach(const char *filename, HANDLE handle, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + +#ifndef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Posix-specific variant. +//////////////////////////////////////////////////////////////////// +void OFileStream:: +attach(const char *filename, int fd, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + //////////////////////////////////////////////////////////////////// // Function: OFileStream::close // Access: Published @@ -162,6 +250,50 @@ open(const char *filename, ios::openmode mode) { } } +#ifdef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: FileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Windows-specific variant. +//////////////////////////////////////////////////////////////////// +void FileStream:: +attach(const char *filename, HANDLE handle, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + +#ifndef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: FileStream::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Posix-specific variant. +//////////////////////////////////////////////////////////////////// +void FileStream:: +attach(const char *filename, int fd, ios::openmode mode) { + clear((ios_iostate)0); + _buf.attach(filename, handle, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} +#endif // _WIN32 + //////////////////////////////////////////////////////////////////// // Function: FileStream::close // Access: Published diff --git a/dtool/src/dtoolutil/pandaFileStream.h b/dtool/src/dtoolutil/pandaFileStream.h index 99929a79d5..23aa5b5521 100644 --- a/dtool/src/dtoolutil/pandaFileStream.h +++ b/dtool/src/dtoolutil/pandaFileStream.h @@ -37,6 +37,15 @@ PUBLISHED: INLINE ~IFileStream(); INLINE void open(const char *filename, ios::openmode mode = ios::in); + +public: +#ifdef _WIN32 + INLINE void attach(const char *filename, HANDLE handle, ios::openmode mode = ios::in); +#else + INLINE void attach(const char *filename, int fd, ios::openmode mode = ios::in); +#endif + +PUBLISHED: INLINE void close(); private: @@ -59,6 +68,15 @@ PUBLISHED: INLINE ~OFileStream(); INLINE void open(const char *filename, ios::openmode mode = ios::out); + +public: +#ifdef _WIN32 + INLINE void attach(const char *filename, HANDLE handle, ios::openmode mode = ios::out); +#else + INLINE void attach(const char *filename, int fd, ios::openmode mode = ios::out); +#endif + +PUBLISHED: INLINE void close(); private: @@ -81,6 +99,15 @@ PUBLISHED: INLINE ~FileStream(); INLINE void open(const char *filename, ios::openmode mode = ios::in); + +public: +#ifdef _WIN32 + INLINE void attach(const char *filename, HANDLE handle, ios::openmode mode); +#else + INLINE void attach(const char *filename, int fd, ios::openmode mode); +#endif + +PUBLISHED: INLINE void close(); private: diff --git a/dtool/src/dtoolutil/pandaFileStreamBuf.cxx b/dtool/src/dtoolutil/pandaFileStreamBuf.cxx index 99c1440230..804a0d1aa7 100644 --- a/dtool/src/dtoolutil/pandaFileStreamBuf.cxx +++ b/dtool/src/dtoolutil/pandaFileStreamBuf.cxx @@ -177,6 +177,72 @@ open(const char *filename, ios::openmode mode) { } +#ifdef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Windows-specific variant. +//////////////////////////////////////////////////////////////////// +void PandaFileStreamBuf:: +attach(const char *filename, HANDLE handle, ios::openmode mode) { + close(); + + _filename = filename; + _open_mode = mode; + _is_open = false; + + if (_open_mode & ios::app) { + // ios::app implies ios::out. + _open_mode |= ios::out; + } + + _handle = handle; + if (_handle != INVALID_HANDLE_VALUE) { + // Presumably the handle is valid. + _is_open = true; + } +} +#endif // _WIN32 + +#ifndef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::attach +// Access: Public +// Description: Connects the file stream to the existing OS-defined +// stream, presumably opened via a low-level OS call. +// The filename is for reporting only. When the file +// stream is closed, it will also close the underlying +// OS handle. +// +// This function is the Posix-specific variant. +//////////////////////////////////////////////////////////////////// +void PandaFileStreamBuf:: +attach(const char *filename, int fd, ios::openmode mode) { + close(); + + _filename = filename; + _open_mode = mode; + _is_open = false; + + if (_open_mode & ios::app) { + // ios::app implies ios::out. + _open_mode |= ios::out; + } + + _fd = fd; + if (_fd != -1) { + // Presumably the file descriptor is valid. + _is_open = true; + } +} +#endif // _WIN32 + //////////////////////////////////////////////////////////////////// // Function: PandaFileStreamBuf::is_open // Access: Public @@ -596,7 +662,7 @@ read_chars_raw(char *start, size_t length) { if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) { // Wait for more later. thread_yield(); - } else if (error == ERROR_HANDLE_EOF) { + } else if (error == ERROR_HANDLE_EOF || error == ERROR_BROKEN_PIPE) { // End-of-file, normal result. break; } else { @@ -671,6 +737,10 @@ write_chars_raw(const char *start, size_t length) { if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) { // Wait for more later. thread_yield(); + } else if (error == ERROR_BROKEN_PIPE) { + // Broken pipe, we're done. + cerr << "Pipe closed on " << _filename << "\n"; + return bytes_written; } else { cerr << "Error writing " << length diff --git a/dtool/src/dtoolutil/pandaFileStreamBuf.h b/dtool/src/dtoolutil/pandaFileStreamBuf.h index 4de6d8eb5a..4421251afd 100644 --- a/dtool/src/dtoolutil/pandaFileStreamBuf.h +++ b/dtool/src/dtoolutil/pandaFileStreamBuf.h @@ -35,6 +35,12 @@ public: virtual ~PandaFileStreamBuf(); void open(const char *filename, ios::openmode mode); +#ifdef _WIN32 + void attach(const char *filename, HANDLE handle, ios::openmode mode); +#else + void attach(const char *filename, int fd, ios::openmode mode); +#endif + bool is_open() const; void close();