Browse Source

define FileStream::attach()

David Rose 16 years ago
parent
commit
23bd4d6ae3

+ 132 - 0
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

+ 27 - 0
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:

+ 71 - 1
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

+ 6 - 0
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();