/* -*- C++ -*- */ //============================================================================= /** * @file IOStream_T.h * * @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/Global_Macros.h" # if defined (ACE_LACKS_IOSTREAM_FX) # include "ace/os_include/os_ctype.h" # endif /**/ ACE_BEGIN_VERSIONED_NAMESPACE_DECL template STREAM & operator>> (STREAM &stream, ACE_Quoted_String &str); template STREAM & operator<< (STREAM &stream, ACE_Quoted_String &str); 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 = 0); virtual ssize_t recv (char *buf, ssize_t len, int flags, ACE_Time_Value * tv = 0); virtual ssize_t recv_n (char *buf, ssize_t len, int flags = 0, ACE_Time_Value *tv = 0); protected: virtual ACE_HANDLE get_handle (); /// 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., * ACE_SOCK_Stream), 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: ACE_IOStream (STREAM &stream, u_int streambuf_size = ACE_STREAMBUF_SIZE); /** * The default constructor. This will initialize 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 (); /// The only ambiguity in the multiple inheritance is the /// function. virtual int close (); /** * 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 @a timeout 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 () const; /** * 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); // = 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; } setstate (failbit); return (0); } virtual int ipfx0 () // Optimized ipfx(0) { return ipfx (0); } virtual int ipfx1 () // Optimized ipfx(1) { if (good ()) { if (tie () != 0) tie ()->flush (); if (good ()) return 1; } setstate (failbit); return (0); } virtual void isfx () { return; } virtual int opfx () { if (good () && tie () != 0) tie ()->flush (); return good (); } virtual void osfx () { if (flags () & unitbuf) flush (); } # else # if defined (__GNUC__) virtual int ipfx0 () { return iostream::ipfx0 (); } // Optimized ipfx(0) virtual int ipfx1 () { return iostream::ipfx1 (); } // Optimized ipfx(1) # else virtual int ipfx0 () { return iostream::ipfx (0); } virtual int ipfx1 () { return iostream::ipfx (1); } # endif /* __GNUC__ */ virtual int ipfx (int need = 0) { return iostream::ipfx (need); } virtual void isfx () { iostream::isfx (); } virtual int opfx () { return iostream::opfx (); } virtual void osfx () { 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: // 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. ssize_t send (...) = delete; ssize_t recv (...) = delete; ssize_t send_n (...) = delete; ssize_t recv_n (...) = delete; }; /** * @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 (); 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 = 0); ssize_t recv (char *buf, ssize_t len, int flags, ACE_Time_Value *tv = 0); ssize_t recv_n (char *buf, ssize_t len, int flags = 0, ACE_Time_Value *tv = 0); int get_remote_addr (ACE_INET_Addr &addr) const; protected: ACE_INET_Addr peer_; }; ACE_END_VERSIONED_NAMESPACE_DECL #if defined (__ACE_INLINE__) # include "ace/IOStream_T.inl" #endif /* __ACE_INLINE__ */ #include "ace/IOStream_T.cpp" #include /**/ "ace/post.h" #endif /* ACE_IOSTREAM_T_H */