diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-02-05 05:01:13 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-02-05 05:01:13 +0000 |
commit | e589686a7e0687a5713b8495c74e83a9752e57c4 (patch) | |
tree | e502ccaf24f415d15f301840b4d384145a93d2cb /ace | |
parent | f18e114a04aa1dc6412b16aae0d59141d9c863db (diff) | |
download | ATCD-e589686a7e0687a5713b8495c74e83a9752e57c4.tar.gz |
foo
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Hash_Map_Manager.cpp | 6 | ||||
-rw-r--r-- | ace/IOStream.cpp | 586 | ||||
-rw-r--r-- | ace/IOStream.h | 343 | ||||
-rw-r--r-- | ace/LSOCK.cpp | 4 | ||||
-rw-r--r-- | ace/LSOCK_Stream.cpp | 20 | ||||
-rw-r--r-- | ace/Malloc.i | 38 | ||||
-rw-r--r-- | ace/Message_Block.cpp | 1 | ||||
-rw-r--r-- | ace/OS.cpp | 10 | ||||
-rw-r--r-- | ace/OS.i | 13 | ||||
-rw-r--r-- | ace/README | 1 | ||||
-rw-r--r-- | ace/SOCK_Dgram.cpp | 12 | ||||
-rw-r--r-- | ace/TTY_IO.cpp | 2 | ||||
-rw-r--r-- | ace/config-dgux-4.11-epc.h | 3 | ||||
-rw-r--r-- | ace/config-unixware-2.01-g++.h | 1 | ||||
-rw-r--r-- | ace/config-vxworks-ghs-1.8.h | 1 | ||||
-rw-r--r-- | ace/config-vxworks5.2-g++.h | 1 |
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 */ @@ -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 |