summaryrefslogtreecommitdiff
path: root/ace/IOStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/IOStream.cpp')
-rw-r--r--ace/IOStream.cpp586
1 files changed, 0 insertions, 586 deletions
diff --git a/ace/IOStream.cpp b/ace/IOStream.cpp
deleted file mode 100644
index e9e8384b917..00000000000
--- a/ace/IOStream.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-// IOStream.cpp
-// $Id$
-#if !defined (ACE_IOSTREAM_C)
-#define ACE_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 (base (), ebuf ());
-
- // 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)
-{
- // pptr() is one character beyond the last character put
- // into the buffer. pbase() points to the beginning of
- // the put buffer. Unless pptr() is greater than pbase()
- // there is nothing to be sent to the peer_.
- //
- if( pptr() <= pbase() )
- return 0;
-
- // Starting at the beginning of the buffer, send as much
- // data as there is waiting. send_n guarantees that all
- // of the data will be sent or an error will be returned.
- //
- if( peer_->send_n( pbase(), pptr() - pbase() ) == -1 )
- return EOF;
-
- // Now that we've sent everything in the output buffer, we reset the
- // buffer pointers to appear empty.
- //
- setp (base (), ebuf ());
-
- 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),
- get_mode_ (1),
- put_mode_ (2),
- 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.
-#if !defined (ACE_LACKS_LINEBUFFERED_STREAMBUF)
- this->linebuffered (0);
-#endif /* ! ACE_LACKS_LINEBUFFERED_STREAMBUF */
-
- // 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 STREAM::close ();
-}
-
-#if defined (__GNUC__) && !defined (CHORUS)
-// 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 */