summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-05-24 02:39:14 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-05-24 02:39:14 +0000
commit9f5f2ecd526db5689ff6712f2a317845dfb2b90a (patch)
tree3934dba31e9d8d7f402a68a9767ddcb2e23a9a30
parent49d2b1a9b3ec1595a9d1273b758f7fa2ba5743d5 (diff)
downloadATCD-9f5f2ecd526db5689ff6712f2a317845dfb2b90a.tar.gz
ACE_IOStream updates: mainly split out templates into separate _T files
-rw-r--r--ace/IOStream.cpp231
-rw-r--r--ace/IOStream.h275
-rw-r--r--ace/IOStream_T.cpp189
-rw-r--r--ace/IOStream_T.h280
-rw-r--r--ace/README1
5 files changed, 512 insertions, 464 deletions
diff --git a/ace/IOStream.cpp b/ace/IOStream.cpp
index 8f9ceb042e7..4737cf6318a 100644
--- a/ace/IOStream.cpp
+++ b/ace/IOStream.cpp
@@ -4,10 +4,10 @@
#if !defined (ACE_IOSTREAM_C)
#define ACE_IOSTREAM_C
+#if !defined (ACE_LACKS_ACE_IOSTREAM)
+
#define ACE_BUILD_DLL
#include "ace/IOStream.h"
-#include "ace/Thread.h"
-#include "ace/Handle_Set.h"
///////////////////////////////////////////////////////////////////////////
@@ -42,7 +42,7 @@
// invokes iostream::operator>> (int&) then iostream::operator>> (String&)
//
// What has happened is that the first >> is invoked on the base class and returns
- // a reference to iostream. The second >> has no idea of the ACE_IOStream and
+ // a reference to iostream. The second >> has no idea of the ACE_IOStream_T and
// gets invoked on iostream. Probably NOT what you wanted!
@@ -84,10 +84,8 @@
// a myiostream&, the second >> will be invoked as desired. */
-#if ! defined (ACE_IOSTREAM_BUILDING_TEMPLATE)
-
-ACE_Time_Value *
-ACE_Streambuf_T::recv_timeout (ACE_Time_Value * tv)
+ACE_Time_Value *
+ACE_Streambuf::recv_timeout (ACE_Time_Value * tv)
{
ACE_Time_Value * rval = recv_timeout_;
if (tv)
@@ -102,7 +100,7 @@ ACE_Streambuf_T::recv_timeout (ACE_Time_Value * tv)
}
int
-ACE_Streambuf_T::underflow (void)
+ACE_Streambuf::underflow (void)
{
// If input mode is not set, any attempt to read from the stream is
// a failure.
@@ -221,7 +219,7 @@ ACE_Streambuf_T::underflow (void)
// rather than repeating a lot of what you've already seen.
int
-ACE_Streambuf_T::overflow (int c)
+ACE_Streambuf::overflow (int c)
{
// Check to see if output is allowed at all.
if (! (mode_ & ios::out))
@@ -291,7 +289,7 @@ ACE_Streambuf_T::overflow (int c)
// syncin
int
-ACE_Streambuf_T::syncin (void)
+ACE_Streambuf::syncin (void)
{
// As discussed, there really isn't any way to sync input from a socket-like
// device. We specifially override this base-class function so that it won't
@@ -302,7 +300,7 @@ ACE_Streambuf_T::syncin (void)
// syncout
int
-ACE_Streambuf_T::syncout (void)
+ACE_Streambuf::syncout (void)
{
// Unlike syncin, syncout is a doable thing. All we have to do is
// write whatever is in the output buffer to the peer. flushbuf ()
@@ -315,7 +313,7 @@ ACE_Streambuf_T::syncout (void)
}
int
-ACE_Streambuf_T::sync (void)
+ACE_Streambuf::sync (void)
{
// sync () is fairly traditional in that it syncs both input and output.
// We could have omitted the call to syncin () but someday, we may want it
@@ -334,7 +332,7 @@ ACE_Streambuf_T::sync (void)
// flushbuf
int
-ACE_Streambuf_T::flushbuf (void)
+ACE_Streambuf::flushbuf (void)
{
// pptr () is one character beyond the last character put
// into the buffer. pbase () points to the beginning of
@@ -395,8 +393,8 @@ ACE_Streambuf_T::flushbuf (void)
return 0;
}
-int
-ACE_Streambuf_T::get_one_byte (void)
+int
+ACE_Streambuf::get_one_byte (void)
{
// The recv function will return immediately if there is no data
// waiting. So, we use recv_n to wait for exactly one byte to come
@@ -411,7 +409,7 @@ ACE_Streambuf_T::get_one_byte (void)
}
int
-ACE_Streambuf_T::fillbuf (void)
+ACE_Streambuf::fillbuf (void)
// This will be called when the read (get) buffer has been
// exhausted (ie -- gptr == egptr)
{
@@ -422,7 +420,7 @@ ACE_Streambuf_T::fillbuf (void)
return EOF;
// Now, get whatever else may be in the buffer. This will return if
- // there is nothing in the buffer.
+ // there is nothing in the buffer.
int bc = this->recv (base (), blen (), recv_timeout_);
@@ -441,7 +439,7 @@ ACE_Streambuf_T::fillbuf (void)
return bc;
}
-ACE_Streambuf_T::ACE_Streambuf_T (u_int streambuf_size, int io_mode)
+ACE_Streambuf::ACE_Streambuf (u_int streambuf_size, int io_mode)
: eback_saved_ (0), // to avoid Purify UMR
pbase_saved_ (0), // to avoid Purify UMR
get_mode_ (1),
@@ -454,26 +452,26 @@ ACE_Streambuf_T::ACE_Streambuf_T (u_int streambuf_size, int io_mode)
(void)reset_put_buffer ();
}
-u_int ACE_Streambuf_T::streambuf_size (void)
+u_int ACE_Streambuf::streambuf_size (void)
{
return streambuf_size_;
}
-u_int ACE_Streambuf_T::get_waiting (void)
+u_int ACE_Streambuf::get_waiting (void)
// Return the number of bytes not yet gotten.
// eback + get_waiting = gptr
{
return this->gptr_saved_ - this->eback_saved_;
}
-u_int ACE_Streambuf_T::get_avail (void)
+u_int ACE_Streambuf::get_avail (void)
// Return the number of bytes in the get area (includes some already gotten);
// eback + get_avail = egptr
{
return this->egptr_saved_ - this->eback_saved_;
}
-u_int ACE_Streambuf_T::put_avail (void)
+u_int ACE_Streambuf::put_avail (void)
// Return the number of bytes to be 'put' onto the stream media.
// pbase + put_avail = pptr
{
@@ -481,7 +479,7 @@ u_int ACE_Streambuf_T::put_avail (void)
}
char *
-ACE_Streambuf_T::reset_get_buffer (char * newBuffer, u_int _streambuf_size, u_int _gptr, u_int _egptr)
+ACE_Streambuf::reset_get_buffer (char * newBuffer, u_int _streambuf_size, u_int _gptr, u_int _egptr)
//
// Typical usage:
//
@@ -536,7 +534,7 @@ ACE_Streambuf_T::reset_get_buffer (char * newBuffer, u_int _streambuf_size, u_in
}
char *
-ACE_Streambuf_T::reset_put_buffer (char * newBuffer, u_int _streambuf_size, u_int _pptr)
+ACE_Streambuf::reset_put_buffer (char * newBuffer, u_int _streambuf_size, u_int _pptr)
//
// Typical usage:
//
@@ -584,7 +582,7 @@ ACE_Streambuf_T::reset_put_buffer (char * newBuffer, u_int _streambuf_size, u_in
}
void
-ACE_Streambuf_T::reset_base (void)
+ACE_Streambuf::reset_base (void)
{
// Until we experience the first get or put operation, we do not
// know what our current IO mode is.
@@ -602,191 +600,12 @@ ACE_Streambuf_T::reset_base (void)
// would be deleted when the object destructs. Since we are providing
// separate read/write buffers, it is up to us to manage their memory.
-ACE_Streambuf_T::~ACE_Streambuf_T (void)
+ACE_Streambuf::~ACE_Streambuf (void)
{
delete [] this->eback_saved_;
delete [] this->pbase_saved_;
}
-#endif // ACE_IOSTREAM_BUILDING_TEMPLATE
-
-///////////////////////////////////////////////////////////////////////////
-
-
-// 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.
-
-template <class STREAM>
-ACE_Streambuf<STREAM>::ACE_Streambuf (STREAM *peer, u_int streambuf_size, int io_mode)
- : ACE_Streambuf_T (streambuf_size, io_mode), peer_ (peer)
-{
- // A streambuf allows for unbuffered IO where every character is
- // read as requested and written as provided. To me, this seems
- // terribly inefficient for socket-type operations, so I've disabled
- // it. All of the work would be done by the underflow/overflow
- // functions anyway and I haven't implemented anything there to
- // support unbuffered IO.
-
- this->unbuffered (0);
-
- // Linebuffered is similar to unbuffered. Again, I don't have any
- // need for this and I don't see the advantage. I believe this
- // would have to be supported by underflow/overflow to be effective.
-#if !defined (ACE_LACKS_LINEBUFFERED_STREAMBUF)
- this->linebuffered (0);
-#endif /* ! ACE_LACKS_LINEBUFFERED_STREAMBUF */
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-
-
-// The typical constructor. This will initiailze your STREAM and then
-// setup the iostream baseclass to use a custom streambuf based on
-// STREAM.
-
-template <class STREAM>
-ACE_IOStream<STREAM>::ACE_IOStream (STREAM & stream, u_int streambuf_size)
- : iostream (streambuf_ = new ACE_Streambuf<STREAM> ((STREAM *) this, streambuf_size)),
- STREAM (stream)
-{
- iostream::init (this->streambuf_);
-}
-
-template <class STREAM>
-ACE_IOStream<STREAM>::ACE_IOStream (u_int streambuf_size)
- : iostream (streambuf_ = new ACE_Streambuf<STREAM> ((STREAM *) this, streambuf_size))
-{
- iostream::init (this->streambuf_);
-}
-
-// We have to get rid of the streambuf_ ourselves since we gave it to
-// iostream ()
-
-template <class STREAM>
-ACE_IOStream<STREAM>::~ACE_IOStream (void)
-{
- delete this->streambuf_;
-}
-
-// The only ambituity in the multiple inheritance is the close ()
-// function.
-
-template <class STREAM> int
-ACE_IOStream<STREAM>::close (void)
-{
- return STREAM::close ();
-}
-
-template <class STREAM> ACE_IOStream<STREAM> &
-ACE_IOStream<STREAM>::operator>> (ACE_Time_Value *& tv)
-{
- ACE_Time_Value * old_tv = this->streambuf_->recv_timeout (tv);
- tv = old_tv;
- return *this;
-}
-
-#if defined (ACE_HAS_STRING_CLASS)
+#endif /* !ACE_LACKS_ACE_IOSTREAM */
-// A simple string operator. The base iostream has 'em for char* but
-// that isn't always the best thing for a String. If we don't provide
-// our own here, we may not get what we want.
-
-template <class STREAM> ACE_IOStream<STREAM> &
-ACE_IOStream<STREAM>::operator>> (ACE_IOStream_String & v)
-{
- if (ipfx0 ())
- {
- char c;
- iostream::operator>> (c);
-
- for (v = c ; this->get (c) && !isspace (c) ; v += c)
- continue;
- }
-
- isfx ();
-
- return *this;
-}
-
-
-template <class STREAM> ACE_IOStream<STREAM> &
-ACE_IOStream<STREAM>::operator<< (ACE_IOStream_String & v)
-{
- if (opfx ())
- {
-#if defined (ACE_WIN32)
- for (int i = 0 ; i < v.GetLength () ; ++i)
-#else
- for (u_int i = 0 ; i < (u_int) v.length () ; ++i)
-#endif
- this->put (v[i]);
- }
-
- osfx ();
-
- return *this;
-}
-
-
-//////////////////////////////////////////////////////////////////
-// A more clever put operator for strings that knows how to
-// deal with quoted strings containing back-quoted quotes.
-//
-template <class STREAM> ACE_IOStream<STREAM> &
-ACE_IOStream<STREAM>::operator>> (QuotedString & str)
-{
- if (ipfx0 ())
- {
- char c;
-
- if (! (*this >> c)) // eat space up to the first char
- // this->set (ios::eofbit|ios::failbit);
- return *this;
-
- str = ""; // Initialize the string
-
- // if we don't have a quote, append until we see space
- if (c != '"')
- for (str = c ; this->get (c) && !isspace (c) ; str += c)
- continue;
- else
- for (; this->get (c) && c != '"' ; str += c)
- if (c == '\\')
- {
- this->get (c);
- if (c != '"')
- str += '\\';
- }
- }
-
- isfx ();
-
- return *this;
-}
-
-template <class STREAM> ACE_IOStream<STREAM> &
-ACE_IOStream<STREAM>::operator<< (QuotedString & str)
-{
- if (opfx ())
- {
- this->put ('"');
- for (u_int i = 0 ; i < str.length () ; ++i)
- {
- if (str[i] == '"')
- this->put ('\\');
- this->put (str[i]);
- }
- this->put ('"');
- }
-
- osfx ();
-
- return *this;
-}
-
-#endif /* ACE_HAS_STRING_CLASS */
#endif /* ACE_IOSTREAM_C */
-
diff --git a/ace/IOStream.h b/ace/IOStream.h
index 454f803e829..1a9ac2886a5 100644
--- a/ace/IOStream.h
+++ b/ace/IOStream.h
@@ -7,7 +7,7 @@
// ace
//
// = FILENAME
-// iostream.h
+// IOStream.h
//
// = AUTHOR
// James CE Johnson <jcej@lads.com>
@@ -20,7 +20,7 @@
/*
Changes 4/5/97
- ACE_Streambuf_T
+ ACE_Streambuf
New public functions added
@@ -62,26 +62,27 @@
Constructor changed
Initialization of the get/put buffers was moved here from
- the derived class/template ACE_Streambuf<...>
+ the derived class/template ACE_Streambuf_T<...>
At the same time, the new functions reset_get/put_buffer
are now used instead of the previous monolithic function.
- ACE_Streambuf<...>
+ ACE_Streambuf_T<...>
Constructor changed:
Initialization of the get/put buffers has been moved to the
- baseclass ACE_Streambuf_T. This will reduce template bloat
+ baseclass ACE_Streambuf. This will reduce template bloat
as well as giving us more functionality as described above.
*/
#if !defined (ACE_IOSTREAM_H)
#define ACE_IOSTREAM_H
+#if !defined (ACE_LACKS_ACE_IOSTREAM)
+
#include "ace/INET_Addr.h"
#include "ace/Handle_Set.h"
-#include <iomanip.h>
#if defined (ACE_HAS_STRING_CLASS)
#if defined (ACE_WIN32)
@@ -104,15 +105,15 @@ public:
inline QuotedString (void) { *this = ""; }
inline QuotedString (const char * c) { *this = ACE_IOStream_String (c); }
inline QuotedString (const ACE_IOStream_String& s) { *this = s; }
- inline QuotedString& operator= (const ACE_IOStream_String& s)
+ inline QuotedString& operator= (const ACE_IOStream_String& s)
{
return (QuotedString&) ACE_IOStream_String::operator= (s);
}
inline QuotedString & operator = (const char c) {
- return (QuotedString&) ACE_IOStream_String::operator= (c);
+ return (QuotedString&) ACE_IOStream_String::operator= (c);
}
- inline QuotedString & operator = (const char* c) {
- return (QuotedString&) ACE_IOStream_String::operator= (c);
+ inline QuotedString & operator = (const char* c) {
+ return (QuotedString&) ACE_IOStream_String::operator= (c);
}
inline bool operator < (const QuotedString& s) const {
return *(ACE_IOStream_String *) this < (ACE_IOStream_String) s;
@@ -126,7 +127,7 @@ public:
///////////////////////////////////////////////////////////////////////////
-class ACE_Export ACE_Streambuf_T : public streambuf
+class ACE_Export ACE_Streambuf : public streambuf
// = TITLE
// Create your custom streambuf by providing and ACE_*_Stream
// object to this template. I have tested it with
@@ -190,7 +191,7 @@ class ACE_Export ACE_Streambuf_T : public streambuf
{
public:
- virtual ~ACE_Streambuf_T (void);
+ virtual ~ACE_Streambuf (void);
// If the default allocation strategey were used the common buffer
// would be deleted when the object destructs. Since we are
// providing separate read/write buffers, it is up to us to manage
@@ -232,7 +233,7 @@ public:
// Query the streambuf for the size of it's buffers.
protected:
- ACE_Streambuf_T (u_int streambuf_size, int io_mode);
+ ACE_Streambuf (u_int streambuf_size, int io_mode);
virtual int sync (void);
// Sync both input and output. See syncin/syncout below for
@@ -322,47 +323,6 @@ protected:
///////////////////////////////////////////////////////////////////////////
-template <class STREAM>
-class ACE_Streambuf : public ACE_Streambuf_T
-{
-public:
- ACE_Streambuf (STREAM * peer, u_int streambuf_size = ACE_STREAMBUF_SIZE, int io_mode = ios::in | ios::out);
- // 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.
-
- virtual ssize_t send ( char * buf, ssize_t len )
- {
- return peer_->send_n(buf,len);
- }
- virtual ssize_t recv ( char * buf, ssize_t len, ACE_Time_Value * tv = NULL )
- {
- return this->recv( buf, len, 0, tv );
- }
- virtual ssize_t recv ( char * buf, ssize_t len, int flags, ACE_Time_Value * tv = NULL )
- {
- ssize_t rval = peer_->recv(buf,len,flags,tv);
- return rval;
- }
- virtual ssize_t recv_n( char * buf, ssize_t len, int flags = 0, ACE_Time_Value * tv = NULL )
- {
- ssize_t rval = peer_->recv_n(buf,len,flags,tv);
- return rval;
- }
-
-protected:
- STREAM * peer_;
- // This will be our ACE_SOCK_Stream or similar object.
-
- virtual ACE_HANDLE get_handle(void)
- {
- return peer_ ? peer_->get_handle() : 0 ;
- }
-};
-
-///////////////////////////////////////////////////////////////////////////
-
// These typedefs are provided by G++ (on some systems?) without the
// trailing '_'. Since we can't count on 'em, I've defined them to
// what GNU wants here.
@@ -478,210 +438,9 @@ typedef ostream& (*__omanip_)(ostream&);
///////////////////////////////////////////////////////////////////////////
-template <class STREAM>
-class ACE_IOStream : public iostream, public STREAM
- // = TITLE
- // 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.
- //
- // = DESCRIPTION
- // We inherit all characteristics of iostream and your <STREAM>
- // class. When you create a new class from this template, you
- // can use it anywhere you would have used your original
- // <STREAM> class.
- //
- // To create an iostream for your favorite ACE IPC class (e.g.,
- // <ACE_SOCK_Stream>), feed that class to this template's
- // <STREAM> parameter, e.g.,
- //
- // typedef ACE_Svc_Handler<ACE_SOCK_iostream,
- // ACE_INET_Addr, ACE_NULL_SYNCH>
- // 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.
-{
-public:
- ACE_IOStream (STREAM & stream, u_int streambuf_size = ACE_STREAMBUF_SIZE);
- ACE_IOStream (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.
-
- virtual ~ACE_IOStream (void);
- // We have to get rid of the streambuf_ ourselves since we gave it
- // to iostream();
-
- virtual int close (void);
- // The only ambituity in the multiple inheritance is the close()
- // function.
-
-#if defined (ACE_HAS_STRING_CLASS)
- virtual ACE_IOStream<STREAM> & operator>>(ACE_IOStream_String & v);
- // A simple string operator. The base iostream has 'em for char*
- // but that isn't always the best thing for a String. If we don't
- // provide our own here, we may not get what we want.
-
- virtual ACE_IOStream<STREAM> & operator<<(ACE_IOStream_String & v);
- // The converse of the String put operator.
-
- virtual ACE_IOStream<STREAM> & operator>>(QuotedString &v);
- // A more clever operator that handles quoted strings so that we
- // can get strings containing whitespace!
-
- virtual ACE_IOStream<STREAM> & operator<<(QuotedString &v);
- // The converse of the QuotedString put operator.
-#endif /* ACE_HAS_STRING_CLASS */
-
- // = Using the macros to provide get/set operators.
- GETPUT_FUNC_SET (ACE_IOStream<STREAM>)
-
-#if defined (ACE_LACKS_IOSTREAM_FX)
- virtual int ipfx (int need = 0) { return good(); }
- virtual int ipfx0(void) { return good(); } // Optimized ipfx(0)
- virtual int ipfx1(void) { return good(); } // Optimized ipfx(1)
- virtual void isfx (void) { return; }
- virtual int opfx (void) { return good(); }
- virtual void osfx (void) { put(' '); return; }
-#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
- virtual int ipfx (int need = 0) { return(iostream::ipfx(need)); }
- virtual void isfx (void) { iostream::isfx(); return; }
- virtual int opfx (void) { return(iostream::opfx()); }
- virtual void osfx (void) { iostream::osfx(); return; }
-#endif /* ACE_LACKS_IOSTREAM_FX */
-
- ACE_IOStream<STREAM> & operator>>(ACE_Time_Value *&tv);
- // Allow the programmer to provide a timeout for read operations.
- // Give it a pointer to NULL to block forever.
-
-protected:
-
- ACE_Streambuf<STREAM> *streambuf_;
- // This is where all of the action takes place. The
- // streambuf_ is the interface to the underlying STREAM.
-
-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 (...);
- ssize_t recv (...);
- ssize_t send_n (...);
- ssize_t recv_n (...);
-};
-
-///////////////////////////////////////////////////////////////////////////
-
-template <class STREAM>
-class ACE_SOCK_Dgram_SC : public STREAM
-// 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. BTW: 'Dgram_SC' is short for 'Datagram-Self-Contained'.
-// 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.
-{
-protected:
- ACE_INET_Addr peer_;
+// Include the templates here.
+#include "ace/IOStream_T.h"
-public:
- ACE_SOCK_Dgram_SC (void)
- {
- }
-
- ACE_SOCK_Dgram_SC (STREAM &source, ACE_INET_Addr &dest)
- : STREAM (source), peer_ (dest)
- {
- }
-
- inline ssize_t send_n (char *buf, ssize_t len)
- {
- return STREAM::send (buf, len, peer_);
- }
-
- inline ssize_t recv (char * buf, ssize_t len, ACE_Time_Value * tv = NULL)
- {
- return recv (buf, len, 0, tv);
- }
-
- inline ssize_t recv (char * buf, ssize_t len, int flags, ACE_Time_Value * tv = NULL)
- {
- if (tv != 0)
- {
- ACE_HANDLE handle = this->get_handle ();
- ACE_Handle_Set handle_set;
-
- handle_set.set_bit (handle);
-
- switch (ACE_OS::select (int (handle) + 1,
- (fd_set *) handle_set, // read_fds.
- (fd_set *) 0, // write_fds.
- (fd_set *) 0, // exception_fds.
- tv))
- {
- case 0:
- errno = ETIME;
- case -1:
- return -1;
- default:
- ; // Do the 'recv' below
- }
- }
-
- int rval = STREAM::recv (buf, len, peer_, flags);
-#ifdef WIN32
- if (rval == SOCKET_ERROR)
- if (WSAGetLastError() == WSAEMSGSIZE)
- if (flags & MSG_PEEK)
- rval = len;
-#endif
-
- return rval < len ? rval : len;
- }
- inline ssize_t recv_n (char * buf,
- ssize_t len, int flags = 0,
- ACE_Time_Value * tv = NULL)
- {
- int rval = this->recv (buf, len, flags, tv);
- return rval;
- }
-
- inline int get_remote_addr (ACE_INET_Addr &addr) const
- {
- addr = peer_;
- return 0;
- }
-
-};
-
-#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
-# if ! defined( ACE_IOSTREAM_C )
-# define ACE_IOSTREAM_BUILDING_TEMPLATE
-# endif
-# include "ace/IOStream.cpp"
-#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+#endif /* !ACE_LACKS_ACE_IOSTREAM */
#endif /* ACE_IOSTREAM_H */
-
diff --git a/ace/IOStream_T.cpp b/ace/IOStream_T.cpp
new file mode 100644
index 00000000000..003ced1dbb5
--- /dev/null
+++ b/ace/IOStream_T.cpp
@@ -0,0 +1,189 @@
+// IOStream.cpp
+// $Id$
+
+#if !defined (ACE_IOSTREAM_T_C)
+#define ACE_IOSTREAM_T_C
+
+#define ACE_BUILD_DLL
+#include "ace/IOStream_T.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+
+// We will be given a STREAM by the iostream object which creates us.
+// See the ACE_IOStream_T template for how that works. Like other
+// streambuf objects, we can be input-only, output-only or both.
+
+template <class STREAM>
+ACE_Streambuf_T<STREAM>::ACE_Streambuf_T (STREAM *peer, u_int streambuf_size, int io_mode)
+ : ACE_Streambuf (streambuf_size, io_mode), peer_ (peer)
+{
+ // A streambuf allows for unbuffered IO where every character is
+ // read as requested and written as provided. To me, this seems
+ // terribly inefficient for socket-type operations, so I've disabled
+ // it. All of the work would be done by the underflow/overflow
+ // functions anyway and I haven't implemented anything there to
+ // support unbuffered IO.
+
+ this->unbuffered (0);
+
+ // Linebuffered is similar to unbuffered. Again, I don't have any
+ // need for this and I don't see the advantage. I believe this
+ // would have to be supported by underflow/overflow to be effective.
+#if !defined (ACE_LACKS_LINEBUFFERED_STREAMBUF)
+ this->linebuffered (0);
+#endif /* ! ACE_LACKS_LINEBUFFERED_STREAMBUF */
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+// The typical constructor. This will initiailze your STREAM and then
+// setup the iostream baseclass to use a custom streambuf based on
+// STREAM.
+
+template <class STREAM>
+ACE_IOStream_T<STREAM>::ACE_IOStream_T (STREAM & stream, u_int streambuf_size)
+ : iostream (streambuf_ = new ACE_Streambuf_T<STREAM> ((STREAM *) this, streambuf_size)),
+ STREAM (stream)
+{
+ iostream::init (this->streambuf_);
+}
+
+template <class STREAM>
+ACE_IOStream_T<STREAM>::ACE_IOStream_T (u_int streambuf_size)
+ : iostream (streambuf_ = new ACE_Streambuf_T<STREAM> ((STREAM *) this, streambuf_size))
+{
+ iostream::init (this->streambuf_);
+}
+
+// We have to get rid of the streambuf_ ourselves since we gave it to
+// iostream ()
+
+template <class STREAM>
+ACE_IOStream_T<STREAM>::~ACE_IOStream_T (void)
+{
+ delete this->streambuf_;
+}
+
+// The only ambituity in the multiple inheritance is the close ()
+// function.
+
+template <class STREAM> int
+ACE_IOStream_T<STREAM>::close (void)
+{
+ return STREAM::close ();
+}
+
+template <class STREAM> ACE_IOStream_T<STREAM> &
+ACE_IOStream_T<STREAM>::operator>> (ACE_Time_Value *& tv)
+{
+ ACE_Time_Value * old_tv = this->streambuf_->recv_timeout (tv);
+ tv = old_tv;
+ return *this;
+}
+
+#if defined (ACE_HAS_STRING_CLASS)
+
+// A simple string operator. The base iostream has 'em for char* but
+// that isn't always the best thing for a String. If we don't provide
+// our own here, we may not get what we want.
+
+template <class STREAM> ACE_IOStream_T<STREAM> &
+ACE_IOStream_T<STREAM>::operator>> (ACE_IOStream_String & v)
+{
+ if (ipfx0 ())
+ {
+ char c;
+ iostream::operator>> (c);
+
+ for (v = c ; this->get (c) && !isspace (c) ; v += c)
+ continue;
+ }
+
+ isfx ();
+
+ return *this;
+}
+
+
+template <class STREAM> ACE_IOStream_T<STREAM> &
+ACE_IOStream_T<STREAM>::operator<< (ACE_IOStream_String & v)
+{
+ if (opfx ())
+ {
+#if defined (ACE_WIN32)
+ for (int i = 0 ; i < v.GetLength () ; ++i)
+#else
+ for (u_int i = 0 ; i < (u_int) v.length () ; ++i)
+#endif
+ this->put (v[i]);
+ }
+
+ osfx ();
+
+ return *this;
+}
+
+
+//////////////////////////////////////////////////////////////////
+// A more clever put operator for strings that knows how to
+// deal with quoted strings containing back-quoted quotes.
+//
+template <class STREAM> ACE_IOStream_T<STREAM> &
+ACE_IOStream_T<STREAM>::operator>> (QuotedString & str)
+{
+ if (ipfx0 ())
+ {
+ char c;
+
+ if (! (*this >> c)) // eat space up to the first char
+ // this->set (ios::eofbit|ios::failbit);
+ return *this;
+
+ str = ""; // Initialize the string
+
+ // if we don't have a quote, append until we see space
+ if (c != '"')
+ for (str = c ; this->get (c) && !isspace (c) ; str += c)
+ continue;
+ else
+ for (; this->get (c) && c != '"' ; str += c)
+ if (c == '\\')
+ {
+ this->get (c);
+ if (c != '"')
+ str += '\\';
+ }
+ }
+
+ isfx ();
+
+ return *this;
+}
+
+template <class STREAM> ACE_IOStream_T<STREAM> &
+ACE_IOStream_T<STREAM>::operator<< (QuotedString & str)
+{
+ if (opfx ())
+ {
+ this->put ('"');
+ for (u_int i = 0 ; i < str.length () ; ++i)
+ {
+ if (str[i] == '"')
+ this->put ('\\');
+ this->put (str[i]);
+ }
+ this->put ('"');
+ }
+
+ osfx ();
+
+ return *this;
+}
+
+#endif /* ACE_HAS_STRING_CLASS */
+#endif /* ACE_IOSTREAM_T_C */
+
diff --git a/ace/IOStream_T.h b/ace/IOStream_T.h
new file mode 100644
index 00000000000..51e74447d70
--- /dev/null
+++ b/ace/IOStream_T.h
@@ -0,0 +1,280 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// IOStream_T.h
+//
+// = AUTHOR
+// James CE Johnson <jcej@lads.com>
+//
+// = COAUTHOR
+// Jim Crossley <jim@lads.com>
+//
+// = NOTE
+// 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.
+//
+// ============================================================================
+
+#if !defined (ACE_IOSTREAM_T_H)
+#define ACE_IOSTREAM_T_H
+
+#include "ace/IOStream.h"
+#include <iomanip.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class STREAM>
+class ACE_Streambuf_T : public ACE_Streambuf
+{
+public:
+ ACE_Streambuf_T (STREAM * peer, u_int streambuf_size = ACE_STREAMBUF_SIZE, int io_mode = ios::in | ios::out);
+ // We will be given a STREAM by the iostream object which creates
+ // us. See the ACE_IOStream_T template for how that works. Like
+ // other streambuf objects, we can be input-only, output-only or
+ // both.
+
+ virtual ssize_t send ( char * buf, ssize_t len )
+ {
+ return peer_->send_n(buf,len);
+ }
+ virtual ssize_t recv ( char * buf, ssize_t len, ACE_Time_Value * tv = NULL )
+ {
+ return this->recv( buf, len, 0, tv );
+ }
+ virtual ssize_t recv ( char * buf, ssize_t len, int flags, ACE_Time_Value * tv = NULL )
+ {
+ ssize_t rval = peer_->recv(buf,len,flags,tv);
+ return rval;
+ }
+ virtual ssize_t recv_n( char * buf, ssize_t len, int flags = 0, ACE_Time_Value * tv = NULL )
+ {
+ ssize_t rval = peer_->recv_n(buf,len,flags,tv);
+ return rval;
+ }
+
+protected:
+ STREAM * peer_;
+ // This will be our ACE_SOCK_Stream or similar object.
+
+ virtual ACE_HANDLE get_handle(void)
+ {
+ return peer_ ? peer_->get_handle() : 0 ;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class STREAM>
+class ACE_IOStream_T : public iostream, public STREAM
+ // = TITLE
+ // 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.
+ //
+ // = DESCRIPTION
+ // We inherit all characteristics of iostream and your <STREAM>
+ // class. When you create a new class from this template, you
+ // can use it anywhere you would have used your original
+ // <STREAM> class.
+ //
+ // To create an iostream for your favorite ACE IPC class (e.g.,
+ // <ACE_SOCK_Stream>), feed that class to this template's
+ // <STREAM> parameter, e.g.,
+ //
+ // typedef ACE_Svc_Handler<ACE_SOCK_iostream,
+ // ACE_INET_Addr, ACE_NULL_SYNCH>
+ // Service_Handler;
+ //
+ // Because the operators in the iostream class are not virtual,
+ // you cannot easily provide overloads in your custom
+ // ACE_IOStream_T classes. To make these things work correctly,
+ // you need to overload ALL operators of the ACE_IOStream_T 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.
+{
+public:
+ ACE_IOStream_T (STREAM & stream, u_int streambuf_size = ACE_STREAMBUF_SIZE);
+ ACE_IOStream_T (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.
+
+ virtual ~ACE_IOStream_T (void);
+ // We have to get rid of the streambuf_ ourselves since we gave it
+ // to iostream();
+
+ virtual int close (void);
+ // The only ambituity in the multiple inheritance is the close()
+ // function.
+
+#if defined (ACE_HAS_STRING_CLASS)
+ virtual ACE_IOStream_T<STREAM> & operator>>(ACE_IOStream_String & v);
+ // A simple string operator. The base iostream has 'em for char*
+ // but that isn't always the best thing for a String. If we don't
+ // provide our own here, we may not get what we want.
+
+ virtual ACE_IOStream_T<STREAM> & operator<<(ACE_IOStream_String & v);
+ // The converse of the String put operator.
+
+ virtual ACE_IOStream_T<STREAM> & operator>>(QuotedString &v);
+ // A more clever operator that handles quoted strings so that we
+ // can get strings containing whitespace!
+
+ virtual ACE_IOStream_T<STREAM> & operator<<(QuotedString &v);
+ // The converse of the QuotedString put operator.
+#endif /* ACE_HAS_STRING_CLASS */
+
+ // = Using the macros to provide get/set operators.
+ GETPUT_FUNC_SET (ACE_IOStream_T<STREAM>)
+
+#if defined (ACE_LACKS_IOSTREAM_FX)
+ virtual int ipfx (int need = 0) { return good(); }
+ virtual int ipfx0(void) { return good(); } // Optimized ipfx(0)
+ virtual int ipfx1(void) { return good(); } // Optimized ipfx(1)
+ virtual void isfx (void) { return; }
+ virtual int opfx (void) { return good(); }
+ virtual void osfx (void) { put(' '); return; }
+#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
+ virtual int ipfx (int need = 0) { return(iostream::ipfx(need)); }
+ virtual void isfx (void) { iostream::isfx(); return; }
+ virtual int opfx (void) { return(iostream::opfx()); }
+ virtual void osfx (void) { iostream::osfx(); return; }
+#endif /* ACE_LACKS_IOSTREAM_FX */
+
+ ACE_IOStream_T<STREAM> & operator>>(ACE_Time_Value *&tv);
+ // Allow the programmer to provide a timeout for read operations.
+ // Give it a pointer to NULL to block forever.
+
+protected:
+
+ ACE_Streambuf_T<STREAM> *streambuf_;
+ // This is where all of the action takes place. The
+ // streambuf_ is the interface to the underlying STREAM.
+
+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 (...);
+ ssize_t recv (...);
+ ssize_t send_n (...);
+ ssize_t recv_n (...);
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+template <class STREAM>
+class ACE_SOCK_Dgram_SC : public STREAM
+// 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. BTW: 'Dgram_SC' is short for 'Datagram-Self-Contained'.
+// 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.
+{
+protected:
+ ACE_INET_Addr peer_;
+
+public:
+ ACE_SOCK_Dgram_SC (void)
+ {
+ }
+
+ ACE_SOCK_Dgram_SC (STREAM &source, ACE_INET_Addr &dest)
+ : STREAM (source), peer_ (dest)
+ {
+ }
+
+ inline ssize_t send_n (char *buf, ssize_t len)
+ {
+ return STREAM::send (buf, len, peer_);
+ }
+
+ inline ssize_t recv (char * buf, ssize_t len, ACE_Time_Value * tv = NULL)
+ {
+ return recv (buf, len, 0, tv);
+ }
+
+ inline ssize_t recv (char * buf, ssize_t len, int flags, ACE_Time_Value * tv = NULL)
+ {
+ if (tv != 0)
+ {
+ ACE_HANDLE handle = this->get_handle ();
+ ACE_Handle_Set handle_set;
+
+ handle_set.set_bit (handle);
+
+ switch (ACE_OS::select (int (handle) + 1,
+ (fd_set *) handle_set, // read_fds.
+ (fd_set *) 0, // write_fds.
+ (fd_set *) 0, // exception_fds.
+ tv))
+ {
+ case 0:
+ errno = ETIME;
+ case -1:
+ return -1;
+ default:
+ ; // Do the 'recv' below
+ }
+ }
+
+ int rval = STREAM::recv (buf, len, peer_, flags);
+#ifdef WIN32
+ if (rval == SOCKET_ERROR)
+ if (WSAGetLastError() == WSAEMSGSIZE)
+ if (flags & MSG_PEEK)
+ rval = len;
+#endif
+
+ return rval < len ? rval : len;
+ }
+ inline ssize_t recv_n (char * buf,
+ ssize_t len, int flags = 0,
+ ACE_Time_Value * tv = NULL)
+ {
+ int rval = this->recv (buf, len, flags, tv);
+ return rval;
+ }
+
+ inline int get_remote_addr (ACE_INET_Addr &addr) const
+ {
+ addr = peer_;
+ return 0;
+ }
+
+};
+
+#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_IOSTREAM_T_H */
diff --git a/ace/README b/ace/README
index ccca38a3464..129abaedc40 100644
--- a/ace/README
+++ b/ace/README
@@ -162,6 +162,7 @@ ACE_HAS_XLI Platform has the XLI version of TLI
ACE_HAS_XT Platform has Xt and Motif
ACE_HAS_YIELD_VOID_PTR Platform requires pthread_yield() to take a NULL.
ACE_LACKS_ACCESS Platform lacks access() (e.g., VxWorks and Chorus)
+ACE_LACKS_ACE_IOSTREAM Platform can not build ace/IOStream{,_T}.cpp. This does not necessarily mean that the platform does not support iostreams.
ACE_LACKS_CONST_STRBUF_PTR Platform uses struct strbuf * rather than const struct strbuf * (e.g., HP/UX 10.x)
ACE_LACKS_CONST_TIMESPEC_PTR Platform forgot const in cond_timewait (e.g., HP/UX).
ACE_LACKS_COND_T Platform lacks condition variables (e.g., Win32 and VxWorks)