Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / IOStream.cpp
blob8d282688785fb13ee64d4d8366dbff986c66eda4
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
14 get you in a mess:
16 class myiostream : public iostream
18 public:
19 myiostream& operator>> (String & s)
21 ...
25 ...
27 int i;
28 String s;
29 myiostream foo (...);
31 foo >> s;
32 // OK
33 // invokes myiostream::operator>> (String&) returning myiostream&
35 foo >> i;
36 // OK
37 // invokes iostream::operator>> (int&) returning iostream&
39 foo >> i >> s;
40 // BAD
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
52 public:
53 myiostream& operator>> (int & i)
55 return ((myiostream&)iostream::operator>> (i));
58 myiostream& operator>> (String & s)
60 ...
64 ...
66 int i;
67 String s;
68 myiostream foo (...);
70 foo >> s;
71 // OK
72 // invokes myiostream::operator>> (String&) returning myiostream&
74 foo >> i;
75 // OK
76 // invokes myiostream::operator>> (int&) returning myiostream&
79 foo >> i >> s;
80 // OK
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
87 ACE_HANDLE
88 ACE_Streambuf::get_handle ()
90 return 0;
93 ACE_Time_Value *
94 ACE_Streambuf::recv_timeout (ACE_Time_Value *tv)
96 ACE_Time_Value * rval = recv_timeout_;
97 if (tv)
99 recv_timeout_value_ = *tv;
100 recv_timeout_ = &recv_timeout_value_;
102 else
103 recv_timeout_ = 0;
105 return rval;
109 ACE_Streambuf::underflow ()
111 // If input mode is not set, any attempt to read from the stream is
112 // a failure.
114 if (ACE_BIT_DISABLED (mode_, ios::in))
115 return EOF;
117 // If base () is empty then this is the first time any get/put
118 // operation has been attempted on the stream.
120 if (!this->base ())
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
139 // earlier.
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.
144 setp (0, 0);
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
152 // 3. reset the mode
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)
162 return EOF;
164 if( ! pbase() )
166 delete [] pbase_saved_;
167 (void) reset_put_buffer();
169 else
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.
179 setp (0, 0);
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_,
190 this->egptr_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.
200 if (in_avail ())
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.
215 if (EOF == result)
217 // Disable ourselves and return failure to the iostream. That
218 // should result in a call to have oursleves closed.
219 setg (0, 0, 0);
220 return EOF;
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))
237 return EOF;
239 if (!base ())
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.
252 setg (0, 0, 0);
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_)
259 // --> JCEJ 6/6/98
260 if (! eback())
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
266 pieces.
268 delete [] eback_saved_;
269 (void) reset_get_buffer();
271 else
273 // Save the current get mode values
274 this->eback_saved_ = eback ();
275 this->gptr_saved_ = gptr ();
276 this->egptr_saved_ = egptr ();
278 // <-- JCEJ 6/6/98
280 // then disable the get buffer
281 setg (0, 0, 0);
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 ())
295 return EOF;
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???
301 if (c != 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.
307 *pptr () = (char) c;
308 pbump (1);
311 return 0;
314 // syncin
317 ACE_Streambuf::syncin ()
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.
322 return 0;
325 // syncout
328 ACE_Streambuf::syncout ()
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 ()
332 // is how we do it.
334 if (flushbuf () == EOF)
335 return EOF;
336 else
337 return 0;
341 ACE_Streambuf::sync ()
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.
347 syncin ();
349 // Don't bother syncing the output unless there is data to be
350 // sent...
352 if (out_waiting ())
353 return syncout ();
354 else
355 return 0;
358 // flushbuf
361 ACE_Streambuf::flushbuf ()
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
366 // sent to the peer.
368 if (pptr () <= pbase ())
369 return 0;
371 // 4/12/97 -- JCEJ
372 // Kludge!!!
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
386 // critical section?
388 // char tbuf[1];
389 // ACE_Time_Value to (0,1);
390 // if (this->recv (tbuf, 1, MSG_PEEK, &to) == -1)
391 // {
392 // if (errno != ETIME)
393 // {
394 // perror ("OOPS preparing to send to peer");
395 // return EOF;
396 // }
397 // }
399 // The correct way to handle this is for the application to trap
400 // (and ignore?) SIGPIPE. Thanks to Amos Shapira for reminding me
401 // of this.
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)
408 return EOF;
410 // Now that we've sent everything in the output buffer, we reset the
411 // buffer pointers to appear empty.
412 setp (base (), ebuf ());
414 return 0;
418 ACE_Streambuf::get_one_byte ()
420 this->timeout_ = 0;
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)
430 if (errno == ETIME)
431 this->timeout_ = 1;
432 return EOF;
434 else
435 return 1;
438 // This will be called when the read (get) buffer has been exhausted
439 // (ie -- gptr == egptr).
442 ACE_Streambuf::fillbuf ()
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)
448 return 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
457 // error.
459 if (bc < 0)
461 if (errno == ETIME)
462 this->timeout_ = 1;
463 return EOF;
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>.
471 return bc;
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
477 get_mode_ (1),
478 put_mode_ (2),
479 mode_ (io_mode),
480 streambuf_size_ (streambuf_size),
481 recv_timeout_ (0)
483 (void)reset_get_buffer ();
484 (void)reset_put_buffer ();
487 u_int
488 ACE_Streambuf::streambuf_size ()
490 return streambuf_size_;
493 // Return the number of bytes not yet gotten. eback + get_waiting =
494 // gptr.
496 u_int
497 ACE_Streambuf::get_waiting ()
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.
505 u_int
506 ACE_Streambuf::get_avail ()
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.
514 u_int
515 ACE_Streambuf::put_avail ()
517 return this->pptr_saved_ - this->pbase_saved_;
520 // Typical usage:
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.
530 char *
531 ACE_Streambuf::reset_get_buffer (char *newBuffer,
532 u_int _streambuf_size,
533 u_int _gptr,
534 u_int _egptr)
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
540 // read buffer:
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.
554 if (newBuffer)
556 if (streambuf_size_ != _streambuf_size)
557 return 0;
558 this->eback_saved_ = newBuffer;
560 else
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.
570 setg (0, 0, 0);
572 reset_base ();
574 return rval;
577 // Typical usage:
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);
583 char *
584 ACE_Streambuf::reset_put_buffer (char *newBuffer,
585 u_int _streambuf_size,
586 u_int _pptr)
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.
603 if (newBuffer)
605 if (streambuf_size_ != _streambuf_size)
606 return 0;
607 this->pbase_saved_ = newBuffer;
609 else
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.
619 setp (0, 0);
621 reset_base ();
623 return rval;
626 void
627 ACE_Streambuf::reset_base ()
629 // Until we experience the first get or put operation, we do not
630 // know what our current IO mode is.
631 this->cur_mode_ = 0;
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
637 // value.
638 setb (0, 0);
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 ()
647 delete [] this->eback_saved_;
648 delete [] this->pbase_saved_;
651 u_char ACE_Streambuf::timeout ()
653 u_char rval = this->timeout_;
654 this->timeout_ = 0;
655 return rval;
658 ACE_END_VERSIONED_NAMESPACE_DECL
660 #endif /* !ACE_LACKS_ACE_IOSTREAM */
661 #endif /* ACE_IOSTREAM_CPP */