/* -*- C++ -*- */ //============================================================================= /** * @file IOStream_T.h * * $Id$ * * @author James CE Johnson * @author Jim Crossley * * This file should not be #included directly by application * code. Instead, it should #include "ace/IOStream.h". That's because * we only put some conditional compilations in that file. */ //============================================================================= #ifndef ACE_IOSTREAM_T_H #define ACE_IOSTREAM_T_H #include /**/ "ace/pre.h" #include "ace/IOStream.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #if !defined (ACE_LACKS_ACE_IOSTREAM) # include "ace/INET_Addr.h" # include "ace/Handle_Set.h" # include "ace/Global_Macros.h" # if defined (ACE_LACKS_IOSTREAM_FX) # include "ace/os_include/os_ctype.h" # endif /**/ # if defined (ACE_HAS_STRING_CLASS) template STREAM & operator>> (STREAM &stream, ACE_Quoted_String &str); template STREAM & operator<< (STREAM &stream, ACE_Quoted_String &str); # endif /* defined (ACE_HAS_STRING_CLASS) */ template class ACE_Streambuf_T : public ACE_Streambuf { public: /** * We will be given a STREAM by the iostream object which creates * us. See the ACE_IOStream template for how that works. Like * other streambuf objects, we can be input-only, output-only or * both. */ ACE_Streambuf_T (STREAM *peer, u_int streambuf_size = ACE_STREAMBUF_SIZE, int io_mode = ios::in | ios::out); virtual ssize_t send (char *buf, ssize_t len); virtual ssize_t recv (char *buf, ssize_t len, ACE_Time_Value *tv = NULL); virtual ssize_t recv (char *buf, ssize_t len, int flags, ACE_Time_Value * tv = NULL); virtual ssize_t recv_n (char *buf, ssize_t len, int flags = 0, ACE_Time_Value *tv = NULL); protected: virtual ACE_HANDLE get_handle (void); /// This will be our ACE_SOCK_Stream or similar object. STREAM *peer_; }; /** * @class ACE_IOStream * * @brief A template adapter for creating an iostream-like object using * an ACE IPC Stream for the actual I/O. Iostreams use an * underlying streambuf object for the IO interface. The * iostream class and derivatives provide you with a host of * convenient operators that access the streambuf. * * We inherit all characteristics of iostream and your * class. When you create a new class from this template, you * can use it anywhere you would have used your original * class. * To create an iostream for your favorite ACE IPC class (e.g., * ), feed that class to this template's * parameter, e.g., * typedef ACE_Svc_Handler * Service_Handler; * Because the operators in the iostream class are not virtual, * you cannot easily provide overloads in your custom * ACE_IOStream classes. To make these things work correctly, * you need to overload ALL operators of the ACE_IOStream you * create. I've attempted to do that here to make things easier * for you but there are no guarantees. * In the iostream.cpp file is an example of why it is necessary * to overload all of the get/put operators when you want to * customize only one or two. */ template class ACE_IOStream : public iostream, public STREAM { public: // = Initialization and termination methods. ACE_IOStream (STREAM &stream, u_int streambuf_size = ACE_STREAMBUF_SIZE); /** * The default constructor. This will initiailze your STREAM and * then setup the iostream baseclass to use a custom streambuf based * on STREAM. */ ACE_IOStream (u_int streambuf_size = ACE_STREAMBUF_SIZE); /// We have to get rid of the ourselves since we gave it /// to the base class; virtual ~ACE_IOStream (void); /// The only ambituity in the multiple inheritance is the /// function. virtual int close (void); /** * Returns 1 if we're at the end of the , i.e., if the * connection has closed down or an error has occurred, else 0. * Under the covers, calls the streambuf's function * which will reset the timeout flag. As as result, you should save * the return of and check it instead of calling * successively. */ int eof (void) const; # if defined (ACE_HAS_STRING_CLASS) /** * A simple string operator. The base has them for char* * but that isn't always the best thing for a . If we don't * provide our own here, we may not get what we want. */ virtual ACE_IOStream &operator>> (ACE_IOStream_String &v); /// The converse of the operator. virtual ACE_IOStream &operator<< (ACE_IOStream_String &v); # endif /* ACE_HAS_STRING_CLASS */ // = Using the macros to provide get/set operators. GETPUT_FUNC_SET (ACE_IOStream) # if defined (ACE_LACKS_IOSTREAM_FX) virtual int ipfx (int noskip = 0) { if (good ()) { if (tie () != 0) tie ()->flush (); if (!noskip && flags () & skipws) { int ch; while (isspace (ch = rdbuf ()->sbumpc ())) continue; if (ch != EOF) rdbuf ()->sputbackc (ch); } if (good ()) return 1; } # if !defined (ACE_WIN32) // MS VC++ 5.0 doesn't declare setstate. setstate (failbit); # endif /* !ACE_WIN32 */ return (0); } virtual int ipfx0 (void) { return ipfx (0); } // Optimized ipfx(0) virtual int ipfx1 (void) // Optimized ipfx(1) { if (good ()) { if (tie () != 0) tie ()->flush (); if (good ()) return 1; } # if !defined (ACE_WIN32) // MS VC++ 5.0 doesn't declare setstate. setstate (failbit); # endif /* !ACE_WIN32 */ return (0); } virtual void isfx (void) { return; } virtual int opfx (void) { if (good () && tie () != 0) tie ()->flush (); return good (); } virtual void osfx (void) { if (flags () & unitbuf) flush (); } # else # if defined (__GNUC__) virtual int ipfx0 (void) { return iostream::ipfx0 (); } // Optimized ipfx(0) virtual int ipfx1 (void) { return iostream::ipfx1 (); } // Optimized ipfx(1) # else virtual int ipfx0 (void) { return iostream::ipfx (0); } virtual int ipfx1 (void) { return iostream::ipfx (1); } # endif /* __GNUC__ */ virtual int ipfx (int need = 0) { return iostream::ipfx (need); } virtual void isfx (void) { iostream::isfx (); } virtual int opfx (void) { return iostream::opfx (); } virtual void osfx (void) { iostream::osfx (); } # endif /* ACE_LACKS_IOSTREAM_FX */ /// Allow the programmer to provide a timeout for read operations. /// Give it a pointer to NULL to block forever. ACE_IOStream & operator>> (ACE_Time_Value *&tv); protected: /// This is where all of the action takes place. The streambuf_ is /// the interface to the underlying STREAM. ACE_Streambuf_T *streambuf_; private: // = Private methods. // We move these into the private section so that they cannot be // used by the application programmer. This is necessary because // streambuf_ will be buffering IO on the STREAM object. If these // functions were used in your program, there is a danger of getting // the datastream out of sync. ACE_UNIMPLEMENTED_FUNC (ssize_t send (...)) ACE_UNIMPLEMENTED_FUNC (ssize_t recv (...)) ACE_UNIMPLEMENTED_FUNC (ssize_t send_n (...)) ACE_UNIMPLEMENTED_FUNC (ssize_t recv_n (...)) }; /** * @class ACE_SOCK_Dgram_SC * * @brief "Dgram_SC" is short for "Datagram Self-Contained." * * Datagrams don't have the notion of a "peer". Each send and * receive on a datagram can go to a different peer if you want. * If you're using datagrams for stream activity, you probably * want 'em all to go to (and come from) the same place. That's * what this class is for. Here, we keep an address object so * that we can remember who last sent us data. When we write * back, we're then able to write back to that same address. */ template class ACE_SOCK_Dgram_SC : public STREAM { public: ACE_SOCK_Dgram_SC (void); ACE_SOCK_Dgram_SC (STREAM &source, ACE_INET_Addr &dest); ssize_t send_n (char *buf, ssize_t len); ssize_t recv (char *buf, ssize_t len, ACE_Time_Value *tv = NULL); ssize_t recv (char *buf, ssize_t len, int flags, ACE_Time_Value *tv = NULL); ssize_t recv_n (char *buf, ssize_t len, int flags = 0, ACE_Time_Value *tv = NULL); int get_remote_addr (ACE_INET_Addr &addr) const; protected: ACE_INET_Addr peer_; }; # if defined (__ACE_INLINE__) # include "ace/IOStream_T.inl" # endif /* __ACE_INLINE__ */ # if defined (ACE_TEMPLATES_REQUIRE_SOURCE) # include "ace/IOStream_T.cpp" # endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ # if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) # pragma implementation ("IOStream_T.cpp") # endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* ACE_LACKS_ACE_IOSTREAM */ #include /**/ "ace/post.h" #endif /* ACE_IOSTREAM_T_H */