summaryrefslogtreecommitdiff
path: root/ACE/ace/UPIPE_Stream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/UPIPE_Stream.cpp')
-rw-r--r--ACE/ace/UPIPE_Stream.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/ACE/ace/UPIPE_Stream.cpp b/ACE/ace/UPIPE_Stream.cpp
new file mode 100644
index 00000000000..53b170d23cd
--- /dev/null
+++ b/ACE/ace/UPIPE_Stream.cpp
@@ -0,0 +1,231 @@
+// $Id$
+
+#include "ace/UPIPE_Stream.h"
+
+ACE_RCSID(ace, UPIPE_Stream, "$Id$")
+
+#if defined (ACE_HAS_THREADS)
+
+#include "ace/OS_NS_string.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/UPIPE_Stream.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Stream)
+
+ACE_UPIPE_Stream::ACE_UPIPE_Stream (void)
+ : mb_last_ (0),
+ reference_count_ (0)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::ACE_UPIPE_STREAM");
+}
+
+ACE_UPIPE_Stream::~ACE_UPIPE_Stream (void)
+{
+ if (this->mb_last_ != 0)
+ {
+ this->mb_last_->release ();
+ this->mb_last_ = 0;
+ }
+}
+
+int
+ACE_UPIPE_Stream::control (int cmd,
+ void * val) const
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::control");
+
+ return ((ACE_UPIPE_Stream *) this)->stream_.control
+ ((ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds) cmd, val);
+}
+
+void
+ACE_UPIPE_Stream::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_UPIPE_Stream::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+int
+ACE_UPIPE_Stream::close (void)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::close");
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
+
+ this->reference_count_--;
+
+ if (this->reference_count_ == 0)
+ {
+ // Since the UPIPE should have been closed earlier we won't bother
+ // checking to see if closing it now fails.
+
+ if (this->ACE_SPIPE::get_handle () != ACE_INVALID_HANDLE)
+ this->ACE_SPIPE::close ();
+
+ // Close down the ACE_stream.
+ return this->stream_.close ();
+ }
+ return 0;
+}
+
+int
+ACE_UPIPE_Stream::get_remote_addr (ACE_UPIPE_Addr &remote_sap) const
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::get_remote_addr");
+ remote_sap = this->remote_addr_;
+ return 0;
+}
+
+int
+ACE_UPIPE_Stream::send (ACE_Message_Block *mb_p,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::send_msg");
+ return this->stream_.put (mb_p, timeout) == -1 ? -1 : 0;
+}
+
+int ACE_UPIPE_Stream::recv (ACE_Message_Block *& mb_p,
+ ACE_Time_Value *timeout)
+{
+ return this->stream_.get (mb_p, timeout) == -1 ? -1 : 0;
+}
+
+// Send a buffer.
+
+ssize_t
+ACE_UPIPE_Stream::send (const char *buffer,
+ size_t n,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::send");
+
+ ACE_Message_Block *mb_p;
+ ACE_NEW_RETURN (mb_p,
+ ACE_Message_Block (n),
+ -1);
+ mb_p->copy (buffer, n);
+ return
+ this->stream_.put (mb_p, timeout) == -1
+ ? -1
+ : static_cast<ssize_t> (n);
+}
+
+// Receive a buffer.
+
+ssize_t
+ACE_UPIPE_Stream::recv (char *buffer,
+ size_t n,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::recv");
+ // Index in buffer.
+ size_t bytes_read = 0;
+
+ while (bytes_read < n)
+ if (this->mb_last_ != 0)
+ {
+ // We have remaining data in our last read Message_Buffer.
+ size_t this_len = this->mb_last_->length ();
+ if (this_len < n)
+ {
+ // The remaining data is not enough.
+
+ ACE_OS::memcpy ((void *) &buffer[bytes_read],
+ this->mb_last_->rd_ptr (),
+ this_len);
+ bytes_read += this_len;
+ this->mb_last_ = this->mb_last_->release (); // mb_last_ now 0
+ return bytes_read;
+ }
+ else
+ {
+ // The remaining data is at least enough. If there's
+ // more, we'll get it the next time through.
+ ACE_OS::memcpy (&buffer[bytes_read],
+ this->mb_last_->rd_ptr (),
+ n);
+ bytes_read += n;
+
+ // Advance rd_ptr.
+ this->mb_last_->rd_ptr (n);
+
+ if (this->mb_last_->length () == 0)
+ // Now the Message_Buffer is empty.
+ this->mb_last_ = this->mb_last_->release ();
+ }
+ }
+ else
+ {
+ // We have to get a new Message_Buffer from our stream.
+ int result = this->stream_.get (this->mb_last_, timeout);
+
+ if (result == -1)
+ {
+ if (errno == EWOULDBLOCK && bytes_read > 0)
+ // Return the number of bytes read before we timed out.
+ return bytes_read;
+ else
+ return -1;
+ }
+ }
+
+ return bytes_read;
+}
+
+ssize_t
+ACE_UPIPE_Stream::send_n (const char *buf,
+ size_t n,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::send_n");
+
+ size_t bytes_written;
+ ssize_t len = 0;
+
+ for (bytes_written = 0;
+ bytes_written < n;
+ bytes_written += len)
+ {
+ len = this->send (buf + bytes_written,
+ n - bytes_written,
+ timeout);
+
+ if (len == -1)
+ return -1;
+ }
+
+ return bytes_written;
+}
+
+ssize_t
+ACE_UPIPE_Stream::recv_n (char *buf,
+ size_t n,
+ ACE_Time_Value *timeout)
+{
+ ACE_TRACE ("ACE_UPIPE_Stream::recv_n");
+ size_t bytes_read;
+ ssize_t len = 0;
+
+ for (bytes_read = 0;
+ bytes_read < n;
+ bytes_read += len)
+ {
+ len = this->recv (buf + bytes_read,
+ n - bytes_read,
+ timeout);
+ if (len == -1)
+ return -1;
+ else if (len == 0)
+ break;
+ }
+
+ return bytes_read;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_HAS_THREADS */