channel.h
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:24k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * channel.h
  3.  *
  4.  * I/O channel ancestor class.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: channel.h,v $
  30.  * Revision 1.30  1999/11/05 09:37:46  craigs
  31.  * Made static form of ConvertOSError public scope
  32.  *
  33.  * Revision 1.29  1999/10/09 01:22:06  robertj
  34.  * Fixed error display for sound channels.
  35.  *
  36.  * Revision 1.28  1999/03/09 02:59:49  robertj
  37.  * Changed comments to doc++ compatible documentation.
  38.  *
  39.  * Revision 1.27  1998/09/23 06:20:18  robertj
  40.  * Added open source copyright license.
  41.  *
  42.  * Revision 1.26  1998/02/03 06:29:10  robertj
  43.  * Added new function to read a block with minimum number of bytes.
  44.  *
  45.  * Revision 1.25  1997/07/08 13:15:03  robertj
  46.  * DLL support.
  47.  *
  48.  * Revision 1.24  1996/11/04 03:41:04  robertj
  49.  * Added extra error message for UDP packet truncated.
  50.  *
  51.  * Revision 1.23  1996/09/14 13:09:17  robertj
  52.  * Major upgrade:
  53.  *   rearranged sockets to help support IPX.
  54.  *   added indirect channel class and moved all protocols to descend from it,
  55.  *   separating the protocol from the low level byte transport.
  56.  *
  57.  * Revision 1.22  1996/08/17 10:00:19  robertj
  58.  * Changes for Windows DLL support.
  59.  *
  60.  * Revision 1.21  1996/07/27 04:15:07  robertj
  61.  * Created static version of ConvertOSError().
  62.  * Created static version of GetErrorText().
  63.  *
  64.  * Revision 1.20  1996/05/26 03:24:40  robertj
  65.  * Compatibility to GNU 2.7.x
  66.  *
  67.  * Revision 1.19  1996/04/15 12:33:03  robertj
  68.  * Fixed SetReadTimeout/SetWriteTimeout to use const reference so works with GNU compiler.
  69.  *
  70.  * Revision 1.18  1996/04/14 02:53:30  robertj
  71.  * Split serial and pipe channel into separate compilation units for Linux executable size reduction.
  72.  *
  73.  * Revision 1.17  1996/02/19 13:12:48  robertj
  74.  * Added new error code for interrupted I/O.
  75.  *
  76.  * Revision 1.16  1996/01/23 13:09:14  robertj
  77.  * Mac Metrowerks compiler support.
  78.  *
  79.  * Revision 1.15  1995/08/12 22:28:22  robertj
  80.  * Work arounf for  GNU bug: can't have private copy constructor with multiple inheritance.
  81.  *
  82.  * Revision 1.14  1995/07/31 12:15:42  robertj
  83.  * Removed PContainer from PChannel ancestor.
  84.  *
  85.  * Revision 1.13  1995/06/17 11:12:21  robertj
  86.  * Documentation update.
  87.  *
  88.  * Revision 1.12  1995/06/04 08:42:00  robertj
  89.  * Fixed comment.
  90.  *
  91.  * Revision 1.11  1995/03/14 12:41:03  robertj
  92.  * Updated documentation to use HTML codes.
  93.  *
  94.  * Revision 1.10  1995/03/12  04:36:53  robertj
  95.  * Moved GetHandle() function from PFile to PChannel.
  96.  *
  97.  * Revision 1.9  1994/12/21  11:52:48  robertj
  98.  * Documentation and variable normalisation.
  99.  *
  100.  * Revision 1.8  1994/11/28  12:31:40  robertj
  101.  * Documentation.
  102.  *
  103.  * Revision 1.7  1994/08/23  11:32:52  robertj
  104.  * Oops
  105.  *
  106.  * Revision 1.6  1994/08/22  00:46:48  robertj
  107.  * Added pragma fro GNU C++ compiler.
  108.  *
  109.  * Revision 1.5  1994/08/21  23:43:02  robertj
  110.  * Moved meta-string transmitter from PModem to PChannel.
  111.  * Added common entry point to convert OS error to PChannel error.
  112.  *
  113.  * Revision 1.4  1994/07/17  10:46:06  robertj
  114.  * Unix support changes.
  115.  *
  116.  * Revision 1.3  1994/07/02  03:03:49  robertj
  117.  * Changed to allow for platform dependent part.
  118.  *
  119.  * Revision 1.2  1994/06/25  11:55:15  robertj
  120.  * Unix version synchronisation.
  121.  *
  122.  * Revision 1.1  1994/04/20  12:17:44  robertj
  123.  * Initial revision
  124.  *
  125.  */
  126. #define _PCHANNEL
  127. #ifdef __GNUC__
  128. #pragma interface
  129. #endif
  130. ///////////////////////////////////////////////////////////////////////////////
  131. // I/O Channels
  132. class PChannel;
  133. /* Buffer class used in PChannel stream.
  134. This class is necessary for implementing the standard C++ iostream interface
  135. on #PChannel# classes and its descendents. It is an internal class and
  136. should not ever be used by application writers.
  137. */
  138. class PChannelStreamBuffer : public streambuf {
  139.   protected:
  140.     /* Construct the streambuf for standard streams on a channel. This is used
  141.        internally by the #PChannel# class.
  142.      */
  143.     PChannelStreamBuffer(
  144.       PChannel * chan   // Channel the buffer operates on.
  145.     );
  146.     virtual int overflow(int=EOF);
  147.     virtual int underflow();
  148.     virtual int sync();
  149. #ifdef __MWERKS__
  150.     virtual streampos seekoff(streamoff, ios::seekdir, ios::openmode);
  151. #else
  152.     virtual streampos seekoff(streamoff, ios::seek_dir, int);
  153. #endif
  154.   private:
  155.     // Member variables
  156.     PChannel * channel;
  157.     char buffer[1024];
  158.   public:
  159.     PChannelStreamBuffer(const PChannelStreamBuffer & sbuf);
  160.     PChannelStreamBuffer & operator=(const PChannelStreamBuffer & sbuf);
  161.   friend class PChannel;
  162. };
  163. /** Abstract class defining I/O channel semantics. An I/O channel can be a
  164.    serial port, pipe, network socket or even just a simple file. Anything that
  165.    requires opening and closing then reading and/or writing from.
  166.    A descendent would typically have constructors and an #Open()# function which
  167.    enables access to the I/O channel it represents. The #Read()# and
  168.    #Write()# functions would then be overridden to the platform and I/O
  169.    specific mechanisms required.
  170.    The general model for a channel is that the channel accepts and/or supplies
  171.    a stream of bytes. The access to the stream of bytes is via a set of
  172.    functions that allow certain types of transfer. These include direct
  173.    transfers, buffered transfers (via iostream) or asynchronous transfers.
  174.    The model also has the fundamental state of the channel being {it open}
  175.    or {it closed}. A channel instance that is closed contains sufficient
  176.    information to describe the channel but does not allocate or lock any
  177.    system resources. An open channel allocates or locks the particular system
  178.    resource. The act of opening a channel is a key event that may fail. In this
  179.    case the channel remains closed and error values are set.
  180.  */
  181. class PChannel : public PObject, public iostream {
  182.   PCLASSINFO(PChannel, PObject);
  183.   public:
  184.   /**@name Construction */
  185.   //@{
  186.       /// Create the channel.
  187.     PChannel();
  188.       /// Close down the channel.
  189.     ~PChannel();
  190.   //@}
  191.   /**@name Information functions */
  192.   //@{
  193.     /** Determine if the channel is currently open.
  194.        This indicates that read and write operations can be executed on the
  195.        channel. For example, in the #PFile# class it returns if the file is
  196.        currently open.
  197.        @return TRUE if the channel is open.
  198.      */
  199.     virtual BOOL IsOpen() const;
  200.     /** Get the platform and I/O channel type name of the channel. For example,
  201.        it would return the filename in #PFile# type channels.
  202.        @return the name of the channel.
  203.      */
  204.     virtual PString GetName() const;
  205.     /** Get the integer operating system handle for the channel.
  206.        @return
  207.        standard OS descriptor integer.
  208.      */
  209.     int GetHandle() const;
  210.     /** Get the base channel of channel indirection using PIndirectChannel.
  211.        This function returns the eventual base channel for reading of a series
  212.        of indirect channels provided by descendents of #PIndirectChannel#.
  213.        The behaviour for this function is to return "this".
  214.        
  215.        @return
  216.        Pointer to base I/O channel for the indirect channel.
  217.      */
  218.     virtual PChannel * GetBaseReadChannel() const;
  219.     /** Get the base channel of channel indirection using PIndirectChannel.
  220.        This function returns the eventual base channel for writing of a series
  221.        of indirect channels provided by descendents of #PIndirectChannel#.
  222.        The behaviour for this function is to return "this".
  223.        
  224.        @return
  225.        Pointer to base I/O channel for the indirect channel.
  226.      */
  227.     virtual PChannel * GetBaseWriteChannel() const;
  228.   //@}
  229.   /**@name Reading functions */
  230.   //@{
  231.     /** Set the timeout for read operations. This may be zero for immediate
  232.        return of data through to #PMaxMilliseconds# which will wait forever for
  233.        the read request to be filled.
  234.        
  235.        Note that this function may not be available, or meaningfull, for all
  236.        channels. In that case it is set but ignored.
  237.      */
  238.     void SetReadTimeout(
  239.       const PTimeInterval & time  /// The new time interval for read operations.
  240.     );
  241.     /** Get the timeout for read operations. Note that this function may not be
  242.        available, or meaningfull, for all channels. In that case it returns the
  243.        previously set value.
  244.        @return time interval for read operations.
  245.      */
  246.     PTimeInterval GetReadTimeout() const;
  247.     /** Low level read from the channel. This function may block until the
  248.        requested number of characters were read or the read timeout was
  249.        reached. The GetLastReadCount() function returns the actual number
  250.        of bytes read.
  251.        The GetErrorCode() function should be consulted after Read() returns
  252.        FALSE to determine what caused the failure.
  253.        @return
  254.        TRUE indicates that at least one character was read from the channel.
  255.        FALSE means no bytes were read due to timeout or some other I/O error.
  256.      */
  257.     virtual BOOL Read(
  258.       void * buf,   /// Pointer to a block of memory to receive the read bytes.
  259.       PINDEX len    /// Maximum number of bytes to read into the buffer.
  260.     );
  261.     /**Get the number of bytes read by the last Read() call. This will be from
  262.        0 to the maximum number of bytes as passed to the Read() call.
  263.        
  264.        Note that the number of bytes read may often be less than that asked
  265.        for. Aside from the most common case of being at end of file, which the
  266.        applications semantics may regard as an exception, there are some cases
  267.        where this is normal. For example, if a PTextFile channel on the
  268.        MSDOS platform is read from, then the translation of CR/LF pairs to n
  269.        characters will result in the number of bytes returned being less than
  270.        the size of the buffer supplied.
  271.        @return
  272.        the number of bytes read.
  273.      */
  274.     PINDEX GetLastReadCount() const;
  275.     /** Read a single 8 bit byte from the channel. If one was not available
  276.        within the read timeout period, or an I/O error occurred, then the
  277.        function gives with a -1 return value.
  278.        @return
  279.        byte read or -1 if no character could be read.
  280.      */
  281.     virtual int ReadChar();
  282.     /** Read len bytes into the buffer from the channel. This function uses
  283.        Read(), so most remarks pertaining to that function also apply to this
  284.        one. The only difference being that this function will not return until
  285.        all of the bytes have been read, or an error occurs.
  286.        @return
  287.        TRUE if the read of #len# bytes was sucessfull.
  288.      */
  289.     BOOL ReadBlock(
  290.       void * buf,   /// Pointer to a block of memory to receive the read bytes.
  291.       PINDEX len    /// Maximum number of bytes to read into the buffer.
  292.     );
  293.     /** Read #len# character into a string from the channel. This
  294.        function simply uses ReadBlock(), so all remarks pertaining to that
  295.        function also apply to this one.
  296.        @return
  297.        String that was read.
  298.      */
  299.     PString ReadString(PINDEX len);
  300.     /** Begin an asynchronous read from channel. The read timeout is used as in
  301.        other read operations, in this case calling the OnReadComplete()
  302.        function.
  303.        Note that if the channel is not capable of asynchronous read then this
  304.        will do a sychronous read is in the Read() function with the addition
  305.        of calling the OnReadComplete() before returning.
  306.        @return
  307.        TRUE if the read was sucessfully queued.
  308.      */
  309.     virtual BOOL ReadAsync(
  310.       void * buf,   /// Pointer to a block of memory to receive the read bytes.
  311.       PINDEX len    /// Maximum number of bytes to read into the buffer.
  312.     );
  313.     /** User callback function for when a #ReadAsync()# call has completed or
  314.        timed out. The original pointer to the buffer passed in ReadAsync() is
  315.        passed to the function.
  316.      */
  317.     virtual void OnReadComplete(
  318.       void * buf, /// Pointer to a block of memory that received the read bytes.
  319.       PINDEX len  /// Actual number of bytes to read into the buffer.
  320.     );
  321.   //@}
  322.   /**@name Writing functions */
  323.   //@{
  324.     /** Set the timeout for write operations to complete. This may be zero for
  325.        immediate return through to PMaxMilliseconds which will wait forever for
  326.        the write request to be completed.
  327.        
  328.        Note that this function may not be available, or meaningfull,  for all
  329.        channels. In this case the parameter is et but ignored.
  330.      */
  331.     void SetWriteTimeout(
  332.       const PTimeInterval & time /// The new time interval for write operations.
  333.     );
  334.     /** Get the timeout for write operations to complete. Note that this
  335.        function may not be available, or meaningfull, for all channels. In
  336.        that case it returns the previously set value.
  337.        @return
  338.        time interval for writing.
  339.      */
  340.     PTimeInterval GetWriteTimeout() const;
  341.     /** Low level write to the channel. This function will block until the
  342.        requested number of characters are written or the write timeout is
  343.        reached. The GetLastWriteCount() function returns the actual number
  344.        of bytes written.
  345.        The GetErrorCode() function should be consulted after Write() returns
  346.        FALSE to determine what caused the failure.
  347.        @return
  348.        TRUE if at least len bytes were written to the channel.
  349.      */
  350.     virtual BOOL Write(
  351.       const void * buf, /// Pointer to a block of memory to write.
  352.       PINDEX len        /// Number of bytes to write.
  353.     );
  354.     /** Get the number of bytes written by the last Write() call.
  355.        
  356.        Note that the number of bytes written may often be less, or even more,
  357.        than that asked for. A common case of it being less is where the disk
  358.        is full. An example of where the bytes written is more is as follows.
  359.        On a #PTextFile# channel on the MSDOS platform, there is
  360.        translation of n to CR/LF pairs. This will result in the number of
  361.        bytes returned being more than that requested.
  362.        @return
  363.        the number of bytes written.
  364.      */
  365.     PINDEX GetLastWriteCount() const;
  366.     /** Write a single character to the channel. This function simply uses the
  367.        Write() function so all comments on that function also apply.
  368.        
  369.        Note that this asserts if the value is not in the range 0..255.
  370.        @return
  371.        TRUE if the byte was successfully written.
  372.      */
  373.     BOOL WriteChar(int c);
  374.     /** Write a string to the channel. This function simply uses the Write()
  375.        function so all comments on that function also apply.
  376.        @return
  377.        TRUE if the character written.
  378.      */
  379.     BOOL WriteString(const PString & str);
  380.     /** Begin an asynchronous write from channel. The write timeout is used as
  381.        in other write operations, in this case calling the OnWriteComplete()
  382.        function. Note that if the channel is not capable of asynchronous write
  383.        then this will do a sychronous write as in the Write() function with
  384.        the addition of calling the OnWriteComplete() before returning.
  385.        @return
  386.        TRUE of the write operation was succesfully queued.
  387.      */
  388.     virtual BOOL WriteAsync(
  389.       const void * buf, /// Pointer to a block of memory to write.
  390.       PINDEX len        /// Number of bytes to write.
  391.     );
  392.     /** User callback function for when a WriteAsync() call has completed or
  393.        timed out. The original pointer to the buffer passed in WriteAsync() is
  394.        passed in here and the len parameter is the actual number of characters
  395.        written.
  396.      */
  397.     virtual void OnWriteComplete(
  398.       const void * buf, /// Pointer to a block of memory to write.
  399.       PINDEX len        /// Number of bytes to write.
  400.     );
  401.   //@}
  402.   /**@name Miscellaneous functions */
  403.   //@{
  404.     /** Close the channel, shutting down the link to the data source.
  405.        @return TRUE if the channel successfully closed.
  406.      */
  407.     virtual BOOL Close();
  408.     enum ShutdownValue {
  409.       ShutdownRead         = 0,
  410.       ShutdownWrite        = 1,
  411.       ShutdownReadAndWrite = 2
  412.     };
  413.     /** Close one or both of the data streams associated with a channel.
  414.        The default behavour is to do nothing and return FALSE.
  415.        @return
  416.        TRUE if the shutdown was successfully performed.
  417.      */
  418.     virtual BOOL Shutdown(
  419.       ShutdownValue option
  420.     );
  421.     /** Send a command meta-string. A meta-string is a string of characters
  422.        that may contain escaped commands. The escape command is the  as in
  423.        the C language.
  424.        The escape commands are:
  425. begin{description}
  426.           item[#a#]    alert (ascii value 7)
  427.           item[#b#]    backspace (ascii value 8)
  428.           item[#f#]    formfeed (ascii value 12)
  429.           item[#n#]    newline (ascii value 10)
  430.           item[#r#]    return (ascii value 13)
  431.           item[#t#]    horizontal tab (ascii value 9)
  432.           item[#v#]    vertical tab (ascii value 11)
  433.           item[#\#]    backslash
  434.           item[#ooo#]  where ooo is octal number, ascii value ooo
  435.           item[#xhh#]  where hh is hex number (ascii value 0xhh)
  436.           item[##]    null character (ascii zero)
  437.           item[#dns#]  delay for n seconds
  438.           item[#dnm#]  delay for n milliseconds
  439.           item[#s#]    characters following this, up to a w
  440.                                      command or the end of string, are to be
  441.                                      sent to modem
  442.           item[#wns#]  characters following this, up to a s, d
  443.                                      or another w or the end of the string are
  444.                                      expected back from the modem. If the
  445.                                      string is not received within n seconds,
  446.                                      a failed command is registered. The
  447.                                      exception to this is if the command is at
  448.                                      the end of the string or the next
  449.                                      character in the string is the s, d or
  450.                                      w in which case all characters are
  451.                                      ignored from the modem until n seconds of
  452.                                      no data.
  453.           item[#wnm#]  as for above but timeout is in
  454.                                      milliseconds.
  455. end{description}
  456.        @return
  457.        TRUE if the command string was completely processed.
  458.      */
  459.     BOOL SendCommandString(
  460.       const PString & command  /// Command to send to the channel
  461.     );
  462.     /** Abort a command string that is in progress. Note that as the
  463.        SendCommandString() function blocks the calling thread when it runs,
  464.        this can only be called from within another thread.
  465.      */
  466.     void AbortCommandString();
  467.   //@}
  468.   /**@name Error functions */
  469.   //@{
  470.     /** Normalised error codes.
  471.         The error result of the last file I/O operation in this object.
  472.      */
  473.     enum Errors {
  474.       NoError,
  475.       /// Open fail due to device or file not found
  476.       NotFound,       
  477.       /// Open fail due to file already existing
  478.       FileExists,     
  479.       /// Write fail due to disk full
  480.       DiskFull,       
  481.       /// Operation fail due to insufficient privilege
  482.       AccessDenied,   
  483.       /// Open fail due to device already open for exclusive use
  484.       DeviceInUse,    
  485.       /// Operation fail due to bad parameters
  486.       BadParameter,   
  487.       /// Operation fail due to insufficient memory
  488.       NoMemory,       
  489.       /// Operation fail due to channel not being open yet
  490.       NotOpen,        
  491.       /// Operation failed due to a timeout
  492.       Timeout,        
  493.       /// Operation was interrupted
  494.       Interrupted,    
  495.       /// Operations buffer was too small for data.
  496.       BufferTooSmall, 
  497.       /// Miscellaneous error.
  498.       Miscellaneous
  499.     };
  500.     /** Get normalised error code.
  501.       Return the error result of the last file I/O operation in this object.
  502.       @return Normalised error code.
  503.       */
  504.     Errors GetErrorCode() const;
  505.     /** Get OS errro code.
  506.       Return the operating system error number of the last file I/O
  507.       operation in this object.
  508.       @return Operating System error code.
  509.       */
  510.     int GetErrorNumber() const;
  511.       /** Get error message description.
  512.         Return a string indicating the error message that may be displayed to
  513.        the user. The error for the last I/O operation in this object is used.
  514.       @return Operating System error description string.
  515.        */
  516.     virtual PString GetErrorText() const;
  517.       /** Get error message description.
  518.         Return a string indicating the error message that may be displayed to
  519.        the user. The #osError# parameter is used unless zero, in which case
  520.        the #lastError# parameter is used.
  521.       @return Operating System error description string.
  522.        */
  523.     static PString GetErrorText(
  524.       Errors lastError,   /// Error code to translate.
  525.       int osError = 0     /// OS error number to translate.
  526.     );
  527.   //@}
  528.     /** Convert an operating system error into platform independent error.
  529.        This will set the lastError and osError member variables for access by
  530.        GetErrorCode() and GetErrorNumber().
  531.        
  532.        @return TRUE if there was no error.
  533.      */
  534.     static BOOL ConvertOSError(int error, Errors & lastError, int & osError);
  535.   protected:
  536.     PChannel(const PChannel &);
  537.     PChannel & operator=(const PChannel &);
  538.     // Prevent usage by external classes
  539.     /** Convert an operating system error into platform independent error.
  540.       The internal error codes are set by this function. They may be obtained
  541.       via the #GetErrorCode()# and #GetErrorNumber()# functions.
  542.        
  543.        @return TRUE if there was no error.
  544.      */
  545.     virtual BOOL ConvertOSError(int error);
  546.     /** Read a character with specified timeout.
  547.       This reads a single character from the channel waiting at most the
  548.       amount of time specified for it to arrive. The #timeout# parameter
  549.       is adjusted for amount of time it actually took, so it can be used
  550.       for a multiple character timeout.
  551.        @return TRUE if there was no error.
  552.      */
  553.     int ReadCharWithTimeout(
  554.       PTimeInterval & timeout  // Timeout for read.
  555.     );
  556.     // Receive a (partial) command string, determine if completed yet.
  557.     BOOL ReceiveCommandString(
  558.       int nextChar,
  559.       const PString & reply,
  560.       PINDEX & pos,
  561.       PINDEX start
  562.     );
  563.     // Member variables
  564.     /// The operating system file handle return by standard open() function.
  565.     int os_handle;
  566.     /// The platform independant error code.
  567.     Errors lastError;
  568.     /// The operating system error number (eg as returned by errno).
  569.     int osError;
  570.     /// Number of byte last read by the Read() function.
  571.     PINDEX lastReadCount;
  572.     /// Number of byte last written by the Write() function.
  573.     PINDEX lastWriteCount;
  574.     /// Timeout for read operations.
  575.     PTimeInterval readTimeout;
  576.     /// Timeout for write operations.
  577.     PTimeInterval writeTimeout;
  578.   private:
  579.     // New functions for class
  580.     void Construct();
  581.       // Complete platform dependent construction.
  582.     // Member variables
  583.     BOOL abortCommandString;
  584.       // Flag to abort the transmission of a command in SendCommandString().
  585. #ifdef DOC_PLUS_PLUS
  586. };
  587. #endif
  588. // Class declaration continued in platform specific header file ///////////////