IOStream_T.h

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

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6