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

IOStream_T.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    IOStream_T.h
00006  *
00007  *  $Id: IOStream_T.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  * This file should not be #included directly by application
00013  * code. Instead, it should #include "ace/IOStream.h".  That's because
00014  * we only put some conditional compilations in that file. 
00015  */
00016 //=============================================================================
00017 
00018 #ifndef ACE_IOSTREAM_T_H
00019 #define ACE_IOSTREAM_T_H
00020 #include "ace/pre.h"
00021 
00022 #include "ace/IOStream.h"
00023 
00024 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00025 # pragma once
00026 #endif /* ACE_LACKS_PRAGMA_ONCE */
00027 
00028 #if !defined (ACE_LACKS_ACE_IOSTREAM)
00029 
00030 #include "ace/INET_Addr.h"
00031 #include "ace/Handle_Set.h"
00032 
00033 #if defined (ACE_HAS_STRING_CLASS)
00034 template <class STREAM> STREAM & operator>> (STREAM &stream, ACE_Quoted_String &str);
00035 template <class STREAM> STREAM & operator<< (STREAM &stream, ACE_Quoted_String &str);
00036 #endif /* defined (ACE_HAS_STRING_CLASS) */
00037 
00038 template <class STREAM>
00039 class ACE_Streambuf_T : public ACE_Streambuf
00040 {
00041 public:
00042   /**
00043    * We will be given a STREAM by the iostream object which creates
00044    * us.  See the ACE_IOStream template for how that works.  Like
00045    * other streambuf objects, we can be input-only, output-only or
00046    * both.
00047    */
00048   ACE_Streambuf_T (STREAM *peer,
00049                    u_int streambuf_size = ACE_STREAMBUF_SIZE,
00050                    int io_mode = ios::in | ios::out);
00051 
00052   virtual ssize_t send (char *buf, ssize_t len);
00053 
00054   virtual ssize_t recv (char *buf,
00055                         ssize_t len,
00056                         ACE_Time_Value *tv = NULL);
00057 
00058   virtual ssize_t recv (char *buf,
00059                         ssize_t len,
00060                         int flags,
00061                         ACE_Time_Value * tv = NULL);
00062 
00063   virtual ssize_t recv_n (char *buf,
00064                           ssize_t len,
00065                           int flags = 0,
00066                           ACE_Time_Value *tv = NULL);
00067 
00068 protected:
00069   virtual ACE_HANDLE get_handle (void);
00070 
00071   /// This will be our ACE_SOCK_Stream or similar object.
00072   STREAM *peer_;
00073 };
00074 
00075 /**
00076  * @class ACE_IOStream
00077  *
00078  * @brief A template adapter for creating an iostream-like object using
00079  * an ACE IPC Stream for the actual I/O.  Iostreams use an
00080  * underlying streambuf object for the IO interface.  The
00081  * iostream class and derivatives provide you with a host of
00082  * convenient operators that access the streambuf.
00083  *
00084  * We inherit all characteristics of iostream and your <STREAM>
00085  * class.  When you create a new class from this template, you
00086  * can use it anywhere you would have used your original
00087  * <STREAM> class.
00088  * To create an iostream for your favorite ACE IPC class (e.g.,
00089  * <ACE_SOCK_Stream>), feed that class to this template's
00090  * <STREAM> parameter, e.g.,
00091  * typedef ACE_Svc_Handler<ACE_SOCK_iostream,
00092  * ACE_INET_Addr, ACE_NULL_SYNCH>
00093  * Service_Handler;
00094  * Because the operators in the iostream class are not virtual,
00095  * you cannot easily provide overloads in your custom
00096  * ACE_IOStream classes.  To make these things work correctly,
00097  * you need to overload ALL operators of the ACE_IOStream you
00098  * create. I've attempted to do that here to make things easier
00099  * for you but there are no guarantees.
00100  * In the iostream.cpp file is an example of why it is necessary
00101  * to overload all of the get/put operators when you want to
00102  * customize only one or two.
00103  */
00104 template <class STREAM>
00105 class ACE_IOStream : public iostream, public STREAM
00106 {
00107 public:
00108   // = Initialization and termination methods.
00109   ACE_IOStream (STREAM &stream,
00110                   u_int streambuf_size = ACE_STREAMBUF_SIZE);
00111 
00112   /**
00113    * The default constructor.  This will initiailze your STREAM and
00114    * then setup the iostream baseclass to use a custom streambuf based
00115    * on STREAM.
00116    */
00117   ACE_IOStream (u_int streambuf_size = ACE_STREAMBUF_SIZE);
00118 
00119   /// We have to get rid of the <streambuf_> ourselves since we gave it
00120   /// to the <iostream> base class;
00121   virtual ~ACE_IOStream (void);
00122 
00123   /// The only ambituity in the multiple inheritance is the <close>
00124   /// function.
00125   virtual int close (void);
00126 
00127   /**
00128    * Returns 1 if we're at the end of the <STREAM>, i.e., if the
00129    * connection has closed down or an error has occurred, else 0.
00130    * Under the covers, <eof> calls the streambuf's <timeout> function
00131    * which will reset the timeout flag.  As as result, you should save
00132    * the return of <eof> and check it instead of calling <eof>
00133    * successively.
00134    */
00135   int eof (void) const;
00136 
00137 #if defined (ACE_HAS_STRING_CLASS)
00138   /**
00139    * A simple string operator.  The base <iostream> has them for char*
00140    * but that isn't always the best thing for a <String>.  If we don't
00141    * provide our own here, we may not get what we want.
00142    */
00143   virtual ACE_IOStream<STREAM> &operator>> (ACE_IOStream_String &v);
00144 
00145   /// The converse of the <String::put> operator.
00146   virtual ACE_IOStream<STREAM> &operator<< (ACE_IOStream_String &v);
00147 
00148 #endif /* ACE_HAS_STRING_CLASS */
00149   // = Using the macros to provide get/set operators.
00150   GETPUT_FUNC_SET (ACE_IOStream<STREAM>)
00151 
00152 #if defined (ACE_LACKS_IOSTREAM_FX)
00153   virtual int ipfx (int noskip = 0)
00154     {
00155       if (good ())
00156         {
00157           if (tie () != 0)
00158              tie ()->flush ();
00159           if (!noskip && flags () & skipws)
00160             {
00161               int ch;
00162               while (isspace (ch = rdbuf ()->sbumpc ()))
00163                 continue;
00164               if (ch != EOF)
00165                   rdbuf ()->sputbackc (ch);
00166             }
00167           if (good ())
00168               return 1;
00169         }
00170 #if !defined (ACE_WIN32)
00171       // MS VC++ 5.0 doesn't declare setstate.
00172       setstate (failbit);
00173 #endif /* !ACE_WIN32 */
00174       return (0);
00175     }
00176   virtual int ipfx0 (void)         {  return ipfx (0); }  // Optimized ipfx(0)
00177   virtual int ipfx1 (void)                                // Optimized ipfx(1)
00178     {
00179       if (good ())
00180         {
00181           if (tie () != 0)
00182              tie ()->flush ();
00183           if (good ())
00184               return 1;
00185         }
00186 #if !defined (ACE_WIN32)
00187       // MS VC++ 5.0 doesn't declare setstate.
00188       setstate (failbit);
00189 #endif /* !ACE_WIN32 */
00190       return (0);
00191     }
00192   virtual void isfx (void) {  return; }
00193   virtual int opfx (void)
00194     {
00195       if (good () && tie () != 0)
00196         tie ()->flush ();
00197       return good ();
00198     }
00199   virtual void osfx (void) {  if (flags () & unitbuf) flush (); }
00200 #else
00201 #if defined (__GNUC__)
00202   virtual int ipfx0 (void) { return iostream::ipfx0 (); }  // Optimized ipfx(0)
00203   virtual int ipfx1 (void) { return iostream::ipfx1 (); }  // Optimized ipfx(1)
00204 #else
00205   virtual int ipfx0 (void) { return iostream::ipfx (0); }
00206   virtual int ipfx1 (void) { return iostream::ipfx (1); }
00207 #endif /* __GNUC__ */
00208   virtual int ipfx (int need = 0) {  return iostream::ipfx (need); }
00209   virtual void isfx (void)        {  iostream::isfx (); }
00210   virtual int opfx (void)         {  return iostream::opfx (); }
00211   virtual void osfx (void)        {  iostream::osfx (); }
00212 #endif /* ACE_LACKS_IOSTREAM_FX */
00213 
00214   /// Allow the programmer to provide a timeout for read operations.
00215   /// Give it a pointer to NULL to block forever.
00216   ACE_IOStream<STREAM> & operator>> (ACE_Time_Value *&tv);
00217 
00218 protected:
00219   /// This is where all of the action takes place.  The streambuf_ is
00220   /// the interface to the underlying STREAM.
00221   ACE_Streambuf_T<STREAM> *streambuf_;
00222 
00223 private:
00224   // = Private methods.
00225 
00226   // We move these into the private section so that they cannot be
00227   // used by the application programmer.  This is necessary because
00228   // streambuf_ will be buffering IO on the STREAM object.  If these
00229   // functions were used in your program, there is a danger of getting
00230   // the datastream out of sync.
00231   ACE_UNIMPLEMENTED_FUNC (ssize_t send (...))
00232   ACE_UNIMPLEMENTED_FUNC (ssize_t recv (...))
00233   ACE_UNIMPLEMENTED_FUNC (ssize_t send_n (...))
00234   ACE_UNIMPLEMENTED_FUNC (ssize_t recv_n (...))
00235 };
00236 
00237 /**
00238  * @class ACE_SOCK_Dgram_SC
00239  *
00240  * @brief "Dgram_SC" is short for "Datagram Self-Contained."
00241  *
00242  * Datagrams don't have the notion of a "peer".  Each send and
00243  * receive on a datagram can go to a different peer if you want.
00244  * If you're using datagrams for stream activity, you probably
00245  * want 'em all to go to (and come from) the same place.  That's
00246  * what this class is for.  Here, we keep an address object so
00247  * that we can remember who last sent us data.  When we write
00248  * back, we're then able to write back to that same address.
00249  */
00250 template <class STREAM>
00251 class ACE_SOCK_Dgram_SC : public STREAM
00252 {
00253 public:
00254   ACE_SOCK_Dgram_SC (void);
00255   ACE_SOCK_Dgram_SC (STREAM &source,
00256                      ACE_INET_Addr &dest);
00257   ssize_t send_n (char *buf, ssize_t len);
00258   ssize_t recv  (char *buf,
00259                  ssize_t len,
00260                  ACE_Time_Value *tv = NULL);
00261   ssize_t recv (char *buf,
00262                 ssize_t len,
00263                 int flags,
00264                 ACE_Time_Value *tv = NULL);
00265   ssize_t recv_n (char *buf,
00266                   ssize_t len,
00267                   int flags = 0,
00268                   ACE_Time_Value *tv = NULL);
00269   int get_remote_addr (ACE_INET_Addr &addr) const;
00270 
00271 protected:
00272   ACE_INET_Addr peer_;
00273 };
00274 
00275 #if defined (__ACE_INLINE__)
00276 #include "ace/IOStream_T.i"
00277 #endif /* __ACE_INLINE__ */
00278 
00279 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00280 #include "ace/IOStream_T.cpp"
00281 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00282 
00283 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00284 #pragma implementation ("IOStream_T.cpp")
00285 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00286 #endif /* ACE_LACKS_ACE_IOSTREAM */
00287 #include "ace/post.h"
00288 #endif /* ACE_IOSTREAM_T_H */

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