summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1997-02-05 05:01:13 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1997-02-05 05:01:13 +0000
commite589686a7e0687a5713b8495c74e83a9752e57c4 (patch)
treee502ccaf24f415d15f301840b4d384145a93d2cb /ace
parentf18e114a04aa1dc6412b16aae0d59141d9c863db (diff)
downloadATCD-e589686a7e0687a5713b8495c74e83a9752e57c4.tar.gz
foo
Diffstat (limited to 'ace')
-rw-r--r--ace/Hash_Map_Manager.cpp6
-rw-r--r--ace/IOStream.cpp586
-rw-r--r--ace/IOStream.h343
-rw-r--r--ace/LSOCK.cpp4
-rw-r--r--ace/LSOCK_Stream.cpp20
-rw-r--r--ace/Malloc.i38
-rw-r--r--ace/Message_Block.cpp1
-rw-r--r--ace/OS.cpp10
-rw-r--r--ace/OS.i13
-rw-r--r--ace/README1
-rw-r--r--ace/SOCK_Dgram.cpp12
-rw-r--r--ace/TTY_IO.cpp2
-rw-r--r--ace/config-dgux-4.11-epc.h3
-rw-r--r--ace/config-unixware-2.01-g++.h1
-rw-r--r--ace/config-vxworks-ghs-1.8.h1
-rw-r--r--ace/config-vxworks5.2-g++.h1
16 files changed, 994 insertions, 48 deletions
diff --git a/ace/Hash_Map_Manager.cpp b/ace/Hash_Map_Manager.cpp
index 14de0442321..5e9eb59279e 100644
--- a/ace/Hash_Map_Manager.cpp
+++ b/ace/Hash_Map_Manager.cpp
@@ -191,8 +191,6 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::bind_i (const EXT_ID &ext_id,
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc];
- assert (temp != 0);
-
for (this->sentinel_->ext_id_ = ext_id;
temp->ext_id_ != ext_id;
temp = temp->next_)
@@ -233,8 +231,6 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::trybind_i (const EXT_ID &ext_id,
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc];
- assert (temp != 0);
-
for (this->sentinel_->ext_id_ = ext_id;
temp->ext_id_ != ext_id;
temp = temp->next_)
@@ -334,8 +330,6 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_find (const EXT_ID &ext_id,
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc];
- assert (temp != 0);
-
for (this->sentinel_->ext_id_ = ext_id;
temp->ext_id_ != ext_id;
temp = temp->next_)
diff --git a/ace/IOStream.cpp b/ace/IOStream.cpp
new file mode 100644
index 00000000000..69b50bb36de
--- /dev/null
+++ b/ace/IOStream.cpp
@@ -0,0 +1,586 @@
+// IOStream.cpp
+// $Id$
+#if !defined (ACE_IOSTREAM_C)
+#define ACE_MAP_IOSTREAM_C
+
+#define ACE_BUILD_DLL
+#include "ace/IOStream.h"
+
+/* Here's a simple example of how iostream's non-virtual operators can
+ get you in a mess:
+
+
+ class myiostream : public iostream
+ {
+ public:
+ myiostream& operator>>(String & s)
+ {
+ ...
+ }
+ };
+
+ ...
+
+ int i;
+ String s;
+ myiostream foo(...);
+
+ foo >> s;
+ // OK
+ // invokes myiostream::operator>>(String&) returning myiostream&
+
+ foo >> i;
+ // OK
+ // invokes iostream::operator>>(int&) returning iostream&
+
+ foo >> i >> s;
+ // BAD
+ // 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
+ // gets invoked on iostream. Probably NOT what you wanted!
+
+
+ // In order to make all of this work the way you want, you have to do this:
+
+ class myiostream : public iostream
+ {
+ public:
+ myiostream& operator>>(int & i)
+ {
+ return((myiostream&)iostream::operator>>(i));
+ }
+
+ myiostream& operator>>(String & s)
+ {
+ ...
+ }
+ };
+
+ ...
+
+ int i;
+ String s;
+ myiostream foo(...);
+
+ foo >> s;
+ // OK
+ // invokes myiostream::operator>>(String&) returning myiostream&
+
+ foo >> i;
+ // OK
+ // invokes myiostream::operator>>(int&) returning myiostream&
+
+
+ foo >> i >> s;
+ // OK
+ // Because you provided operator>>(int&) in class myiostream, that
+ // function will be invoked by the first >>. Since it returns
+ // a myiostream&, the second >> will be invoked as desired. */
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::underflow( void )
+{
+ // If input mode is not set, any attempt to read from the stream is
+ // a failure.
+
+ if (!(mode_ & ios::in))
+ return EOF;
+
+ // If base () is empty then this is the first time any get/put
+ // operation has been attempted on the stream.
+
+ if (!this->base ())
+ {
+ // Set base () to use our private read buffer. The arguments are:
+ // beginning of the buffer (base ())
+ // one-beyond the end of the buffer (ebase ())
+ // should base () be deleted on destruction
+ //
+ // We have to say "no" to the third parameter because we want to
+ // explicitly handle deletion of the TWO buffers at destruction.
+ //
+ setb (this->eback_saved_,
+ this->eback_saved_ + ACE_STREAMBUF_SIZE, 0);
+
+ // Using the new values for base (), initialize the get area.
+ // This simply sets eback (), gptr () and egptr () described
+ // earlier.
+ setg (base (), base (), base ());
+
+ // Set the put buffer such that puts will be disabled. Any
+ // attempt to put data will now cause overflow to be invoked.
+ setp (0, 0);
+
+ // Remember that we are now in getMode. This will help us if
+ // we're called prior to a mode change as well as helping us
+ // when the mode does change.
+ this->cur_mode_ = this->get_mode_;
+ }
+ else // base () has been initialized already...
+ {
+ // If we are in put_mode_ now, then it is time to switch to get_mode_
+ //
+ // 1. get rid of any pending output
+ // 2. rearrange base () to use our half of the buffer
+ // 3. reset the mode
+ //
+ if (this->cur_mode_ == this->put_mode_)
+ {
+ // Dump any pending output to the peer. This is not
+ // really necessary because of the dual-buffer arrangement
+ // we've set up but intuitively it makes sense to send
+ // the pending data before we request data since the peer
+ // will probably need what we're sending before it can
+ // respond.
+ if (out_waiting () && syncout () == EOF)
+ return EOF;
+
+ // We're about to disable put mode but before we do that, we
+ // wan't to preserve it's state.
+ this->pbase_saved_ = pbase ();
+ this->pptr_saved_ = pptr ();
+ this->epptr_saved_ = epptr ();
+ //
+ // Disable put mode as described in the constructor.
+ //
+ setp (0, 0);
+
+ // Like the case where base () is false, we now point base()
+ // to use our private get buffer.
+
+ setb (this->eback_saved_,
+ this->eback_saved_ + ACE_STREAMBUF_SIZE, 0);
+
+ // And restore the previous state of the get pointers.
+
+ setg (this->eback_saved_, this->gptr_saved_,
+ this->egptr_saved_);
+
+ // Finally, set our mode so that we don't get back into this
+ // if () and so that overflow can operate correctly.
+ cur_mode_ = get_mode_;
+ }
+
+ // There could be data in the input buffer if we switched to put
+ // mode before reading everything. In that case, we take this
+ // opportunity to feed it back to the iostream.
+ if (in_avail ())
+ // Remember that we return an int so that we can give
+ // back EOF. The explicit cast prevents us from
+ // returning a signed char when we're not returning EOF.
+ return (u_char) *gptr ();
+ }
+
+ // We really shouldn't be here unless there is a lack of data in the
+ // read buffer. So... go get some more data from the peer.
+
+ int result = fillbuf ();
+
+ // fillbuf will give us EOF if there was an error with the peer. In
+ // that case, we can do no more input.
+
+ if (EOF == result)
+ {
+ // Disable ourselves and return failure to the iostream. That
+ // should result in a call to have oursleves closed.
+ setg (0, 0, 0);
+ return EOF;
+ }
+
+ // Return the next available character in the input buffer. Again,
+ // we protect against sign extension.
+
+ return (u_char) *gptr ();
+}
+
+// Much of this is similar to underflow. I'll just hit the highlights
+// rather than repeating a lot of what you've already seen.
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::overflow (int c)
+{
+ // Check to see if output is allowed at all.
+ if (!(mode_ & ios::out))
+ return EOF;
+
+ // First invokation of a get or put function
+ if (!base ())
+ {
+ // Set base () to use put's private buffer.
+ //
+ setb (this->pbase_saved_,
+ this->pbase_saved_ + ACE_STREAMBUF_SIZE, 0);
+
+ // Set the put area using the new base () values.
+ setp (base (), ebuf ());
+
+ // Disable the get area.
+ setg (0, 0, 0);
+
+ // Set the mode for optimization.
+ this->cur_mode_ = this->put_mode_;
+ }
+ else // We're already reading or writting
+ {
+ // If we're coming out of get mode...
+ if (this->cur_mode_ == this->get_mode_)
+ {
+ // Save the current get mode values
+ this->eback_saved_ = eback ();
+ this->gptr_saved_ = gptr ();
+ this->egptr_saved_ = egptr ();
+
+ // then disable the get buffer
+ setg (0, 0, 0);
+
+ // Reconfigure base () and restore the put pointers.
+ setb (pbase_saved_, pbase_saved_ + ACE_STREAMBUF_SIZE, 0);
+ setp (pbase_saved_, epptr_saved_);
+
+ // Save the new mode.
+ this->cur_mode_ = this->put_mode_;
+ }
+
+ // If there is output to be flushed, do so now. We shouldn't
+ // get here unless this is the case...
+
+ if (out_waiting ()
+ && EOF == syncout ())
+ return EOF;
+ }
+
+ // If we're not putting EOF, then we have to deal with the character
+ // that is being put. Perhaps we should do something special with EOF???
+
+ if (c != EOF)
+ {
+ // We've already written any data that may have been in the
+ // buffer, so we're guaranteed to have room in the buffer for
+ // this new information. So... we add it to the buffer and
+ // adjust our 'next' pointer acordingly.
+ *pptr () = c;
+ pbump (1);
+ }
+
+ return 0;
+}
+
+// syncin
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::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
+ // do anything evil to us.
+ return 0;
+}
+
+///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// ///// /////
+
+// syncout
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::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 ()
+ // is how we do it.
+
+ if (flushbuf () == EOF)
+ return EOF;
+ else
+ return 0;
+}
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::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
+ // to do something.
+
+ syncin ();
+
+ // Don't bother syncing the output unless there is data to be sent...
+
+ if (out_waiting ())
+ return syncout ();
+
+ return 0;
+}
+
+// flushbuf
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::flushbuf (void)
+{
+ size_t n;
+ char *q;
+
+ // Get a pointer to the beginning of the output buffer
+ q = pbase ();
+
+ // and calculate the number of bytes based on the end-of-data pointer
+ // and the beginning-of-data pointer.
+ n = pptr () - q;
+
+ // Use the send_n function to ensure that everything waiting in the
+ // put area is sent to the peer.
+ ssize_t s = peer_->send_n (q, n);
+
+ // If we didn't send as many as we wanted then there is something
+ // wrong with the peer. A send_n guarantees the delivery of our
+ // data or total failure.
+ if (s < n)
+ return EOF;
+
+ // Now that we've sent everything in the output buffer, we reset the
+ // buffer pointers to appear empty.
+ setp (base (), base ());
+
+ return 0;
+}
+
+template <class STREAM>
+int ACE_Streambuf<STREAM>::get_one_byte (void)
+{
+ char * p = base ();
+ ssize_t i = peer_->recv_n (p, 1);
+
+ // 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
+ // from the peer. Later, we can use recv to see if there is
+ // anything else in the buffer. (Ok, we could use flags to tell it
+ // to block but I like this better.)
+
+ if (i != 1)
+ return EOF;
+
+ // Set the get pointers to indicate that we've got new data.
+ setg (base (), base (), base () + 1);
+
+ return 1;
+}
+
+template <class STREAM> int
+ACE_Streambuf<STREAM>::fillbuf (void)
+{
+ char *p;
+
+ // Invoke recv_n to get at least one byte from the remote. This
+ // will block until something shows up.
+
+ if (this->get_one_byte () == EOF)
+ return EOF;
+
+ // Now, get whatever else may be in the buffer. This will return if
+ // there is nothing in the buffer. Notice that we can only read
+ // blen ()-1 bytes since we've already read one via <get_one_byte>
+
+ p = base () + 1;
+ ssize_t t = peer_->recv (p, blen () - 1);
+
+ // recv will give us -1 if there was a problem. If there was
+ // nothing waiting to be read, it will give us 0. That isn't an
+ // error.
+
+ if (t++ < 0)
+ return EOF;
+
+ // Move the get pointer to reflect the number of bytes we just read.
+
+ setg (base (), base (), base () + t);
+
+ // Return the byte-read-count including the one from <get_one_byte>
+ return t;
+}
+
+// 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, int io_mode)
+ : peer_ (peer),
+ mode_ (io_mode)
+{
+ // 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.
+ this->linebuffered (0);
+
+ // The get area is where the iostrem will get data from. This is
+ // our read buffer. There are three pointers which describe the
+ // read buffer:
+ //
+ // eback () - The beginning of the buffer. Also the furthest
+ // point at which putbacks can be done. Hence the name.
+ //
+ // gptr () - Where the next character is to be got from.
+ //
+ // egptr () - One position beyond the last get-able character.
+ //
+ // So that we can switch quicky from read to write mode without
+ // any data copying, we keep copies of these three pointers in
+ // the variables below. Initially, they all point to the beginning
+ // of our read-dedicated buffer.
+ //
+ ACE_NEW (this->eback_saved_, char[ACE_STREAMBUF_SIZE]);
+ this->gptr_saved_ = this->eback_saved_;
+ this->egptr_saved_ = this->eback_saved_;
+
+ // The put area is where the iostream will put data that needs to be
+ // sent to the peer. This becomes our write buffer. The three
+ // pointers which maintain this area are:
+ //
+ // pbase () - The beginning of the put area.
+ //
+ // pptr () - Where the next character is to be put.
+ //
+ // epptr () - One beyond the last valid position for putting.
+ //
+ // Again to switch quickly between modes, we keep copies of
+ // these three pointers.
+ //
+ ACE_NEW (this->pbase_saved_, char[ACE_STREAMBUF_SIZE]);
+ this->pptr_saved_ = this->pbase_saved_;
+ this->epptr_saved_ = this->pbase_saved_ + ACE_STREAMBUF_SIZE;
+
+ // Disable the get area initially. This will cause underflow to be
+ // invoked on the first get operation.
+ setg (0, 0, 0);
+
+ // Disable the put area. Overflow will be called by the first call
+ // to any put operator.
+ setp (0, 0);
+
+ // Until we experience the first get or put operation, we do not
+ // know what our current IO mode is.
+ this->cur_mode_ = 0;
+
+ // The common area used for reading and writting is called "base".
+ // We initialize it this way so that the first get/put operation
+ // will have to "allocate" base. This allocation will set base to
+ // the appropriate specific buffer and set the mode to the correct
+ // value.
+ setb (0, 0);
+}
+
+// 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 their memory.
+
+template <class STREAM>
+ACE_Streambuf<STREAM>::~ACE_Streambuf (void)
+{
+ delete [] this->eback_saved_;
+ delete [] this->pbase_saved_;
+}
+
+// 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 (void)
+ : iostream (streambuf_ = new ACE_Streambuf<STREAM> ((STREAM *) this))
+{
+}
+
+// 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 ACE_SOCK_Stream::close ();
+}
+
+#if defined (__GNUC__)
+// 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>> (String & v)
+{
+ char c;
+ iostream::operator>> (c);
+
+ for (v = c ; this->get (c) && !isspace (c) ; v += c)
+ continue;
+
+ 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)
+{
+ 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 );
+ }
+ else
+ {
+ for( ; this->get(c) && c != '"' ; str += c )
+ {
+ if (c == '\\')
+ {
+ this->get(c);
+ if (c != '"')
+ str += '\\';
+ }
+ }
+ }
+
+ return *this;
+}
+
+template <class STREAM> ACE_IOStream<STREAM> &
+ACE_IOStream<STREAM>::operator<< (QuotedString & str)
+{
+ *this << '"';
+ *this << (String&)str;
+ *this << '"';
+ return *this;
+}
+
+#endif /* __GNUG__ */
+#endif /* ACE_IOSTREAM_C */
diff --git a/ace/IOStream.h b/ace/IOStream.h
new file mode 100644
index 00000000000..e465d69980f
--- /dev/null
+++ b/ace/IOStream.h
@@ -0,0 +1,343 @@
+
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// iostream.h
+//
+// = AUTHOR
+// James CE Johnson <jcej@lads.com>
+//
+// = COAUTHOR
+// Jim Crossley <jim@lads.com>
+//
+// ============================================================================
+
+#if !defined (ACE_IOSTREAM_H)
+#define ACE_IOSTREAM_H
+
+#include "ace/OS.h"
+
+#ifndef ACE_STREAMBUF_SIZE
+#define ACE_STREAMBUF_SIZE 1024
+#endif ACE_STREAMBUF_SIZE
+
+#if defined (__GNUC__)
+#include <String.h>
+
+class QuotedString : public String
+{
+public:
+ inline QuotedString & operator =(char c) { return((QuotedString&)String::operator=(c)); }
+ inline QuotedString & operator =(char* c) { return((QuotedString&)String::operator=(c)); }
+};
+#endif /* __GNUC__ */
+
+template <class STREAM>
+class ACE_Streambuf : public streambuf
+ // = TITLE
+ // Create your custom streambuf by providing and ACE_*_Stream
+ // object to this template. I have tested it with
+ // ACE_SOCK_Stream and it should work fine for others as well.
+ // I'm hoping to add functionality for ACE_SOCK_Dgram soon...
+ //
+ // = DESCRIPTION
+ // For any iostream object, the real work is done by the
+ // underlying streambuf class. That is what we create here.
+ //
+ // A streambuf has an internal buffer area into which data is
+ // read and written as the iostream requests and provides data.
+ // At some point during the read process, the iostream will
+ // realize that the streambuf has no more data. The underflow
+ // function of the streambuf is then called.
+ //
+ // Likewise, during the write process, the iostream will
+ // eventually notice that the streabuf's buffer has become full
+ // and will invoke the overflow function.
+ //
+ // The empty/full state of the read/write "buffers" are
+ // controled by two sets pointers. One set is dedicated to
+ // read, the other to write. These pointers, in turn, reference
+ // a common buffer that is to be shared by both read and write
+ // operations. It is this common buffer to which data is
+ // written and from which it is read.
+ //
+ // The common buffer is used by functions of the streambuf as
+ // well as the iostream. Because of this and the fact that it
+ // is "shared" by both read and write operators, there is a
+ // danger of data corruption if read and write operations are
+ // allowed to take place "at the same time".
+ //
+ // To prevent data corruption, we manipulate the read and write
+ // pointer sets so that the streambuf is in either a read-mode
+ // or write-mode at all times and can never be in both modes at
+ // the same time.
+ //
+ // In the constructor: set the read and write sets to NULL This
+ // causes the underflow or overflow operators to be invoked at
+ // the first IO activity of the iostream.
+ //
+ // In the underflow function we arrange for the common buffer to
+ // reference our read buffer and for the write pointer set to be
+ // disabled. If a write operation is performed by the iostream
+ // this will cause the overflow function to be invoked.
+ //
+ // In the overflow function we arrange for the common buffer to
+ // reference our write buffer and for the read pointer set to be
+ // disabled. This causes the underflow function to be invoked
+ // when the iostream "changes our mode".
+ //
+ // The overflow function will also invoke the send_n function to
+ // flush the buffered data to our peer. Similarly, the sync and
+ // syncout functions will cause send_n to be invoked to send the
+ // data.
+ //
+ // Since socket's and the like do not support seeking, there can
+ // be no method for "syncing" the input. However, since we
+ // maintain separate read/write buffers, no data is lost by
+ // "syncing" the input. It simply remains buffered.
+{
+public:
+ ACE_Streambuf (STREAM * peer, 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 ~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
+ // their memory.
+
+protected:
+ virtual int sync (void);
+ // Sync both input and output. See syncin/syncout below for
+ // descriptions.
+
+ // = Signatures for the underflow/overflow discussed above.
+ virtual int underflow (void);
+
+ virtual int overflow (int = EOF);
+ // The overflow function receives the character which caused the
+ // overflow.
+
+private:
+ STREAM *peer_;
+ // This will be our ACE_SOCK_Stream or similar object.
+
+ // = Two pointer sets for manipulating the read/write areas.
+ char *eback_saved_;
+ char *gptr_saved_;
+ char *egptr_saved_;
+ char *pbase_saved_;
+ char *pptr_saved_;
+ char *epptr_saved_;
+
+ // = With cur_mode_ we keep track of our current IO mode.
+
+ // This helps us to optimize the underflow/overflow functions.
+ u_char cur_mode_;
+ const u_char get_mode_ = 1;
+ const u_char put_mode_ = 2;
+
+ int mode_;
+ // mode tells us if we're working for an istream, ostream, or
+ // iostream.
+
+ int syncin (void);
+ // syncin is called when the input needs to be synced with the
+ // source file. In a filebuf, this results in the seek() system
+ // call being used. We can't do that on socket-like connections,
+ // so this does basically nothing. That's safe because we have a
+ // separate read buffer to maintain the already-read data. In a
+ // filebuf, the single common buffer is used forcing the seek()
+ // call.
+
+ int syncout (void);
+ // syncout is called when the output needs to be flushed. This is
+ // easily done by calling the peer's send_n function.
+
+ int flushbuf (void);
+ // flushbuf is the worker of syncout. It is a separate function
+ // because it gets used sometimes in different context.
+
+ int fillbuf (void);
+ // fillbuf is called in a couple of places. This is the worker of
+ // underflow. It will attempt to fill the read buffer from the
+ // peer.
+
+ int get_one_byte(void);
+ // Used by fillbuf and others to get exactly one byte from the peer.
+ // recv_n is used to be sure we block until something is available.
+};
+
+// This macro defines the get operator for class MT into datatype DT.
+// We will use it below to quickly override most (all?) iostream get
+// operators. Notice how the ipfx() and isfx() functions are used.
+
+#define ACE_OPERATORG(MT,DT) \
+ inline virtual MT& operator>>(DT v) { \
+ if(ipfx()) iostream::operator>>(v); isfx(); return(*this); \
+ };
+
+// This macro defines the put operator for class MT into datatype DT.
+// We will use it below to quickly override most (all?) iostream put
+// operators. Notice how the opfx() and osfx() functions are used.
+
+#define ACE_OPERATORP(MT,DT) \
+ inline virtual MT& operator<<(DT v) { \
+ if(opfx()) iostream::operator<<(v); osfx(); return(*this); \
+ };
+
+// These are necessary in case somebody wants to derive from us and
+// override one of these with a custom approach.
+
+#define ACE_OPERATORG_SET(MT) \
+ ACE_OPERATORG(MT,short &); \
+ ACE_OPERATORG(MT,u_short &); \
+ ACE_OPERATORG(MT,int &); \
+ ACE_OPERATORG(MT,u_int &); \
+ ACE_OPERATORG(MT,long &); \
+ ACE_OPERATORG(MT,u_long &); \
+ ACE_OPERATORG(MT,float &); \
+ ACE_OPERATORG(MT,double &); \
+ ACE_OPERATORG(MT,long double &); \
+ ACE_OPERATORG(MT,char &) \
+ ACE_OPERATORG(MT,u_char &); \
+ ACE_OPERATORG(MT,signed char &); \
+ ACE_OPERATORG(MT,char *) \
+ ACE_OPERATORG(MT,u_char *); \
+ ACE_OPERATORG(MT,signed char *); \
+ virtual MT& operator>>(__omanip func) { (*func)(*this); return *this; } \
+ virtual MT& operator>>(__manip func) { (*func)(*this); return *this; }
+
+#define ACE_OPERATORP_SET(MT) \
+ ACE_OPERATORP(MT,short); \
+ ACE_OPERATORP(MT,u_short); \
+ ACE_OPERATORP(MT,int); \
+ ACE_OPERATORP(MT,u_int); \
+ ACE_OPERATORP(MT,long); \
+ ACE_OPERATORP(MT,u_long); \
+ ACE_OPERATORP(MT,float); \
+ ACE_OPERATORP(MT,double); \
+ ACE_OPERATORP(MT,char); \
+ ACE_OPERATORP(MT,u_char); \
+ ACE_OPERATORP(MT,signed char); \
+ ACE_OPERATORP(MT,const char *); \
+ ACE_OPERATORP(MT,const u_char *); \
+ ACE_OPERATORP(MT,const signed char *); \
+ ACE_OPERATORP(MT,const void *); \
+ virtual MT& operator<<(__omanip func) { (*func)(*this); return *this; } \
+ virtual MT& operator<<(__manip func) { (*func)(*this); return *this; }
+
+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 (void);
+ // 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 (__GNUC__)
+ virtual ACE_IOStream& operator>>(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& operator>>(QuotedString &v);
+ // A more clever operator that handles quoted strings so that we
+ // can get strings containing whitespace!
+
+ virtual ACE_IOStream& operator<<(QuotedString &v);
+ // The converse of the QuotedString put operator.
+#endif /* __GNUG__ */
+
+ // = Using the macros to provide get/set operators.
+ ACE_OPERATORG_SET (ACE_IOStream);
+ ACE_OPERATORP_SET (ACE_IOStream);
+
+ // = These are handy to have around for overriding.
+
+ // The *pfx functions are called at the beginning of each get/put
+ // operator. The *sfx are called at the end. In a derivative
+ // class, I've overridden the osfx() operator such that a space will
+ // be inserted after every put operation so that my transmitted
+ // "fields" are always separated.
+
+ virtual int ipfx (int need = 0) { iostream::ipfx(need); }
+ virtual int ipfx0(void) { iostream::ipfx0(); } // Optimized ipfx(0)
+ virtual int ipfx1(void) { iostream::ipfx1(); } // Optimized ipfx(1)
+ virtual void isfx (void) { iostream::isfx(); }
+ virtual int opfx (void) { iostream::opfx(); }
+ virtual void osfx (void) { iostream::osfx(); }
+
+protected:
+ ACE_Streambuf<STREAM> *streambuf_;
+ // This is where all of the action takes place. The
+ // streambuf_ is the interface to the underlying STREAM.
+
+ // 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.
+ send;
+ recv;
+ send_n;
+ recv_n;
+};
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "IOStream.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#endif /* ACE_IOSTREAM_H */
+
+
diff --git a/ace/LSOCK.cpp b/ace/LSOCK.cpp
index add2fe3851f..ee8aa67077f 100644
--- a/ace/LSOCK.cpp
+++ b/ace/LSOCK.cpp
@@ -35,7 +35,7 @@ ACE_LSOCK::send_handle (const ACE_HANDLE fd) const
iov.iov_len = sizeof a;
send_msg.msg_iov = &iov;
send_msg.msg_iovlen = 1;
- send_msg.msg_name = (char *) 0;
+ send_msg.msg_name = 0;
send_msg.msg_namelen = 0;
send_msg.msg_accrights = (char *) &fd;
send_msg.msg_accrightslen = sizeof fd;
@@ -68,7 +68,7 @@ ACE_LSOCK::recv_handle (ACE_HANDLE &fd, char *pbuf, int *len) const
recv_msg.msg_iov = &iov;
recv_msg.msg_iovlen = 1;
- recv_msg.msg_name = (char *) 0;
+ recv_msg.msg_name = 0;
recv_msg.msg_namelen = 0;
recv_msg.msg_accrights = (char *) &fd;
recv_msg.msg_accrightslen = sizeof fd;
diff --git a/ace/LSOCK_Stream.cpp b/ace/LSOCK_Stream.cpp
index bcfe6a60d73..eb6db5d0b26 100644
--- a/ace/LSOCK_Stream.cpp
+++ b/ace/LSOCK_Stream.cpp
@@ -39,11 +39,11 @@ ACE_LSOCK_Stream::send_msg (const iovec iov[],
ACE_TRACE ("ACE_LSOCK_Stream::send_msg");
msghdr send_msg;
- send_msg.msg_iov = (iovec *) iov;
- send_msg.msg_iovlen = n;
- send_msg.msg_name = (char *) 0;
- send_msg.msg_namelen = 0;
- send_msg.msg_accrights = (char *) &fd;
+ send_msg.msg_iov = (iovec *) iov;
+ send_msg.msg_iovlen = n;
+ send_msg.msg_name = 0;
+ send_msg.msg_namelen = 0;
+ send_msg.msg_accrights = (char *) &fd;
send_msg.msg_accrightslen = sizeof fd;
return ACE_OS::sendmsg (this->ACE_SOCK_Stream::get_handle (),
@@ -61,11 +61,11 @@ ACE_LSOCK_Stream::recv_msg (iovec iov[],
ACE_TRACE ("ACE_LSOCK_Stream::recv_msg");
msghdr recv_msg;
- recv_msg.msg_iov = (iovec *) iov;
- recv_msg.msg_iovlen = n;
- recv_msg.msg_name = (char *) 0;
- recv_msg.msg_namelen = 0;
- recv_msg.msg_accrights = (char *) &fd;
+ recv_msg.msg_iov = (iovec *) iov;
+ recv_msg.msg_iovlen = n;
+ recv_msg.msg_name = 0;
+ recv_msg.msg_namelen = 0;
+ recv_msg.msg_accrights = (char *) &fd;
recv_msg.msg_accrightslen = sizeof fd;
return ACE_OS::recvmsg (this->ACE_SOCK_Stream::get_handle (),
diff --git a/ace/Malloc.i b/ace/Malloc.i
index 12ec718df4a..115f004f7c2 100644
--- a/ace/Malloc.i
+++ b/ace/Malloc.i
@@ -6,18 +6,22 @@
ACE_INLINE void *
ACE_New_Allocator::malloc (size_t nbytes)
{
- return new char[nbytes];
+ char *ptr;
+
+ ACE_NEW_RETURN (ptr, char[nbytes], 0);
+ return (void *) ptr;
}
ACE_INLINE void *
-ACE_New_Allocator::calloc (size_t nbytes, char initial_value)
+ACE_New_Allocator::calloc (size_t nbytes,
+ char initial_value)
{
- char *ptr = new char [nbytes];
-
- if (ptr != 0)
- ACE_OS::memset (ptr, initial_value, nbytes);
+ char *ptr;
+
+ ACE_NEW_RETURN (ptr, char[nbytes], 0);
- return 0;
+ ACE_OS::memset (ptr, initial_value, nbytes);
+ return (void *) ptr;
}
ACE_INLINE void
@@ -33,61 +37,61 @@ ACE_New_Allocator::remove (void)
}
ACE_INLINE int
-ACE_New_Allocator::bind (const char *name, void *pointer, int duplicates)
+ACE_New_Allocator::bind (const char *, void *, int)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::trybind (const char *name, void *&pointer)
+ACE_New_Allocator::trybind (const char *, void *&)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::find (const char *name, void *&pointer)
+ACE_New_Allocator::find (const char *, void *&)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::find (const char *name)
+ACE_New_Allocator::find (const char *)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::unbind (const char *name)
+ACE_New_Allocator::unbind (const char *)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::unbind (const char *name, void *&pointer)
+ACE_New_Allocator::unbind (const char *, void *&)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::sync (ssize_t len, int flags)
+ACE_New_Allocator::sync (ssize_t, int)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::sync (void *addr, size_t len, int flags)
+ACE_New_Allocator::sync (void *, size_t, int)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::protect (ssize_t len, int prot)
+ACE_New_Allocator::protect (ssize_t, int)
{
return -1;
}
ACE_INLINE int
-ACE_New_Allocator::protect (void *addr, size_t len, int prot)
+ACE_New_Allocator::protect (void *, size_t, int)
{
return -1;
}
diff --git a/ace/Message_Block.cpp b/ace/Message_Block.cpp
index 211492011e8..a95d4ce2501 100644
--- a/ace/Message_Block.cpp
+++ b/ace/Message_Block.cpp
@@ -3,6 +3,7 @@
#define ACE_BUILD_DLL
#include "ace/Message_Block.h"
+#include "ace/Service_Config.h"
#if !defined (__ACE_INLINE__)
#include "ace/Message_Block.i"
diff --git a/ace/OS.cpp b/ace/OS.cpp
index 5cdd0e749c0..e9df7ece983 100644
--- a/ace/OS.cpp
+++ b/ace/OS.cpp
@@ -338,22 +338,24 @@ ACE_OS::gethostbyname (const char *name)
#if defined (VXWORKS)
// not thread safe!
static hostent ret;
- static int first_addr;
+ static int first_addr = ::hostGetByName ((char *) name);
static char *hostaddr[2];
- if ((first_addr = ::hostGetByName ((char *) name)) < 0)
+ if (first_addr == -1)
return 0;
+
hostaddr[0] = (char *) &first_addr;
hostaddr[1] = 0;
- ret.h_name = (char *) name; /* might not be official: just echo input arg */
+ // might not be official: just echo input arg.
+ ret.h_name = (char *) name;
ret.h_addrtype = AF_INET;
ret.h_length = 4; // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
ret.h_addr_list = hostaddr;
return &ret;
#elif defined (ACE_HAS_NONCONST_GETBY)
- ACE_SOCKCALL_RETURN ((char *) ::gethostbyname (name), struct hostent *, 0);
+ ACE_SOCKCALL_RETURN (::gethostbyname ((char *) name), struct hostent *, 0);
#else
ACE_SOCKCALL_RETURN (::gethostbyname (name), struct hostent *, 0);
#endif /* ACE_HAS_NONCONST_GETBY */
diff --git a/ace/OS.i b/ace/OS.i
index 193006600ae..9dc44505584 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -541,8 +541,7 @@ ACE_INLINE int
ACE_OS::strcasecmp (const char *s, const char *t)
{
// ACE_TRACE ("ACE_OS::strcasecmp");
-#if defined (UNIXWARE) || defined (VXWORKS)
-
+#if defined (ACE_LACKS_STRCASECMP)
// Handles most of what the BSD version does, but does not indicate
// lexicographic ordering if the strings are unequal. Just
// indicates equal (ignoring case) by return value == 0, else not
@@ -556,13 +555,14 @@ ACE_OS::strcasecmp (const char *s, const char *t)
result = 1;
break;
}
+
++s; ++t;
}
return result; // == 0 for match, else 1
#else
return ::strcasecmp (s, t);
-#endif /* UNIXWARE || VXWORKS */
+#endif /* ACE_LACKS_STRCASECMP */
}
ACE_INLINE mode_t
@@ -2503,6 +2503,10 @@ ACE_OS::getprotobyname (const char *name)
{
#if defined (VXWORKS)
ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_NONCONST_GETBY)
+#else
+ ACE_SOCKCALL_RETURN (::getprotobyname ((char *) name),
+ struct protoent *, 0);
#else
ACE_SOCKCALL_RETURN (::getprotobyname (name),
struct protoent *, 0);
@@ -2532,6 +2536,9 @@ ACE_OS::getprotobyname_r (const char *name,
struct protoent *, 0);
#endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
#endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+#if defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::getprotobyname ((char *) name),
+ struct protoent *, 0);
#else
ACE_UNUSED_ARG(buffer);
ACE_UNUSED_ARG(result);
diff --git a/ace/README b/ace/README
index 994f04e3c1d..6983dd49176 100644
--- a/ace/README
+++ b/ace/README
@@ -168,6 +168,7 @@ ACE_LACKS_SYSV_SHMEM Platform lacks System V shared memory (e.g., Win32 and Vx
ACE_LACKS_SIGINFO_H Platform lacks the siginfo.h include file (e.g., MVS)
ACE_LACKS_SOCKETPAIR Platform lacks the socketpair() call (e.g., SCO UNIX)
ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES Compiler doesn't support static data member templates
+ACE_LACKS_STRCASECMP Compiler/platform lacks strcasecmp() (e.g., DG/UX, UNIXWARE, VXWORKS)
ACE_LACKS_STRRECVFD Platform doesn't define struct strrecvfd.
ACE_LACKS_SYSCALL Platform doesn't have syscall() prototype
ACE_LACKS_SYSV_MSQ_PROTOS Platform doesn't have prototypes for Sys V msg()* queues.
diff --git a/ace/SOCK_Dgram.cpp b/ace/SOCK_Dgram.cpp
index 3e982039052..30371c9bc26 100644
--- a/ace/SOCK_Dgram.cpp
+++ b/ace/SOCK_Dgram.cpp
@@ -120,11 +120,11 @@ ACE_SOCK_Dgram::send (const iovec iov[],
ACE_TRACE ("ACE_SOCK_Dgram::send");
msghdr send_msg;
- send_msg.msg_iov = (iovec *) iov;
- send_msg.msg_iovlen = n;
- send_msg.msg_name = (char *) addr.get_addr ();
- send_msg.msg_namelen = addr.get_size ();
- send_msg.msg_accrights = 0;
+ send_msg.msg_iov = (iovec *) iov;
+ send_msg.msg_iovlen = n;
+ send_msg.msg_name = addr.get_addr ();
+ send_msg.msg_namelen = addr.get_size ();
+ send_msg.msg_accrights = 0;
send_msg.msg_accrightslen = 0;
return ACE_OS::sendmsg (this->get_handle (), &send_msg, flags);
}
@@ -143,7 +143,7 @@ ACE_SOCK_Dgram::recv (iovec iov[],
recv_msg.msg_iov = (iovec *) iov;
recv_msg.msg_iovlen = n;
- recv_msg.msg_name = (char *) addr.get_addr ();
+ recv_msg.msg_name = addr.get_addr ();
recv_msg.msg_namelen = addr.get_size ();
recv_msg.msg_accrights = 0;
recv_msg.msg_accrightslen = 0;
diff --git a/ace/TTY_IO.cpp b/ace/TTY_IO.cpp
index 74beed31c5e..b0a2f3ec20b 100644
--- a/ace/TTY_IO.cpp
+++ b/ace/TTY_IO.cpp
@@ -96,8 +96,10 @@ ACE_TTY_IO::control (Control_Mode cmd,
strcmp((char *) arg->paritymode,"odd")==0)
c_cflag |= PARODD;
}
+#if defined (CRTSCTS)
if (arg->ctsenb) /* enable CTS/RTS protocoll */
c_cflag |= CRTSCTS;
+#endif /* CRTSCTS */
if (arg->rcvenb) /* enable receiver */
c_cflag |= CREAD;
diff --git a/ace/config-dgux-4.11-epc.h b/ace/config-dgux-4.11-epc.h
index 095af26e8cf..af1f4872866 100644
--- a/ace/config-dgux-4.11-epc.h
+++ b/ace/config-dgux-4.11-epc.h
@@ -4,6 +4,9 @@
#if !defined (ACE_CONFIG_H)
#define ACE_CONFIG_H
+// Platform lacks strcasecmp().
+#define ACE_LACKS_STRCASECMP
+
// Platform supports System V IPC (most versions of UNIX, but not Win32)
#define ACE_HAS_SYSV_IPC
diff --git a/ace/config-unixware-2.01-g++.h b/ace/config-unixware-2.01-g++.h
index 457967efabf..dfae5c8baac 100644
--- a/ace/config-unixware-2.01-g++.h
+++ b/ace/config-unixware-2.01-g++.h
@@ -8,6 +8,7 @@
// See README for what the ACE_HAS... and ACE_LACKS... macros mean
+#define ACE_LACKS_STRCASECMP
#define ACE_HAS_SIZET_SOCKET_LEN
#define ACE_HAS_AUTOMATIC_INIT_FINI
#define ACE_HAS_CPLUSPLUS_HEADERS
diff --git a/ace/config-vxworks-ghs-1.8.h b/ace/config-vxworks-ghs-1.8.h
index 3dd48ff25f8..296747938b5 100644
--- a/ace/config-vxworks-ghs-1.8.h
+++ b/ace/config-vxworks-ghs-1.8.h
@@ -7,6 +7,7 @@
#if !defined (ACE_CONFIG_H)
#define ACE_CONFIG_H
+#define ACE_LACKS_STRCASECMP
#define ACE_LACKS_COND_T
#define ACE_LACKS_RWLOCK_T
#define ACE_HAS_BROKEN_SENDMSG
diff --git a/ace/config-vxworks5.2-g++.h b/ace/config-vxworks5.2-g++.h
index e12e7a23618..8b48de3c396 100644
--- a/ace/config-vxworks5.2-g++.h
+++ b/ace/config-vxworks5.2-g++.h
@@ -7,6 +7,7 @@
#if !defined (ACE_CONFIG_H)
#define ACE_CONFIG_H
+#define ACE_LACKS_STRCASECMP
#define ACE_LACKS_SYS_NERR
#define ACE_LACKS_COND_T
#define ACE_LACKS_RWLOCK_T