00001 /* 00002 * channel.h 00003 * 00004 * I/O channel ancestor class. 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (c) 1993-1998 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Portions are Copyright (C) 1993 Free Software Foundation, Inc. 00025 * All Rights Reserved. 00026 * 00027 * Contributor(s): ______________________________________. 00028 * 00029 * $Log: channel.h,v $ 00030 * Revision 1.49 2005/11/30 12:47:37 csoutheren 00031 * Removed tabs, reformatted some code, and changed tags for Doxygen 00032 * 00033 * Revision 1.48 2005/11/25 03:43:47 csoutheren 00034 * Fixed function argument comments to be compatible with Doxygen 00035 * 00036 * Revision 1.47 2005/09/18 11:05:36 dominance 00037 * include/ptlib/channel.h, include/ptlib/pstring.h, src/ptlib/common/contain.cxx, 00038 * src/ptlib/common/pchannel.cxx: 00039 * correct the STL defined checking to use proper syntax. 00040 * 00041 * include/ptlib/object.h: 00042 * re-add typedef to compile on mingw 00043 * 00044 * make/ptlib-config.in: 00045 * import a long-standing fix from the Debian packs which allows usage of 00046 * ptlib-config without manually adding -lpt for each of the subsequent 00047 * projects 00048 * 00049 * Revision 1.46 2005/08/05 20:44:46 csoutheren 00050 * Fixed typo 00051 * 00052 * Revision 1.45 2005/08/05 20:41:41 csoutheren 00053 * Added unix support for scattered read/write 00054 * 00055 * Revision 1.44 2005/08/05 19:42:09 csoutheren 00056 * Added support for scattered read/write 00057 * 00058 * Revision 1.43 2004/04/09 06:38:10 rjongbloed 00059 * Fixed compatibility with STL based streams, eg as used by VC++2003 00060 * 00061 * Revision 1.42 2003/12/19 04:29:52 csoutheren 00062 * Changed GetLastReadCount and GetLastWriteCount to be virtual 00063 * 00064 * Revision 1.41 2003/09/17 05:41:58 csoutheren 00065 * Removed recursive includes 00066 * 00067 * Revision 1.40 2003/09/17 01:18:02 csoutheren 00068 * Removed recursive include file system and removed all references 00069 * to deprecated coooperative threading support 00070 * 00071 * Revision 1.39 2002/09/16 01:08:59 robertj 00072 * Added #define so can select if #pragma interface/implementation is used on 00073 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00074 * 00075 * Revision 1.38 2002/07/04 23:35:47 robertj 00076 * Fixed documentation error 00077 * 00078 * Revision 1.37 2002/04/09 02:30:18 robertj 00079 * Removed GCC3 variable as __GNUC__ can be used instead, thanks jason Spence 00080 * 00081 * Revision 1.36 2002/01/26 23:55:55 craigs 00082 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net 00083 * 00084 * Revision 1.35 2001/11/13 04:13:22 robertj 00085 * Added ability to adjust size of ios buffer on PChannels. 00086 * 00087 * Revision 1.34 2001/09/11 03:27:46 robertj 00088 * Improved error processing on high level protocol failures, usually 00089 * caused by unexpected shut down of a socket. 00090 * 00091 * Revision 1.33 2001/09/10 02:51:22 robertj 00092 * Major change to fix problem with error codes being corrupted in a 00093 * PChannel when have simultaneous reads and writes in threads. 00094 * 00095 * Revision 1.32 2001/06/04 10:13:08 robertj 00096 * Added compare function to compare value of os_handle. 00097 * Added has function based on os_handle value. 00098 * 00099 * Revision 1.31 2001/05/22 12:49:32 robertj 00100 * Did some seriously wierd rewrite of platform headers to eliminate the 00101 * stupid GNU compiler warning about braces not matching. 00102 * 00103 * Revision 1.30 1999/11/05 09:37:46 craigs 00104 * Made static form of ConvertOSError public scope 00105 * 00106 * Revision 1.29 1999/10/09 01:22:06 robertj 00107 * Fixed error display for sound channels. 00108 * 00109 * Revision 1.28 1999/03/09 02:59:49 robertj 00110 * Changed comments to doc++ compatible documentation. 00111 * 00112 * Revision 1.27 1998/09/23 06:20:18 robertj 00113 * Added open source copyright license. 00114 * 00115 * Revision 1.26 1998/02/03 06:29:10 robertj 00116 * Added new function to read a block with minimum number of bytes. 00117 * 00118 * Revision 1.25 1997/07/08 13:15:03 robertj 00119 * DLL support. 00120 * 00121 * Revision 1.24 1996/11/04 03:41:04 robertj 00122 * Added extra error message for UDP packet truncated. 00123 * 00124 * Revision 1.23 1996/09/14 13:09:17 robertj 00125 * Major upgrade: 00126 * rearranged sockets to help support IPX. 00127 * added indirect channel class and moved all protocols to descend from it, 00128 * separating the protocol from the low level byte transport. 00129 * 00130 * Revision 1.22 1996/08/17 10:00:19 robertj 00131 * Changes for Windows DLL support. 00132 * 00133 * Revision 1.21 1996/07/27 04:15:07 robertj 00134 * Created static version of ConvertOSError(). 00135 * Created static version of GetErrorText(). 00136 * 00137 * Revision 1.20 1996/05/26 03:24:40 robertj 00138 * Compatibility to GNU 2.7.x 00139 * 00140 * Revision 1.19 1996/04/15 12:33:03 robertj 00141 * Fixed SetReadTimeout/SetWriteTimeout to use const reference so works with GNU compiler. 00142 * 00143 * Revision 1.18 1996/04/14 02:53:30 robertj 00144 * Split serial and pipe channel into separate compilation units for Linux executable size reduction. 00145 * 00146 * Revision 1.17 1996/02/19 13:12:48 robertj 00147 * Added new error code for interrupted I/O. 00148 * 00149 * Revision 1.16 1996/01/23 13:09:14 robertj 00150 * Mac Metrowerks compiler support. 00151 * 00152 * Revision 1.15 1995/08/12 22:28:22 robertj 00153 * Work arounf for GNU bug: can't have private copy constructor with multiple inheritance. 00154 * 00155 * Revision 1.14 1995/07/31 12:15:42 robertj 00156 * Removed PContainer from PChannel ancestor. 00157 * 00158 * Revision 1.13 1995/06/17 11:12:21 robertj 00159 * Documentation update. 00160 * 00161 * Revision 1.12 1995/06/04 08:42:00 robertj 00162 * Fixed comment. 00163 * 00164 * Revision 1.11 1995/03/14 12:41:03 robertj 00165 * Updated documentation to use HTML codes. 00166 * 00167 * Revision 1.10 1995/03/12 04:36:53 robertj 00168 * Moved GetHandle() function from PFile to PChannel. 00169 * 00170 * Revision 1.9 1994/12/21 11:52:48 robertj 00171 * Documentation and variable normalisation. 00172 * 00173 * Revision 1.8 1994/11/28 12:31:40 robertj 00174 * Documentation. 00175 * 00176 * Revision 1.7 1994/08/23 11:32:52 robertj 00177 * Oops 00178 * 00179 * Revision 1.6 1994/08/22 00:46:48 robertj 00180 * Added pragma fro GNU C++ compiler. 00181 * 00182 * Revision 1.5 1994/08/21 23:43:02 robertj 00183 * Moved meta-string transmitter from PModem to PChannel. 00184 * Added common entry point to convert OS error to PChannel error. 00185 * 00186 * Revision 1.4 1994/07/17 10:46:06 robertj 00187 * Unix support changes. 00188 * 00189 * Revision 1.3 1994/07/02 03:03:49 robertj 00190 * Changed to allow for platform dependent part. 00191 * 00192 * Revision 1.2 1994/06/25 11:55:15 robertj 00193 * Unix version synchronisation. 00194 * 00195 * Revision 1.1 1994/04/20 12:17:44 robertj 00196 * Initial revision 00197 * 00198 */ 00199 00200 #ifndef _PCHANNEL 00201 #define _PCHANNEL 00202 00203 #ifdef P_USE_PRAGMA 00204 #pragma interface 00205 #endif 00206 00207 #include <ptlib/mutex.h> 00208 00210 // I/O Channels 00211 00212 class PChannel; 00213 00214 /* Buffer class used in PChannel stream. 00215 This class is necessary for implementing the standard C++ iostream interface 00216 on #PChannel# classes and its descendents. It is an internal class and 00217 should not ever be used by application writers. 00218 */ 00219 class PChannelStreamBuffer : public streambuf { 00220 00221 protected: 00222 /* Construct the streambuf for standard streams on a channel. This is used 00223 internally by the #PChannel# class. 00224 */ 00225 PChannelStreamBuffer( 00226 PChannel * chan // Channel the buffer operates on. 00227 ); 00228 00229 virtual int overflow(int=EOF); 00230 virtual int underflow(); 00231 virtual int sync(); 00232 #ifdef __USE_STL__ 00233 virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode = ios_base::in | ios_base::out); 00234 virtual pos_type seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out); 00235 #else 00236 virtual streampos seekoff(streamoff, ios::seek_dir, int); 00237 #endif 00238 00239 BOOL SetBufferSize( 00240 PINDEX newSize 00241 ); 00242 00243 private: 00244 // Member variables 00245 PChannel * channel; 00246 PCharArray input, output; 00247 00248 public: 00249 PChannelStreamBuffer(const PChannelStreamBuffer & sbuf); 00250 PChannelStreamBuffer & operator=(const PChannelStreamBuffer & sbuf); 00251 00252 friend class PChannel; 00253 }; 00254 00255 00277 class PChannel : public PObject, public iostream { 00278 PCLASSINFO(PChannel, PObject); 00279 00280 public: 00283 00284 PChannel(); 00285 00287 ~PChannel(); 00289 00301 virtual Comparison Compare( 00302 const PObject & obj 00303 ) const; 00304 00318 virtual PINDEX HashFunction() const; 00320 00330 virtual BOOL IsOpen() const; 00331 00337 virtual PString GetName() const; 00338 00344 int GetHandle() const; 00345 00355 virtual PChannel * GetBaseReadChannel() const; 00356 00366 virtual PChannel * GetBaseWriteChannel() const; 00368 00378 void SetReadTimeout( 00379 const PTimeInterval & time 00380 ); 00381 00388 PTimeInterval GetReadTimeout() const; 00389 00402 virtual BOOL Read( 00403 void * buf, 00404 PINDEX len 00405 ); 00406 00421 virtual PINDEX GetLastReadCount() const; 00422 00430 virtual int ReadChar(); 00431 00440 BOOL ReadBlock( 00441 void * buf, 00442 PINDEX len 00443 ); 00444 00452 PString ReadString(PINDEX len); 00453 00465 virtual BOOL ReadAsync( 00466 void * buf, 00467 PINDEX len 00468 ); 00469 00474 virtual void OnReadComplete( 00475 void * buf, 00476 PINDEX len 00477 ); 00479 00489 void SetWriteTimeout( 00490 const PTimeInterval & time 00491 ); 00492 00500 PTimeInterval GetWriteTimeout() const; 00501 00513 virtual BOOL Write( 00514 const void * buf, 00515 PINDEX len 00516 ); 00517 00530 virtual PINDEX GetLastWriteCount() const; 00531 00540 BOOL WriteChar(int c); 00541 00548 BOOL WriteString(const PString & str); 00549 00559 virtual BOOL WriteAsync( 00560 const void * buf, 00561 PINDEX len 00562 ); 00563 00569 virtual void OnWriteComplete( 00570 const void * buf, 00571 PINDEX len 00572 ); 00574 00581 virtual BOOL Close(); 00582 00583 enum ShutdownValue { 00584 ShutdownRead = 0, 00585 ShutdownWrite = 1, 00586 ShutdownReadAndWrite = 2 00587 }; 00588 00596 virtual BOOL Shutdown( 00597 ShutdownValue option 00598 ); 00599 00605 BOOL SetBufferSize( 00606 PINDEX newSize 00607 ); 00608 00648 BOOL SendCommandString( 00649 const PString & command 00650 ); 00651 00656 void AbortCommandString(); 00658 00664 enum Errors { 00665 NoError, 00667 NotFound, 00669 FileExists, 00671 DiskFull, 00673 AccessDenied, 00675 DeviceInUse, 00677 BadParameter, 00679 NoMemory, 00681 NotOpen, 00683 Timeout, 00685 Interrupted, 00687 BufferTooSmall, 00689 Miscellaneous, 00691 ProtocolFailure, 00692 NumNormalisedErrors 00693 }; 00694 00700 enum ErrorGroup { 00701 LastReadError, 00702 LastWriteError, 00703 LastGeneralError, 00704 NumErrorGroups 00705 }; 00706 00711 Errors GetErrorCode( 00712 ErrorGroup group = NumErrorGroups 00713 ) const; 00714 00720 int GetErrorNumber( 00721 ErrorGroup group = NumErrorGroups 00722 ) const; 00723 00729 virtual PString GetErrorText( 00730 ErrorGroup group = NumErrorGroups 00731 ) const; 00732 00739 static PString GetErrorText( 00740 Errors lastError, 00741 int osError = 0 00742 ); 00744 00751 static BOOL ConvertOSError( 00752 int libcReturnValue, 00753 Errors & lastError, 00754 int & osError 00755 ); 00756 00761 #if P_HAS_RECVMSG 00762 typedef iovec Slice; 00763 #else 00764 struct Slice { 00765 void * iov_base; 00766 size_t iov_len; 00767 }; 00768 #endif 00769 00770 typedef std::vector<Slice> VectorOfSlice; 00771 00781 virtual BOOL Read( 00782 const VectorOfSlice & slices // slices to read to 00783 ); 00784 00794 virtual BOOL Write( 00795 const VectorOfSlice & slices // slices to read to 00796 ); 00798 00799 protected: 00800 PChannel(const PChannel &); 00801 PChannel & operator=(const PChannel &); 00802 // Prevent usage by external classes 00803 00804 00811 virtual BOOL ConvertOSError( 00812 int libcReturnValue, 00813 ErrorGroup group = LastGeneralError 00814 ); 00815 00819 BOOL SetErrorValues( 00820 Errors errorCode, 00821 int osError, 00822 ErrorGroup group = LastGeneralError 00823 ); 00824 00833 int ReadCharWithTimeout( 00834 PTimeInterval & timeout // Timeout for read. 00835 ); 00836 00837 // Receive a (partial) command string, determine if completed yet. 00838 BOOL ReceiveCommandString( 00839 int nextChar, 00840 const PString & reply, 00841 PINDEX & pos, 00842 PINDEX start 00843 ); 00844 00845 00846 // Member variables 00848 int os_handle; 00850 Errors lastErrorCode[NumErrorGroups+1]; 00852 int lastErrorNumber[NumErrorGroups+1]; 00854 PINDEX lastReadCount; 00856 PINDEX lastWriteCount; 00858 PTimeInterval readTimeout; 00860 PTimeInterval writeTimeout; 00861 00862 00863 private: 00864 // New functions for class 00865 void Construct(); 00866 // Complete platform dependent construction. 00867 00868 // Member variables 00869 BOOL abortCommandString; 00870 // Flag to abort the transmission of a command in SendCommandString(). 00871 00872 00873 // Include platform dependent part of class 00874 #ifdef _WIN32 00875 #include "msos/ptlib/channel.h" 00876 #else 00877 #include "unix/ptlib/channel.h" 00878 #endif 00879 00880 }; 00881 00882 #endif 00883 00884 // End Of File ///////////////////////////////////////////////////////////////