Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

IOStream.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    IOStream.h
00006  *
00007  *  $Id: IOStream.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00008  *
00009  *  @author James CE Johnson <jcej@lads.com>
00010  *  @author Jim Crossley <jim@lads.com>
00011  */
00012 //=============================================================================
00013 
00014 #ifndef ACE_IOSTREAM_H
00015 #define ACE_IOSTREAM_H
00016 #include "ace/pre.h"
00017 
00018 #include "ace/config-all.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 // This is a temporary restriction - ACE_IOStream is only enabled if the
00025 // compiler does not supply the standard C++ library (and standard iostreams)
00026 // or, if it does, the platform is explicitly set to use old iostreams
00027 // by its config.h file.
00028 // This restriction is recorded in Bugzilla entry 857.
00029 #if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && (ACE_HAS_STANDARD_CPP_LIBRARY == 1)
00030 #  if !defined (ACE_USES_OLD_IOSTREAMS) && !defined (ACE_LACKS_ACE_IOSTREAM)
00031 #    define ACE_LACKS_ACE_IOSTREAM
00032 #  endif /* !ACE_USES_OLD_IOSTREAMS && !ACE_LACKS_ACE_IOSTREAM */
00033 #endif /* ACE_HAS_STANDARD_CPP_LIBRARY */
00034 
00035 #if !defined (ACE_LACKS_ACE_IOSTREAM)
00036 
00037 #include "ace/OS.h"
00038 #include "ace/streams.h"
00039 
00040 #if defined (ACE_HAS_STRING_CLASS)
00041 #if defined (ACE_WIN32) && defined (_MSC_VER)
00042 typedef CString ACE_IOStream_String;
00043 #else
00044 #if !defined (ACE_HAS_STDCPP_STL_INCLUDES)
00045 #include /**/ <String.h>
00046 typedef String ACE_IOStream_String;
00047 #else
00048 #include /**/ <string>
00049 
00050 #if defined(ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB)
00051 typedef std::string ACE_IOStream_String;
00052 #else
00053 typedef string ACE_IOStream_String;
00054 #endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */
00055 #endif /* ! ACE_HAS_STDCPP_STL_INCLUDES */
00056 #endif /* ACE_WIN32 && defined (_MSC_VER) */
00057 
00058 #if defined (__DECCXX_VER)
00059 # if __DECCXX_VER < 50700000
00060 #   include /**/ <stl_macros>
00061 # else
00062 #   include /**/ <stdcomp>
00063 # endif /* __DECCXX_VER < 50700000 */
00064 #endif /* __DECCXX_VER */
00065 
00066 class ACE_Export ACE_Quoted_String : public ACE_IOStream_String
00067 {
00068 public:
00069   inline ACE_Quoted_String (void) { *this = ""; }
00070   inline ACE_Quoted_String (const char *c) { *this = ACE_IOStream_String (c); }
00071   inline ACE_Quoted_String (const ACE_IOStream_String &s) { *this = s; }
00072   inline ACE_Quoted_String &operator= (const ACE_IOStream_String& s)
00073   {
00074     return (ACE_Quoted_String &) ACE_IOStream_String::operator= (s);
00075   }
00076   inline ACE_Quoted_String &operator = (const char c) {
00077     return (ACE_Quoted_String &) ACE_IOStream_String::operator= (c);
00078   }
00079   inline ACE_Quoted_String &operator = (const char *c) {
00080     return (ACE_Quoted_String &) ACE_IOStream_String::operator= (c);
00081   }
00082   inline int operator < (const ACE_Quoted_String &s) const {
00083     return *(ACE_IOStream_String *) this < (ACE_IOStream_String) s;
00084   }
00085 #if defined (ACE_WIN32) && defined (_MSC_VER)
00086   inline int length (void) { return this->GetLength (); }
00087 #endif /* ACE_WIN32 && defined (_MSC_VER) */
00088 };
00089 
00090 #endif /* ACE_HAS_STRING_CLASS */
00091 
00092 /**
00093  * @class ACE_Streambuf
00094  *
00095  * @brief Create your custom streambuf by providing and ACE_*_Stream
00096  * object to this template.  I have tested it with
00097  * ACE_SOCK_Stream and it should work fine for others as well.
00098  *
00099  * For any iostream object, the real work is done by the
00100  * underlying streambuf class.  That is what we create here.
00101  * A streambuf has an internal buffer area into which data is
00102  * read and written as the iostream requests and provides data.
00103  * At some point during the read process, the iostream will
00104  * realize that the streambuf has no more data.  The underflow
00105  * function of the streambuf is then called.
00106  * Likewise, during the write process, the iostream will
00107  * eventually notice that the streabuf's buffer has become full
00108  * and will invoke the overflow function.
00109  * The empty/full state of the read/write "buffers" are
00110  * controled by two sets pointers.  One set is dedicated to
00111  * read, the other to write.  These pointers, in turn, reference
00112  * a common buffer that is to be shared by both read and write
00113  * operations.  It is this common buffer to which data is
00114  * written and from which it is read.
00115  * The common buffer is used by functions of the streambuf as
00116  * well as the iostream.  Because of this and the fact that it
00117  * is "shared" by both read and write operators, there is a
00118  * danger of data corruption if read and write operations are
00119  * allowed to take place "at the same time".
00120  * To prevent data corruption, we manipulate the read and write
00121  * pointer sets so that the streambuf is in either a read-mode
00122  * or write-mode at all times and can never be in both modes at
00123  * the same time.
00124  * In the constructor: set the read and write sets to NULL This
00125  * causes the underflow or overflow operators to be invoked at
00126  * the first IO activity of the iostream.
00127  * In the underflow function we arrange for the common buffer to
00128  * reference our read buffer and for the write pointer set to be
00129  * disabled.  If a write operation is performed by the iostream
00130  * this will cause the overflow function to be invoked.
00131  * In the overflow function we arrange for the common buffer to
00132  * reference our write buffer and for the read pointer set to be
00133  * disabled.  This causes the underflow function to be invoked
00134  * when the iostream "changes our mode".
00135  * The overflow function will also invoke the send_n function to
00136  * flush the buffered data to our peer.  Similarly, the sync and
00137  * syncout functions will cause send_n to be invoked to send the
00138  * data.
00139  * Since socket's and the like do not support seeking, there can
00140  * be no method for "syncing" the input.  However, since we
00141  * maintain separate read/write buffers, no data is lost by
00142  * "syncing" the input.  It simply remains buffered.
00143  */
00144 class ACE_Export ACE_Streambuf : public streambuf
00145 {
00146 public:
00147 
00148   /**
00149    * If the default allocation strategey were used the common buffer
00150    * would be deleted when the object destructs.  Since we are
00151    * providing separate read/write buffers, it is up to us to manage
00152    * their memory.
00153    */
00154   virtual ~ACE_Streambuf (void);
00155 
00156   /// Get the current Time_Value pointer and provide a new one.
00157   ACE_Time_Value *recv_timeout (ACE_Time_Value *tv = NULL);
00158 
00159   /**
00160    * Use this to allocate a new/different buffer for put operations.
00161    * If you do not provide a buffer pointer, one will be allocated.
00162    * That is the preferred method.  If you do provide a buffer, the
00163    * size must match that being used by the get buffer.  If
00164    * successful, you will receive a pointer to the current put buffer.
00165    * It is your responsibility to delete this memory when you are done
00166    * with it.
00167    */
00168   char *reset_put_buffer (char *newBuffer = NULL,
00169                           u_int _streambuf_size = 0,
00170                           u_int _pptr = 0 );
00171 
00172   /// Return the number of bytes to be 'put' onto the stream media.
00173   ///    pbase + put_avail = pptr
00174   u_int put_avail (void);
00175 
00176   /**
00177    * Use this to allocate a new/different buffer for get operations.
00178    * If you do not provide a buffer pointer, one will be allocated.
00179    * That is the preferred method.  If you do provide a buffer, the
00180    * size must match that being used by the put buffer.  If
00181    * successful, you will receive a pointer to the current get buffer.
00182    * It is your responsibility to delete this memory when you are done
00183    * with it.
00184    */
00185   char *reset_get_buffer (char *newBuffer = NULL,
00186                           u_int _streambuf_size = 0,
00187                           u_int _gptr = 0,
00188                           u_int _egptr = 0);
00189 
00190   /// Return the number of bytes not yet gotten.  eback + get_waiting =
00191   /// gptr
00192   u_int get_waiting (void);
00193 
00194   /// Return the number of bytes in the get area (includes some already
00195   /// gotten); eback + get_avail = egptr
00196   u_int get_avail (void);
00197 
00198   /// Query the streambuf for the size of its buffers.
00199   u_int streambuf_size (void);
00200 
00201   /// Did we take an error because of an IO operation timeout?  Note:
00202   /// Invoking this resets the flag.
00203   u_char timeout (void);
00204 
00205 protected:
00206   ACE_Streambuf (u_int streambuf_size,
00207                  int io_mode);
00208 
00209   /// Sync both input and output. See syncin/syncout below for
00210   /// descriptions.
00211   virtual int sync (void);
00212 
00213   // = Signatures for the underflow/overflow discussed above.
00214   virtual int underflow (void);
00215 
00216   /// The overflow function receives the character which caused the
00217   /// overflow.
00218   virtual int overflow (int = EOF);
00219 
00220   /// Resets the <base> pointer and streambuf mode.  This is used
00221   /// internally when get/put buffers are allocatd.
00222   void reset_base (void);
00223 
00224 protected:
00225   // = Two pointer sets for manipulating the read/write areas.
00226   char *eback_saved_;
00227   char *gptr_saved_;
00228   char *egptr_saved_;
00229   char *pbase_saved_;
00230   char *pptr_saved_;
00231   char *epptr_saved_;
00232 
00233   // = With cur_mode_ we keep track of our current IO mode.
00234 
00235   // This helps us to optimize the underflow/overflow functions.
00236   u_char cur_mode_;
00237   const u_char get_mode_;
00238   const u_char put_mode_;
00239 
00240   /// mode tells us if we're working for an istream, ostream, or
00241   /// iostream.
00242   int mode_;
00243 
00244   /// This defines the size of the input and output buffers.  It can be
00245   /// set by the object constructor.
00246   const u_int streambuf_size_;
00247 
00248   /// Did we take an error because of an IO operation timeout?
00249   u_char timeout_;
00250 
00251   /// We want to allow the user to provide Time_Value pointers to
00252   /// prevent infinite blocking while waiting to receive data.
00253   ACE_Time_Value recv_timeout_value_;
00254   ACE_Time_Value *recv_timeout_;
00255 
00256   /**
00257    * syncin is called when the input needs to be synced with the
00258    * source file.  In a filebuf, this results in the <seek> system
00259    * call being used.  We can't do that on socket-like connections, so
00260    * this does basically nothing.  That's safe because we have a
00261    * separate read buffer to maintain the already-read data.  In a
00262    * filebuf, the single common buffer is used forcing the <seek>
00263    * call.
00264    */
00265   int syncin (void);
00266 
00267   /// syncout is called when the output needs to be flushed.  This is
00268   /// easily done by calling the peer's send_n function.
00269   int syncout (void);
00270 
00271   /// flushbuf is the worker of syncout.  It is a separate function
00272   /// because it gets used sometimes in different context.
00273   int flushbuf (void);
00274 
00275   /**
00276    * fillbuf is called in a couple of places.  This is the worker of
00277    * underflow.  It will attempt to fill the read buffer from the
00278    * peer.
00279    */
00280   int fillbuf (void);
00281 
00282   /**
00283    * Used by fillbuf and others to get exactly one byte from the peer.
00284    * recv_n is used to be sure we block until something is available.
00285    * It is virtual because we really need to override it for
00286    * datagram-derived objects.
00287    */
00288   virtual int get_one_byte (void);
00289 
00290   /**
00291    * Stream connections and "unconnected connections" (ie --
00292    * datagrams) need to work just a little differently.  We derive
00293    * custom Streambuf objects for them and provide these functions at
00294    * that time.
00295    */
00296   virtual ssize_t send (char *buf,
00297                         ssize_t len) = 0;
00298   virtual ssize_t recv (char *buf,
00299                         ssize_t len,
00300                         ACE_Time_Value *tv = NULL) = 0;
00301   virtual ssize_t recv (char *buf,
00302                         ssize_t len,
00303                         int flags,
00304                         ACE_Time_Value *tv = NULL) = 0;
00305   virtual ssize_t recv_n (char *buf,
00306                           ssize_t len,
00307                           int flags = 0,
00308                           ACE_Time_Value *tv = NULL) = 0;
00309 
00310   virtual ACE_HANDLE get_handle (void);
00311 
00312 #if defined (ACE_HAS_STANDARD_CPP_LIBRARY) && (ACE_HAS_STANDARD_CPP_LIBRARY != 0) && !defined (ACE_USES_OLD_IOSTREAMS)
00313   char *base (void) const
00314     {
00315       return cur_mode_ == get_mode_ ? eback_saved_
00316         : cur_mode_ == put_mode_ ? pbase_saved_
00317         : 0;
00318     }
00319   char *ebuf (void) const
00320     {
00321       return cur_mode_ == 0 ? 0 : base () + streambuf_size_;
00322     }
00323 
00324   int blen (void) const
00325     {
00326       return streambuf_size_;
00327     }
00328 
00329   void setb (char* b, char* eb, int /* a */=0)
00330     {
00331       setbuf (b, (eb - b));
00332     }
00333 
00334   int out_waiting (void)
00335     {
00336       return pptr () - pbase ();
00337     }
00338 #endif /* ACE_HAS_STANDARD_CPP_LIBRARY */
00339 };
00340 
00341 ///////////////////////////////////////////////////////////////////////////
00342 
00343 // These typedefs are provided by G++ (on some systems?) without the
00344 // trailing '_'.  Since we can't count on 'em, I've defined them to
00345 // what GNU wants here.
00346 //
00347 typedef ios& (*__manip_)(ios&);
00348 typedef istream& (*__imanip_)(istream&);
00349 typedef ostream& (*__omanip_)(ostream&);
00350 
00351 // Trying to do something like is shown below instead of using the
00352 // __*manip typedefs causes Linux do segfault when "<<endl" is done.
00353 //
00354 //        virtual MT& operator<<(ios& (*func)(ios&))  { (*func)(*this); return *this; }
00355 
00356 // This macro defines the get operator for class MT into datatype DT.
00357 // We will use it below to quickly override most (all?)  iostream get
00358 // operators.  Notice how the <ipfx> and <isfx> functions are used.
00359 
00360 #define GET_SIG(MT,DT)          inline virtual MT& operator>> (DT v)
00361 #if defined (__KCC) || (defined (__SUNPRO_CC) && __SUNPRO_CC > 0x510)
00362 #define GET_CODE {                      \
00363         if (ipfx (0))                                   \
00364         {                                               \
00365                 (*((istream*)this)) >> (v);             \
00366         }                                               \
00367         isfx ();                                        \
00368         return *this;                                   \
00369         }
00370 #else
00371 #define GET_CODE {                      \
00372         if (ipfx (0))                                   \
00373         {                                               \
00374                 iostream::operator>> (v);               \
00375         }                                               \
00376         isfx ();                                        \
00377         return *this;                                   \
00378         }
00379 #endif /* __KCC */
00380 #define GET_PROT(MT,DT,CODE)    GET_SIG(MT,DT)  CODE
00381 #define GET_FUNC(MT,DT)         GET_PROT(MT,DT,GET_CODE)
00382 
00383 // This macro defines the put operator for class MT into datatype DT.
00384 // We will use it below to quickly override most (all?)  iostream put
00385 // operators.  Notice how the <opfx> and <osfx> functions are used.
00386 
00387 #define PUT_SIG(MT,DT)          inline virtual MT& operator<< (DT v)
00388 #if defined (__KCC) || (defined (__SUNPRO_CC) && __SUNPRO_CC > 0x510)
00389 #define PUT_CODE {                      \
00390         if (opfx ())                                    \
00391         {                                               \
00392                 (*((ostream *) this)) << (v);            \
00393         }                                               \
00394         osfx ();                                        \
00395         return *this;                                   \
00396         }
00397 #else
00398 #define PUT_CODE {                      \
00399         if (opfx ())                                    \
00400         {                                               \
00401                 iostream::operator<< (v);               \
00402         }                                               \
00403         osfx ();                                        \
00404         return *this;                                   \
00405         }
00406 #endif /* __KCC */
00407 #define PUT_PROT(MT,DT,CODE)    PUT_SIG(MT,DT)  CODE
00408 #define PUT_FUNC(MT,DT)         PUT_PROT(MT,DT,PUT_CODE)
00409 
00410 
00411 // These are necessary in case somebody wants to derive from us and
00412 // override one of these with a custom approach.
00413 
00414 #if defined (ACE_LACKS_CHAR_STAR_RIGHT_SHIFTS)
00415 #define GET_FUNC_SET0(MT,CODE,CODE2) \
00416         GET_PROT(MT,short &,CODE) \
00417         GET_PROT(MT,u_short &,CODE) \
00418         GET_PROT(MT,int &,CODE) \
00419         GET_PROT(MT,u_int &,CODE) \
00420         GET_PROT(MT,long &,CODE) \
00421         GET_PROT(MT,u_long &,CODE) \
00422         GET_PROT(MT,float &,CODE) \
00423         GET_PROT(MT,double &,CODE) \
00424         GET_PROT(MT,char &,CODE) \
00425         GET_PROT(MT,u_char &,CODE) \
00426         GET_PROT(MT,char *,CODE) \
00427         inline virtual MT& operator>>(__omanip_ func) CODE2 \
00428         inline virtual MT& operator>>(__manip_ func)  CODE2
00429 #elif defined (ACE_LACKS_CHAR_RIGHT_SHIFTS)
00430 #define GET_FUNC_SET0(MT,CODE,CODE2) \
00431         GET_PROT(MT,short &,CODE) \
00432         GET_PROT(MT,u_short &,CODE) \
00433         GET_PROT(MT,int &,CODE) \
00434         GET_PROT(MT,u_int &,CODE) \
00435         GET_PROT(MT,long &,CODE) \
00436         GET_PROT(MT,u_long &,CODE) \
00437         GET_PROT(MT,float &,CODE) \
00438         GET_PROT(MT,double &,CODE) \
00439         inline virtual MT& operator>>(__omanip_ func) CODE2 \
00440         inline virtual MT& operator>>(__manip_ func)  CODE2
00441 #else
00442 #define GET_FUNC_SET0(MT,CODE,CODE2) \
00443         GET_PROT(MT,short &,CODE) \
00444         GET_PROT(MT,u_short &,CODE) \
00445         GET_PROT(MT,int &,CODE) \
00446         GET_PROT(MT,u_int &,CODE) \
00447         GET_PROT(MT,long &,CODE) \
00448         GET_PROT(MT,u_long &,CODE) \
00449         GET_PROT(MT,float &,CODE) \
00450         GET_PROT(MT,double &,CODE) \
00451         GET_PROT(MT,char &,CODE) \
00452         GET_PROT(MT,u_char &,CODE) \
00453         GET_PROT(MT,char *,CODE) \
00454         GET_PROT(MT,u_char *,CODE) \
00455         inline virtual MT& operator>>(__omanip_ func) CODE2 \
00456         inline virtual MT& operator>>(__manip_ func)  CODE2
00457 #endif
00458 
00459 #define PUT_FUNC_SET0(MT,CODE,CODE2) \
00460         PUT_PROT(MT,short,CODE) \
00461         PUT_PROT(MT,u_short,CODE) \
00462         PUT_PROT(MT,int,CODE) \
00463         PUT_PROT(MT,u_int,CODE) \
00464         PUT_PROT(MT,long,CODE) \
00465         PUT_PROT(MT,u_long,CODE) \
00466         PUT_PROT(MT,float,CODE) \
00467         PUT_PROT(MT,double,CODE) \
00468         PUT_PROT(MT,char,CODE) \
00469         PUT_PROT(MT,u_char,CODE) \
00470         PUT_PROT(MT,const char *,CODE) \
00471         PUT_PROT(MT,u_char *,CODE) \
00472         PUT_PROT(MT,void *,CODE) \
00473         inline virtual MT& operator<<(__omanip_ func) CODE2 \
00474         inline virtual MT& operator<<(__manip_ func)  CODE2
00475 
00476 #if defined (ACE_LACKS_SIGNED_CHAR)
00477   #define GET_FUNC_SET1(MT,CODE,CODE2) GET_FUNC_SET0(MT,CODE,CODE2)
00478   #define PUT_FUNC_SET1(MT,CODE,CODE2) PUT_FUNC_SET0(MT,CODE,CODE2)
00479 #else
00480 #if defined (ACE_LACKS_CHAR_STAR_RIGHT_SHIFTS)
00481   #define GET_FUNC_SET1(MT,CODE,CODE2) \
00482           GET_PROT(MT,signed char &,CODE) \
00483           GET_FUNC_SET0(MT,CODE,CODE2)
00484 #else
00485   #define GET_FUNC_SET1(MT,CODE,CODE2) \
00486           GET_PROT(MT,signed char &,CODE) \
00487           GET_PROT(MT,signed char *,CODE) \
00488           GET_FUNC_SET0(MT,CODE,CODE2)
00489 #endif
00490 
00491   #define PUT_FUNC_SET1(MT,CODE,CODE2) \
00492           PUT_FUNC(MT,signed char) \
00493           PUT_FUNC(MT,const signed char *) \
00494           PUT_FUNC_SET0(MT,CODE,CODE2)
00495 #endif /* ACE_LACKS_SIGNED_CHAR */
00496 
00497 #define GET_MANIP_CODE  { if (ipfx ()) { (*func) (*this); } isfx (); return *this; }
00498 #define PUT_MANIP_CODE  { if (opfx ()) { (*func) (*this); } osfx (); return *this; }
00499 
00500 #define GET_FUNC_SET(MT)        GET_FUNC_SET1(MT,GET_CODE,GET_MANIP_CODE)
00501 #define PUT_FUNC_SET(MT)        PUT_FUNC_SET1(MT,PUT_CODE,PUT_MANIP_CODE)
00502 #define GETPUT_FUNC_SET(MT)     GET_FUNC_SET(MT) PUT_FUNC_SET(MT)
00503 
00504 #define GET_SIG_SET(MT)         GET_FUNC_SET1(MT,= 0;,= 0;)
00505 #define PUT_SIG_SET(MT)         PUT_FUNC_SET1(MT,= 0;,= 0;)
00506 #define GETPUT_SIG_SET(MT)      GET_SIG_SET(MT) PUT_SIG_SET(MT)
00507 
00508 // Include the templates here.
00509 #include "ace/IOStream_T.h"
00510 #endif /* !ACE_LACKS_ACE_IOSTREAM && ACE_USES_OLD_IOSTREAMS */
00511 
00512 #include "ace/post.h"
00513 #endif /* ACE_IOSTREAM_H */

Generated on Mon Jun 16 11:19:54 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002