IOStream_T.cpp

Go to the documentation of this file.
00001 // IOStream_T.cpp,v 4.26 2005/10/28 16:14:52 ossama Exp
00002 
00003 #ifndef ACE_IOSTREAM_T_CPP
00004 #define ACE_IOSTREAM_T_CPP
00005 
00006 #include "ace/IOStream_T.h"
00007 #include "ace/OS_Memory.h"
00008 
00009 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00010 # pragma once
00011 #endif /* ACE_LACKS_PRAGMA_ONCE */
00012 
00013 #if !defined (ACE_LACKS_ACE_IOSTREAM)
00014 
00015 #if !defined (__ACE_INLINE__)
00016 #include "ace/IOStream_T.inl"
00017 #endif /* !__ACE_INLINE__ */
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 // We will be given a STREAM by the iostream object which creates us.
00022 // See the ACE_IOStream template for how that works.  Like other
00023 // streambuf objects, we can be input-only, output-only or both.
00024 
00025 template <class STREAM>
00026 ACE_Streambuf_T<STREAM>::ACE_Streambuf_T (STREAM *peer,
00027                                           u_int streambuf_size,
00028                                           int io_mode)
00029   : ACE_Streambuf (streambuf_size, io_mode),
00030     peer_ (peer)
00031 {
00032   // A streambuf allows for unbuffered IO where every character is
00033   // read as requested and written as provided.  To me, this seems
00034   // terribly inefficient for socket-type operations, so I've disabled
00035   // it.  All of the work would be done by the underflow/overflow
00036   // functions anyway and I haven't implemented anything there to
00037   // support unbuffered IO.
00038 
00039 #if !defined (ACE_LACKS_UNBUFFERED_STREAMBUF)
00040   this->unbuffered (0);
00041 #endif /* ! ACE_LACKS_UNBUFFERED_STREAMBUF */
00042 
00043   // Linebuffered is similar to unbuffered.  Again, I don't have any
00044   // need for this and I don't see the advantage.  I believe this
00045   // would have to be supported by underflow/overflow to be effective.
00046 #if !defined (ACE_LACKS_LINEBUFFERED_STREAMBUF)
00047   this->linebuffered (0);
00048 #endif /* ! ACE_LACKS_LINEBUFFERED_STREAMBUF */
00049 }
00050 
00051 template <class STREAM> ssize_t
00052 ACE_Streambuf_T<STREAM>::send (char *buf, ssize_t len)
00053 {
00054   return peer_->send_n (buf,len);
00055 }
00056 
00057 template <class STREAM> ssize_t
00058 ACE_Streambuf_T<STREAM>::recv (char *buf,
00059                                ssize_t len,
00060                                ACE_Time_Value *tv)
00061 {
00062   return this->recv (buf, len, 0, tv);
00063 }
00064 
00065 template <class STREAM> ssize_t
00066 ACE_Streambuf_T<STREAM>::recv (char *buf,
00067                                ssize_t len,
00068                                int flags,
00069                                ACE_Time_Value * tv)
00070 {
00071   this->timeout_ = 0;
00072   errno = ESUCCESS;
00073   ssize_t rval = peer_->recv (buf, len, flags, tv);
00074   if (errno == ETIME)
00075     this->timeout_ = 1;
00076   return rval;
00077 }
00078 
00079 template <class STREAM> ssize_t
00080 ACE_Streambuf_T<STREAM>::recv_n (char *buf,
00081                                  ssize_t len,
00082                                  int flags,
00083                                  ACE_Time_Value *tv)
00084 {
00085   this->timeout_ = 0;
00086   errno = ESUCCESS;
00087   ssize_t rval = peer_->recv_n (buf, len, flags, tv);
00088   if (errno == ETIME)
00089     this->timeout_ = 1;
00090   return rval;
00091 }
00092 
00093 template <class STREAM> ACE_HANDLE
00094 ACE_Streambuf_T<STREAM>::get_handle (void)
00095 {
00096   return peer_ ? peer_->get_handle () : 0;
00097 }
00098 
00099 // The typical constructor.  This will initiailze your STREAM and then
00100 // setup the iostream baseclass to use a custom streambuf based on
00101 // STREAM.
00102 
00103 template <class STREAM>
00104 ACE_IOStream<STREAM>::ACE_IOStream (STREAM &stream,
00105                                     u_int streambuf_size)
00106   : iostream (0),
00107     STREAM (stream)
00108 {
00109   ACE_NEW (streambuf_,
00110            ACE_Streambuf_T<STREAM> ((STREAM *) this,
00111                                     streambuf_size));
00112   iostream::init (this->streambuf_);
00113 }
00114 
00115 template <class STREAM>
00116 ACE_IOStream<STREAM>::ACE_IOStream (u_int streambuf_size)
00117   : iostream (0)
00118 {
00119   ACE_NEW (this->streambuf_,
00120            ACE_Streambuf_T<STREAM> ((STREAM *) this,
00121                                     streambuf_size));
00122   iostream::init (this->streambuf_);
00123 }
00124 
00125 // We have to get rid of the streambuf_ ourselves since we gave it to
00126 // iostream ()
00127 
00128 template <class STREAM>
00129 ACE_IOStream<STREAM>::~ACE_IOStream (void)
00130 {
00131   delete this->streambuf_;
00132 }
00133 
00134 // The only ambituity in the multiple inheritance is the close ()
00135 // function.
00136 
00137 template <class STREAM> int
00138 ACE_IOStream<STREAM>::close (void)
00139 {
00140   return STREAM::close ();
00141 }
00142 
00143 template <class STREAM> ACE_IOStream<STREAM> &
00144 ACE_IOStream<STREAM>::operator>> (ACE_Time_Value *&tv)
00145 {
00146   ACE_Time_Value *old_tv = this->streambuf_->recv_timeout (tv);
00147   tv = old_tv;
00148   return *this;
00149 }
00150 
00151 #if defined (ACE_HAS_STRING_CLASS)
00152 
00153 // A simple string operator.  The base iostream has 'em for char* but
00154 // that isn't always the best thing for a String.  If we don't provide
00155 // our own here, we may not get what we want.
00156 
00157 template <class STREAM> ACE_IOStream<STREAM> &
00158 ACE_IOStream<STREAM>::operator>> (ACE_IOStream_String &v)
00159 {
00160   if (ipfx0 ())
00161     {
00162       char c;
00163       this->get (c);
00164 
00165       for (v = c;
00166            this->get (c) && !isspace (c);
00167            v += c)
00168         continue;
00169     }
00170 
00171   isfx ();
00172 
00173   return *this;
00174 }
00175 
00176 template <class STREAM> ACE_IOStream<STREAM> &
00177 ACE_IOStream<STREAM>::operator<< (ACE_IOStream_String &v)
00178 {
00179   if (opfx ())
00180     {
00181 #if defined (ACE_WIN32) && defined (_MSC_VER)
00182       for (int i = 0; i < v.GetLength (); ++i)
00183 #else
00184       for (u_int i = 0; i < (u_int) v.length (); ++i)
00185 #endif /* ACE_WIN32 && defined (_MSC_VER) */
00186         this->put (v[i]);
00187     }
00188 
00189   osfx ();
00190 
00191   return *this;
00192 }
00193 
00194 // A more clever put operator for strings that knows how to deal with
00195 // quoted strings containing back-quoted quotes.
00196 
00197 template <class STREAM> STREAM &
00198 operator>> (STREAM &stream,
00199             ACE_Quoted_String &str)
00200 {
00201   char c;
00202 
00203   if (!(stream >> c)) // eat space up to the first char
00204     // stream.set (ios::eofbit|ios::failbit);
00205     return stream;
00206 
00207   str = "";     // Initialize the string
00208 
00209   // if we don't have a quote, append until we see space
00210   if (c != '"')
00211     for (str = c; stream.get (c) && !isspace (c); str += c)
00212       continue;
00213   else
00214     for (; stream.get (c) && c != '"'; str += c)
00215       if (c == '\\')
00216         {
00217           stream.get (c);
00218           if (c != '"')
00219             str += '\\';
00220         }
00221 
00222   return stream;
00223 }
00224 
00225 template <class STREAM> STREAM &
00226 operator<< (STREAM &stream,
00227             ACE_Quoted_String &str)
00228 {
00229   stream.put ('"');
00230 
00231   for (u_int i = 0; i < str.length (); ++i)
00232     {
00233       if (str[i] == '"')
00234         stream.put ('\\');
00235       stream.put (str[i]);
00236     }
00237 
00238   stream.put ('"');
00239 
00240   return stream;
00241 }
00242 
00243 ACE_END_VERSIONED_NAMESPACE_DECL
00244 
00245 #endif /* ACE_HAS_STRING_CLASS */
00246 #endif /* ACE_LACKS_ACE_IOSTREAM */
00247 #endif /* ACE_IOSTREAM_T_CPP */

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6