+#if defined(__WIN32__) && wxUSE_STREAMS
+
+// ----------------------------------------------------------------------------
+// wxPipeStreams
+// ----------------------------------------------------------------------------
+
+class wxPipeInputStream: public wxInputStream
+{
+public:
+ wxPipeInputStream(HANDLE hInput);
+ ~wxPipeInputStream();
+
+ virtual bool Eof() const;
+
+protected:
+ size_t OnSysRead(void *buffer, size_t len);
+
+protected:
+ HANDLE m_hInput;
+};
+
+class wxPipeOutputStream: public wxOutputStream
+{
+public:
+ wxPipeOutputStream(HANDLE hOutput);
+ ~wxPipeOutputStream();
+
+protected:
+ size_t OnSysWrite(const void *buffer, size_t len);
+
+protected:
+ HANDLE m_hOutput;
+};
+
+// ==================
+// wxPipeInputStream
+// ==================
+
+wxPipeInputStream::wxPipeInputStream(HANDLE hInput)
+{
+ m_hInput = hInput;
+}
+
+wxPipeInputStream::~wxPipeInputStream()
+{
+ ::CloseHandle(m_hInput);
+}
+
+bool wxPipeInputStream::Eof() const
+{
+ DWORD nAvailable;
+
+ // function name is misleading, it works with anon pipes as well
+ DWORD rc = ::PeekNamedPipe
+ (
+ m_hInput, // handle
+ NULL, 0, // ptr to buffer and its size
+ NULL, // [out] bytes read
+ &nAvailable, // [out] bytes available
+ NULL // [out] bytes left
+ );
+
+ if ( !rc )
+ {
+ if ( ::GetLastError() != ERROR_BROKEN_PIPE )
+ {
+ // unexpected error
+ wxLogLastError(_T("PeekNamedPipe"));
+ }
+
+ // don't try to continue reading from a pipe if an error occured or if
+ // it had been closed
+ return TRUE;
+ }
+ else
+ {
+ return nAvailable == 0;
+ }
+}
+
+size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
+{
+ // reading from a pipe may block if there is no more data, always check for
+ // EOF first
+ m_lasterror = wxSTREAM_NOERROR;
+ if ( Eof() )
+ return 0;
+
+ DWORD bytesRead;
+ if ( !::ReadFile(m_hInput, buffer, len, &bytesRead, NULL) )
+ {
+ if ( ::GetLastError() == ERROR_BROKEN_PIPE )
+ m_lasterror = wxSTREAM_EOF;
+ else
+ m_lasterror = wxSTREAM_READ_ERROR;
+ }
+
+ return bytesRead;
+}
+
+// ==================
+// wxPipeOutputStream
+// ==================
+
+wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
+{
+ m_hOutput = hOutput;
+}
+
+wxPipeOutputStream::~wxPipeOutputStream()
+{
+ ::CloseHandle(m_hOutput);
+}
+
+size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
+{
+ DWORD bytesRead;
+
+ m_lasterror = wxSTREAM_NOERROR;
+ if ( !::WriteFile(m_hOutput, buffer, len, &bytesRead, NULL) )
+ {
+ if ( ::GetLastError() == ERROR_BROKEN_PIPE )
+ m_lasterror = wxSTREAM_EOF;
+ else
+ m_lasterror = wxSTREAM_READ_ERROR;
+ }
+
+ return bytesRead;
+}
+
+#endif // __WIN32__
+
+// ============================================================================
+// implementation
+// ============================================================================