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.50 2006/01/27 07:54:32 csoutheren 00031 * Exposed PChannel::SetError function 00032 * 00033 * Revision 1.49 2005/11/30 12:47:37 csoutheren 00034 * Removed tabs, reformatted some code, and changed tags for Doxygen 00035 * 00036 * Revision 1.48 2005/11/25 03:43:47 csoutheren 00037 * Fixed function argument comments to be compatible with Doxygen 00038 * 00039 * Revision 1.47 2005/09/18 11:05:36 dominance 00040 * include/ptlib/channel.h, include/ptlib/pstring.h, src/ptlib/common/contain.cxx, 00041 * src/ptlib/common/pchannel.cxx: 00042 * correct the STL defined checking to use proper syntax. 00043 * 00044 * include/ptlib/object.h: 00045 * re-add typedef to compile on mingw 00046 * 00047 * make/ptlib-config.in: 00048 * import a long-standing fix from the Debian packs which allows usage of 00049 * ptlib-config without manually adding -lpt for each of the subsequent 00050 * projects 00051 * 00052 * Revision 1.46 2005/08/05 20:44:46 csoutheren 00053 * Fixed typo 00054 * 00055 * Revision 1.45 2005/08/05 20:41:41 csoutheren 00056 * Added unix support for scattered read/write 00057 * 00058 * Revision 1.44 2005/08/05 19:42:09 csoutheren 00059 * Added support for scattered read/write 00060 * 00061 * Revision 1.43 2004/04/09 06:38:10 rjongbloed 00062 * Fixed compatibility with STL based streams, eg as used by VC++2003 00063 * 00064 * Revision 1.42 2003/12/19 04:29:52 csoutheren 00065 * Changed GetLastReadCount and GetLastWriteCount to be virtual 00066 * 00067 * Revision 1.41 2003/09/17 05:41:58 csoutheren 00068 * Removed recursive includes 00069 * 00070 * Revision 1.40 2003/09/17 01:18:02 csoutheren 00071 * Removed recursive include file system and removed all references 00072 * to deprecated coooperative threading support 00073 * 00074 * Revision 1.39 2002/09/16 01:08:59 robertj 00075 * Added #define so can select if #pragma interface/implementation is used on 00076 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00077 * 00078 * Revision 1.38 2002/07/04 23:35:47 robertj 00079 * Fixed documentation error 00080 * 00081 * Revision 1.37 2002/04/09 02:30:18 robertj 00082 * Removed GCC3 variable as __GNUC__ can be used instead, thanks jason Spence 00083 * 00084 * Revision 1.36 2002/01/26 23:55:55 craigs 00085 * Changed for GCC 3.0 compatibility, thanks to manty@manty.net 00086 * 00087 * Revision 1.35 2001/11/13 04:13:22 robertj 00088 * Added ability to adjust size of ios buffer on PChannels. 00089 * 00090 * Revision 1.34 2001/09/11 03:27:46 robertj 00091 * Improved error processing on high level protocol failures, usually 00092 * caused by unexpected shut down of a socket. 00093 * 00094 * Revision 1.33 2001/09/10 02:51:22 robertj 00095 * Major change to fix problem with error codes being corrupted in a 00096 * PChannel when have simultaneous reads and writes in threads. 00097 * 00098 * Revision 1.32 2001/06/04 10:13:08 robertj 00099 * Added compare function to compare value of os_handle. 00100 * Added has function based on os_handle value. 00101 * 00102 * Revision 1.31 2001/05/22 12:49:32 robertj 00103 * Did some seriously wierd rewrite of platform headers to eliminate the 00104 * stupid GNU compiler warning about braces not matching. 00105 * 00106 * Revision 1.30 1999/11/05 09:37:46 craigs 00107 * Made static form of ConvertOSError public scope 00108 * 00109 * Revision 1.29 1999/10/09 01:22:06 robertj 00110 * Fixed error display for sound channels. 00111 * 00112 * Revision 1.28 1999/03/09 02:59:49 robertj 00113 * Changed comments to doc++ compatible documentation. 00114 * 00115 * Revision 1.27 1998/09/23 06:20:18 robertj 00116 * Added open source copyright license. 00117 * 00118 * Revision 1.26 1998/02/03 06:29:10 robertj 00119 * Added new function to read a block with minimum number of bytes. 00120 * 00121 * Revision 1.25 1997/07/08 13:15:03 robertj 00122 * DLL support. 00123 * 00124 * Revision 1.24 1996/11/04 03:41:04 robertj 00125 * Added extra error message for UDP packet truncated. 00126 * 00127 * Revision 1.23 1996/09/14 13:09:17 robertj 00128 * Major upgrade: 00129 * rearranged sockets to help support IPX. 00130 * added indirect channel class and moved all protocols to descend from it, 00131 * separating the protocol from the low level byte transport. 00132 * 00133 * Revision 1.22 1996/08/17 10:00:19 robertj 00134 * Changes for Windows DLL support. 00135 * 00136 * Revision 1.21 1996/07/27 04:15:07 robertj 00137 * Created static version of ConvertOSError(). 00138 * Created static version of GetErrorText(). 00139 * 00140 * Revision 1.20 1996/05/26 03:24:40 robertj 00141 * Compatibility to GNU 2.7.x 00142 * 00143 * Revision 1.19 1996/04/15 12:33:03 robertj 00144 * Fixed SetReadTimeout/SetWriteTimeout to use const reference so works with GNU compiler. 00145 * 00146 * Revision 1.18 1996/04/14 02:53:30 robertj 00147 * Split serial and pipe channel into separate compilation units for Linux executable size reduction. 00148 * 00149 * Revision 1.17 1996/02/19 13:12:48 robertj 00150 * Added new error code for interrupted I/O. 00151 * 00152 * Revision 1.16 1996/01/23 13:09:14 robertj 00153 * Mac Metrowerks compiler support. 00154 * 00155 * Revision 1.15 1995/08/12 22:28:22 robertj 00156 * Work arounf for GNU bug: can't have private copy constructor with multiple inheritance. 00157 * 00158 * Revision 1.14 1995/07/31 12:15:42 robertj 00159 * Removed PContainer from PChannel ancestor. 00160 * 00161 * Revision 1.13 1995/06/17 11:12:21 robertj 00162 * Documentation update. 00163 * 00164 * Revision 1.12 1995/06/04 08:42:00 robertj 00165 * Fixed comment. 00166 * 00167 * Revision 1.11 1995/03/14 12:41:03 robertj 00168 * Updated documentation to use HTML codes. 00169 * 00170 * Revision 1.10 1995/03/12 04:36:53 robertj 00171 * Moved GetHandle() function from PFile to PChannel. 00172 * 00173 * Revision 1.9 1994/12/21 11:52:48 robertj 00174 * Documentation and variable normalisation. 00175 * 00176 * Revision 1.8 1994/11/28 12:31:40 robertj 00177 * Documentation. 00178 * 00179 * Revision 1.7 1994/08/23 11:32:52 robertj 00180 * Oops 00181 * 00182 * Revision 1.6 1994/08/22 00:46:48 robertj 00183 * Added pragma fro GNU C++ compiler. 00184 * 00185 * Revision 1.5 1994/08/21 23:43:02 robertj 00186 * Moved meta-string transmitter from PModem to PChannel. 00187 * Added common entry point to convert OS error to PChannel error. 00188 * 00189 * Revision 1.4 1994/07/17 10:46:06 robertj 00190 * Unix support changes. 00191 * 00192 * Revision 1.3 1994/07/02 03:03:49 robertj 00193 * Changed to allow for platform dependent part. 00194 * 00195 * Revision 1.2 1994/06/25 11:55:15 robertj 00196 * Unix version synchronisation. 00197 * 00198 * Revision 1.1 1994/04/20 12:17:44 robertj 00199 * Initial revision 00200 * 00201 */ 00202 00203 #ifndef _PCHANNEL 00204 #define _PCHANNEL 00205 00206 #ifdef P_USE_PRAGMA 00207 #pragma interface 00208 #endif 00209 00210 #include <ptlib/mutex.h> 00211 00213 // I/O Channels 00214 00215 class PChannel; 00216 00217 /* Buffer class used in PChannel stream. 00218 This class is necessary for implementing the standard C++ iostream interface 00219 on #PChannel# classes and its descendents. It is an internal class and 00220 should not ever be used by application writers. 00221 */ 00222 class PChannelStreamBuffer : public streambuf { 00223 00224 protected: 00225 /* Construct the streambuf for standard streams on a channel. This is used 00226 internally by the #PChannel# class. 00227 */ 00228 PChannelStreamBuffer( 00229 PChannel * chan // Channel the buffer operates on. 00230 ); 00231 00232 virtual int overflow(int=EOF); 00233 virtual int underflow(); 00234 virtual int sync(); 00235 #ifdef __USE_STL__ 00236 virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode = ios_base::in | ios_base::out); 00237 virtual pos_type seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out); 00238 #else 00239 virtual streampos seekoff(streamoff, ios::seek_dir, int); 00240 #endif 00241 00242 BOOL SetBufferSize( 00243 PINDEX newSize 00244 ); 00245 00246 private: 00247 // Member variables 00248 PChannel * channel; 00249 PCharArray input, output; 00250 00251 public: 00252 PChannelStreamBuffer(const PChannelStreamBuffer & sbuf); 00253 PChannelStreamBuffer & operator=(const PChannelStreamBuffer & sbuf); 00254 00255 friend class PChannel; 00256 }; 00257 00258 00280 class PChannel : public PObject, public iostream { 00281 PCLASSINFO(PChannel, PObject); 00282 00283 public: 00286 00287 PChannel(); 00288 00290 ~PChannel(); 00292 00304 virtual Comparison Compare( 00305 const PObject & obj 00306 ) const; 00307 00321 virtual PINDEX HashFunction() const; 00323 00333 virtual BOOL IsOpen() const; 00334 00340 virtual PString GetName() const; 00341 00347 int GetHandle() const; 00348 00358 virtual PChannel * GetBaseReadChannel() const; 00359 00369 virtual PChannel * GetBaseWriteChannel() const; 00371 00381 void SetReadTimeout( 00382 const PTimeInterval & time 00383 ); 00384 00391 PTimeInterval GetReadTimeout() const; 00392 00405 virtual BOOL Read( 00406 void * buf, 00407 PINDEX len 00408 ); 00409 00424 virtual PINDEX GetLastReadCount() const; 00425 00433 virtual int ReadChar(); 00434 00443 BOOL ReadBlock( 00444 void * buf, 00445 PINDEX len 00446 ); 00447 00455 PString ReadString(PINDEX len); 00456 00468 virtual BOOL ReadAsync( 00469 void * buf, 00470 PINDEX len 00471 ); 00472 00477 virtual void OnReadComplete( 00478 void * buf, 00479 PINDEX len 00480 ); 00482 00492 void SetWriteTimeout( 00493 const PTimeInterval & time 00494 ); 00495 00503 PTimeInterval GetWriteTimeout() const; 00504 00516 virtual BOOL Write( 00517 const void * buf, 00518 PINDEX len 00519 ); 00520 00533 virtual PINDEX GetLastWriteCount() const; 00534 00543 BOOL WriteChar(int c); 00544 00551 BOOL WriteString(const PString & str); 00552 00562 virtual BOOL WriteAsync( 00563 const void * buf, 00564 PINDEX len 00565 ); 00566 00572 virtual void OnWriteComplete( 00573 const void * buf, 00574 PINDEX len 00575 ); 00577 00584 virtual BOOL Close(); 00585 00586 enum ShutdownValue { 00587 ShutdownRead = 0, 00588 ShutdownWrite = 1, 00589 ShutdownReadAndWrite = 2 00590 }; 00591 00599 virtual BOOL Shutdown( 00600 ShutdownValue option 00601 ); 00602 00608 BOOL SetBufferSize( 00609 PINDEX newSize 00610 ); 00611 00651 BOOL SendCommandString( 00652 const PString & command 00653 ); 00654 00659 void AbortCommandString(); 00661 00667 enum Errors { 00668 NoError, 00670 NotFound, 00672 FileExists, 00674 DiskFull, 00676 AccessDenied, 00678 DeviceInUse, 00680 BadParameter, 00682 NoMemory, 00684 NotOpen, 00686 Timeout, 00688 Interrupted, 00690 BufferTooSmall, 00692 Miscellaneous, 00694 ProtocolFailure, 00695 NumNormalisedErrors 00696 }; 00697 00703 enum ErrorGroup { 00704 LastReadError, 00705 LastWriteError, 00706 LastGeneralError, 00707 NumErrorGroups 00708 }; 00709 00714 Errors GetErrorCode( 00715 ErrorGroup group = NumErrorGroups 00716 ) const; 00717 00723 int GetErrorNumber( 00724 ErrorGroup group = NumErrorGroups 00725 ) const; 00726 00732 virtual PString GetErrorText( 00733 ErrorGroup group = NumErrorGroups 00734 ) const; 00735 00742 static PString GetErrorText( 00743 Errors lastError, 00744 int osError = 0 00745 ); 00747 00754 static BOOL ConvertOSError( 00755 int libcReturnValue, 00756 Errors & lastError, 00757 int & osError 00758 ); 00759 00764 #if P_HAS_RECVMSG 00765 typedef iovec Slice; 00766 #else 00767 struct Slice { 00768 void * iov_base; 00769 size_t iov_len; 00770 }; 00771 #endif 00772 00773 typedef std::vector<Slice> VectorOfSlice; 00774 00784 virtual BOOL Read( 00785 const VectorOfSlice & slices // slices to read to 00786 ); 00787 00797 virtual BOOL Write( 00798 const VectorOfSlice & slices // slices to read to 00799 ); 00801 00802 protected: 00803 PChannel(const PChannel &); 00804 PChannel & operator=(const PChannel &); 00805 // Prevent usage by external classes 00806 00807 00814 virtual BOOL ConvertOSError( 00815 int libcReturnValue, 00816 ErrorGroup group = LastGeneralError 00817 ); 00818 00819 public: 00823 BOOL SetErrorValues( 00824 Errors errorCode, 00825 int osError, 00826 ErrorGroup group = LastGeneralError 00827 ); 00828 00829 protected: 00838 int ReadCharWithTimeout( 00839 PTimeInterval & timeout // Timeout for read. 00840 ); 00841 00842 // Receive a (partial) command string, determine if completed yet. 00843 BOOL ReceiveCommandString( 00844 int nextChar, 00845 const PString & reply, 00846 PINDEX & pos, 00847 PINDEX start 00848 ); 00849 00850 00851 // Member variables 00853 int os_handle; 00855 Errors lastErrorCode[NumErrorGroups+1]; 00857 int lastErrorNumber[NumErrorGroups+1]; 00859 PINDEX lastReadCount; 00861 PINDEX lastWriteCount; 00863 PTimeInterval readTimeout; 00865 PTimeInterval writeTimeout; 00866 00867 00868 private: 00869 // New functions for class 00870 void Construct(); 00871 // Complete platform dependent construction. 00872 00873 // Member variables 00874 BOOL abortCommandString; 00875 // Flag to abort the transmission of a command in SendCommandString(). 00876 00877 00878 // Include platform dependent part of class 00879 #ifdef _WIN32 00880 #include "msos/ptlib/channel.h" 00881 #else 00882 #include "unix/ptlib/channel.h" 00883 #endif 00884 00885 }; 00886 00887 #endif 00888 00889 // End Of File ///////////////////////////////////////////////////////////////