1 #ifndef ACE_IOSTREAM_CPP
2 #define ACE_IOSTREAM_CPP
4 #include "ace/IOStream.h"
6 #if !defined (ACE_LACKS_ACE_IOSTREAM)
8 # include "ace/OS_NS_errno.h"
9 # include "ace/OS_Memory.h"
11 ///////////////////////////////////////////////////////////////////////////
13 /* Here's a simple example of how iostream's non-virtual operators can
16 class myiostream : public iostream
19 myiostream& operator>> (String & s)
33 // invokes myiostream::operator>> (String&) returning myiostream&
37 // invokes iostream::operator>> (int&) returning iostream&
41 // invokes iostream::operator>> (int&) then iostream::operator>> (String&)
43 // What has happened is that the first >> is invoked on the base class and returns
44 // a reference to iostream. The second >> has no idea of the ACE_IOStream and
45 // gets invoked on iostream. Probably NOT what you wanted!
48 // In order to make all of this work the way you want, you have to do this:
50 class myiostream : public iostream
53 myiostream& operator>> (int & i)
55 return ((myiostream&)iostream::operator>> (i));
58 myiostream& operator>> (String & s)
72 // invokes myiostream::operator>> (String&) returning myiostream&
76 // invokes myiostream::operator>> (int&) returning myiostream&
81 // Because you provided operator>> (int&) in class myiostream, that
82 // function will be invoked by the first >>. Since it returns
83 // a myiostream&, the second >> will be invoked as desired. */
85 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
88 ACE_Streambuf::get_handle (void)
94 ACE_Streambuf::recv_timeout (ACE_Time_Value
*tv
)
96 ACE_Time_Value
* rval
= recv_timeout_
;
99 recv_timeout_value_
= *tv
;
100 recv_timeout_
= &recv_timeout_value_
;
109 ACE_Streambuf::underflow (void)
111 // If input mode is not set, any attempt to read from the stream is
114 if (ACE_BIT_DISABLED (mode_
, ios::in
))
117 // If base () is empty then this is the first time any get/put
118 // operation has been attempted on the stream.
122 // Set base () to use our private read buffer. The arguments are:
123 // beginning of the buffer (base ())
124 // one-beyond the end of the buffer (ebase ())
125 // should base () be deleted on destruction
127 // We have to say "no" to the third parameter because we want to
128 // explicitly handle deletion of the TWO buffers at destruction.
130 setb (this->eback_saved_
,
131 this->eback_saved_
+ streambuf_size_
, 0);
133 // Remember that we are now in getMode. This will help us if
134 // we're called prior to a mode change as well as helping us
135 // when the mode does change.
136 this->cur_mode_
= this->get_mode_
;
137 // Using the new values for base (), initialize the get area.
138 // This simply sets eback (), gptr () and egptr () described
140 setg (base (), base (), base ());
142 // Set the put buffer such that puts will be disabled. Any
143 // attempt to put data will now cause overflow to be invoked.
146 else // base () has been initialized already...
148 // If we are in put_mode_ now, then it is time to switch to get_mode_
150 // 1. get rid of any pending output
151 // 2. rearrange base () to use our half of the buffer
154 if (this->cur_mode_
== this->put_mode_
)
156 // Dump any pending output to the peer. This is not really
157 // necessary because of the dual-buffer arrangement we've
158 // set up but intuitively it makes sense to send the pending
159 // data before we request data since the peer will probably
160 // need what we're sending before it can respond.
161 if (out_waiting () && syncout () == EOF
)
166 delete [] pbase_saved_
;
167 (void) reset_put_buffer();
171 // We're about to disable put mode but before we do
172 // that, we want to preserve it's state.
173 this->pbase_saved_
= pbase ();
174 this->pptr_saved_
= pptr ();
175 this->epptr_saved_
= epptr ();
178 // Disable put mode as described in the constructor.
181 // Like the case where base () is false, we now point base
182 // () to use our private get buffer.
183 setb (this->eback_saved_
,
184 this->eback_saved_
+ streambuf_size_
,
187 // And restore the previous state of the get pointers.
189 setg (this->eback_saved_
, this->gptr_saved_
,
192 // Finally, set our mode so that we don't get back into this
193 // if () and so that overflow can operate correctly.
194 cur_mode_
= get_mode_
;
197 // There could be data in the input buffer if we switched to put
198 // mode before reading everything. In that case, we take this
199 // opportunity to feed it back to the iostream.
201 // Remember that we return an int so that we can give back
202 // EOF. The explicit cast prevents us from returning a signed
203 // char when we're not returning EOF.
204 return (u_char
) *gptr ();
207 // We really shouldn't be here unless there is a lack of data in the
208 // read buffer. So... go get some more data from the peer.
210 int result
= fillbuf ();
212 // Fillbuf will give us EOF if there was an error with the peer. In
213 // that case, we can do no more input.
217 // Disable ourselves and return failure to the iostream. That
218 // should result in a call to have oursleves closed.
223 // Return the next available character in the input buffer. Again,
224 // we protect against sign extension.
226 return (u_char
) *gptr ();
229 // Much of this is similar to underflow. I'll just hit the highlights
230 // rather than repeating a lot of what you've already seen.
233 ACE_Streambuf::overflow (int c
)
235 // Check to see if output is allowed at all.
236 if (! (mode_
& ios::out
))
241 // Set base () to use put's private buffer.
243 setb (this->pbase_saved_
,
244 this->pbase_saved_
+ streambuf_size_
, 0);
246 // Set the mode for optimization.
247 this->cur_mode_
= this->put_mode_
;
248 // Set the put area using the new base () values.
249 setp (base (), ebuf ());
251 // Disable the get area.
254 else // We're already reading or writing
256 // If we're coming out of get mode...
257 if (this->cur_mode_
== this->get_mode_
)
262 /* Something has happened to cause the streambuf
263 to get rid of our get area.
264 We could probably do this a bit cleaner but
265 this method is sure to cleanup the bits and
268 delete [] eback_saved_
;
269 (void) reset_get_buffer();
273 // Save the current get mode values
274 this->eback_saved_
= eback ();
275 this->gptr_saved_
= gptr ();
276 this->egptr_saved_
= egptr ();
280 // then disable the get buffer
283 // Reconfigure base () and restore the put pointers.
284 setb (pbase_saved_
, pbase_saved_
+ streambuf_size_
, 0);
285 setp (base (), ebuf ());
287 // Save the new mode.
288 this->cur_mode_
= this->put_mode_
;
291 // If there is output to be flushed, do so now. We shouldn't
292 // get here unless this is the case...
294 if (out_waiting () && EOF
== syncout ())
298 // If we're not putting EOF, then we have to deal with the character
299 // that is being put. Perhaps we should do something special with EOF???
303 // We've already written any data that may have been in the
304 // buffer, so we're guaranteed to have room in the buffer for
305 // this new information. So... we add it to the buffer and
306 // adjust our 'next' pointer acordingly.
317 ACE_Streambuf::syncin (void)
319 // As discussed, there really isn't any way to sync input from a
320 // socket-like device. We specifially override this base-class
321 // function so that it won't do anything evil to us.
328 ACE_Streambuf::syncout (void)
330 // Unlike syncin, syncout is a doable thing. All we have to do is
331 // write whatever is in the output buffer to the peer. flushbuf ()
334 if (flushbuf () == EOF
)
341 ACE_Streambuf::sync (void)
343 // sync () is fairly traditional in that it syncs both input and
344 // output. We could have omitted the call to syncin () but someday,
345 // we may want it to do something.
349 // Don't bother syncing the output unless there is data to be
361 ACE_Streambuf::flushbuf (void)
363 // pptr () is one character beyond the last character put into the
364 // buffer. pbase () points to the beginning of the put buffer.
365 // Unless pptr () is greater than pbase () there is nothing to be
368 if (pptr () <= pbase ())
373 // If the remote side shuts down the connection, an attempt to send
374 // () to the remote will result in the message 'Broken Pipe' I think
375 // this is an OS message, I've tracked it down to the ACE_OS::write
376 // () function. That's the last one to be called before the
377 // message. I can only test this on Linux though, so I don't know
378 // how other systems will react.
380 // To get around this gracefully, I do a PEEK recv () with an
381 // immediate (nearly) timeout. recv () is much more graceful on
382 // it's failure. If we get -1 from recv () not due to timeout then
383 // we know we're SOL.
385 // Q: Is 'errno' threadsafe? Should the section below be a
389 // ACE_Time_Value to (0,1);
390 // if (this->recv (tbuf, 1, MSG_PEEK, &to) == -1)
392 // if (errno != ETIME)
394 // perror ("OOPS preparing to send to peer");
399 // The correct way to handle this is for the application to trap
400 // (and ignore?) SIGPIPE. Thanks to Amos Shapira for reminding me
403 // Starting at the beginning of the buffer, send as much data as
404 // there is waiting. send guarantees that all of the data will be
405 // sent or an error will be returned.
407 if (this->send (pbase (), pptr () - pbase ()) == -1)
410 // Now that we've sent everything in the output buffer, we reset the
411 // buffer pointers to appear empty.
412 setp (base (), ebuf ());
418 ACE_Streambuf::get_one_byte (void)
422 // The recv function will return immediately if there is no data
423 // waiting. So, we use recv_n to wait for exactly one byte to come
424 // from the peer. Later, we can use recv to see if there is
425 // anything else in the buffer. (Ok, we could use flags to tell it
426 // to block but I like this better.)
428 if (this->recv_n (base (), 1, MSG_PEEK
, this->recv_timeout_
) != 1)
438 // This will be called when the read (get) buffer has been exhausted
439 // (ie -- gptr == egptr).
442 ACE_Streambuf::fillbuf (void)
444 // Invoke recv_n to get exactly one byte from the remote. This will
445 // block until something shows up.
447 if (get_one_byte () == EOF
)
450 // Now, get whatever else may be in the buffer. This will return if
451 // there is nothing in the buffer.
453 int bc
= this->recv (base (), blen (), this->recv_timeout_
);
455 // recv will give us -1 if there was a problem. If there was
456 // nothing waiting to be read, it will give us 0. That isn't an
466 // Move the get pointer to reflect the number of bytes we just read.
468 setg (base (), base (), base () + bc
);
470 // Return the byte-read-count including the one from <get_one_byte>.
474 ACE_Streambuf::ACE_Streambuf (u_int streambuf_size
, int io_mode
)
475 : eback_saved_ (0), // to avoid Purify UMR
476 pbase_saved_ (0), // to avoid Purify UMR
480 streambuf_size_ (streambuf_size
),
483 (void)reset_get_buffer ();
484 (void)reset_put_buffer ();
488 ACE_Streambuf::streambuf_size (void)
490 return streambuf_size_
;
493 // Return the number of bytes not yet gotten. eback + get_waiting =
497 ACE_Streambuf::get_waiting (void)
499 return this->gptr_saved_
- this->eback_saved_
;
502 // Return the number of bytes in the get area (includes some already
503 // gotten); eback + get_avail = egptr.
506 ACE_Streambuf::get_avail (void)
508 return this->egptr_saved_
- this->eback_saved_
;
511 // Return the number of bytes to be 'put' onto the stream media.
512 // pbase + put_avail = pptr.
515 ACE_Streambuf::put_avail (void)
517 return this->pptr_saved_
- this->pbase_saved_
;
522 // u_int newGptr = otherStream->get_waiting ();
523 // u_int newEgptr = otherStream->get_avail ();
524 // char * newBuf = otherStream->reset_get_buffer ();
525 // char * oldgetbuf = myStream->reset_get_buffer (newBuf, otherStream->streambuf_size (), newGptr, newEgptr);
527 // 'myStream' now has the get buffer of 'otherStream' and can use it in any way.
528 // 'otherStream' now has a new, empty get buffer.
531 ACE_Streambuf::reset_get_buffer (char *newBuffer
,
532 u_int _streambuf_size
,
536 char * rval
= this->eback_saved_
;
538 // The get area is where the iostream will get data from. This is
539 // our read buffer. There are three pointers which describe the
542 // eback () - The beginning of the buffer. Also the furthest
543 // point at which putbacks can be done. Hence the name.
545 // gptr () - Where the next character is to be got from.
547 // egptr () - One position beyond the last get-able character.
549 // So that we can switch quicky from read to write mode without
550 // any data copying, we keep copies of these three pointers in
551 // the variables below. Initially, they all point to the beginning
552 // of our read-dedicated buffer.
556 if (streambuf_size_
!= _streambuf_size
)
558 this->eback_saved_
= newBuffer
;
561 ACE_NEW_RETURN (this->eback_saved_
,
562 char[streambuf_size_
],
565 this->gptr_saved_
= this->eback_saved_
+ _gptr
;
566 this->egptr_saved_
= this->eback_saved_
+ _egptr
;
568 // Disable the get area initially. This will cause underflow to be
569 // invoked on the first get operation.
579 // u_int newPptr = otherStream->put_avail ();
580 // char * newBuf = otherStream->reset_put_buffer ();
581 // char * oldputbuf = otherStream->reset_put_buffer (newBuf, otherStream->streambuf_size (), newPptr);
584 ACE_Streambuf::reset_put_buffer (char *newBuffer
,
585 u_int _streambuf_size
,
588 char *rval
= this->pbase_saved_
;
590 // The put area is where the iostream will put data that needs to be
591 // sent to the peer. This becomes our write buffer. The three
592 // pointers which maintain this area are:
594 // pbase () - The beginning of the put area.
596 // pptr () - Where the next character is to be put.
598 // epptr () - One beyond the last valid position for putting.
600 // Again to switch quickly between modes, we keep copies of
601 // these three pointers.
605 if (streambuf_size_
!= _streambuf_size
)
607 this->pbase_saved_
= newBuffer
;
610 ACE_NEW_RETURN (this->pbase_saved_
,
611 char[streambuf_size_
],
614 this->pptr_saved_
= this->pbase_saved_
+ _pptr
;
615 this->epptr_saved_
= this->pbase_saved_
+ streambuf_size_
;
617 // Disable the put area. Overflow will be called by the first call
618 // to any put operator.
627 ACE_Streambuf::reset_base (void)
629 // Until we experience the first get or put operation, we do not
630 // know what our current IO mode is.
633 // The common area used for reading and writting is called "base".
634 // We initialize it this way so that the first get/put operation
635 // will have to "allocate" base. This allocation will set base to
636 // the appropriate specific buffer and set the mode to the correct
641 // If the default allocation strategey were used the common buffer
642 // would be deleted when the object destructs. Since we are providing
643 // separate read/write buffers, it is up to us to manage their memory.
645 ACE_Streambuf::~ACE_Streambuf (void)
647 delete [] this->eback_saved_
;
648 delete [] this->pbase_saved_
;
651 u_char
ACE_Streambuf::timeout (void)
653 u_char rval
= this->timeout_
;
658 ACE_END_VERSIONED_NAMESPACE_DECL
660 #endif /* !ACE_LACKS_ACE_IOSTREAM */
661 #endif /* ACE_IOSTREAM_CPP */