PROTON-799: Added the Transport class to the Ruby engine APIs.

Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/8e968fa9
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/8e968fa9
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/8e968fa9

Branch: refs/heads/ruby-engine-apis
Commit: 8e968fa9dc4b8e8986d65649ebf7ff9d188ff679
Parents: a3db56d
Author: Darryl L. Pierce <mcpie...@gmail.com>
Authored: Wed Jan 14 09:31:46 2015 -0500
Committer: Darryl L. Pierce <mcpie...@gmail.com>
Committed: Mon May 18 11:33:31 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/exceptions.rb |   5 +
 proton-c/bindings/ruby/lib/core/transport.rb  | 412 +++++++++++++++++++++
 proton-c/bindings/ruby/lib/qpid_proton.rb     |   1 +
 proton-c/bindings/ruby/ruby.i                 |  14 +
 4 files changed, 432 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8e968fa9/proton-c/bindings/ruby/lib/core/exceptions.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/exceptions.rb 
b/proton-c/bindings/ruby/lib/core/exceptions.rb
index 2695709..94d2957 100644
--- a/proton-c/bindings/ruby/lib/core/exceptions.rb
+++ b/proton-c/bindings/ruby/lib/core/exceptions.rb
@@ -80,6 +80,11 @@ module Qpid
     class InProgressError < ProtonError
     end
 
+    # Raised by instances of Transport.
+    #
+    class TransportError < ProtonError
+    end
+
     # Raised by instances of SASL
     #
     class SASLError < TransportError

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8e968fa9/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb 
b/proton-c/bindings/ruby/lib/core/transport.rb
new file mode 100644
index 0000000..206f97d
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -0,0 +1,412 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+module Qpid::Proton
+
+  # A transport is used by a connection to interface with the network.
+  #
+  # A transport is associated with, at most, one Connection.
+  #
+  # == Client And Server Mode
+  #
+  # Initially, a transport is configured to be a client tranpsort. It can be
+  # configured to act as a server when it is created.
+  #
+  # A client transport initiates outgoing connections.
+  #
+  # A client transport must be configured with the protocol layers to use and
+  # cannot configure itself automatically.
+  #
+  # A server transport accepts incoming connections. It can automatically
+  # configure itself to include the various protocol layers depending on the
+  # incoming protocol headers.
+  #
+  # == Tracing Data
+  #
+  # Data can be traced into and out of the transport programmatically by 
setting
+  # the #trace level to one of the defined trace values (TRACE_RAW, TRACE_FRM 
or
+  # TRACE_DRV). Tracing can also be turned off programmatically by setting the
+  # #trace level to TRACE_OFF.
+  #
+  # @example
+  #
+  #   # turns on frame tracing
+  #   @transport.trace = Qpid::Proton::Transport::TRACE_FRM
+  #
+  #   # ... do something where the frames are of interest, such as debugging
+  #
+  #   # turn tracing off again
+  #   @transport.trace = Qpid::Proton::Transport::TRACE_NONE
+  #
+  # Tracing can also be enabled from the command line by defining the similarly
+  # named environment variable before starting a Proton application:
+  #
+  # @example
+  #
+  #   # enable tracing from the command line
+  #   PN_TRACE_FRM=1 ruby my_proton_app.rb
+  #
+  class Transport
+
+    # @private
+    include Util::Engine
+
+    # Turn logging off entirely.
+    TRACE_OFF = Cproton::PN_TRACE_OFF
+    # Log raw binary data into/out of the transport.
+    TRACE_RAW = Cproton::PN_TRACE_RAW
+    # Log frames into/out of the transport.
+    TRACE_FRM = Cproton::PN_TRACE_FRM
+    # Log driver related events; i.e., initialization, end of stream, etc.
+    TRACE_DRV = Cproton::PN_TRACE_DRV
+
+    # @private
+    CLIENT = 1
+    # @private
+    SERVER = 2
+
+    # @private
+    include Util::SwigHelper
+
+    # @private
+    PROTON_METHOD_PREFIX = "pn_transport"
+
+    # @!attribute channel_max
+    #
+    # @return [Fixnum] The maximum allowed channel.
+    #
+    proton_accessor :channel_max
+
+    # @!attribute [r] remote_channel_max
+    #
+    # @return [Fixnum] The maximum allowed channel of a transport's remote 
peer.
+    #
+    proton_caller :remote_channel_max
+
+    # @!attribute max_frame_size
+    #
+    # @return [Fixnum] The maximum frame size.
+    #
+    proton_accessor :max_frame_size
+
+    # @!attribute [r] remote_max_frame_size
+    #
+    # @return [Fixnum] The maximum frame size of the transport's remote peer.
+    #
+    proton_reader :remote_max_frame_size
+
+    # @!attribute idle_timeout
+    #
+    # @return [Fixnum] The idle timeout.
+    #
+    proton_accessor :idle_timeout
+
+    # @!attribute [r] remote_idle_timeout
+    #
+    # @return [Fixnum] The idle timeout for the transport's remote peer.
+    #
+    proton_accessor :remote_idle_timeout
+
+    # @!attribute [r] capacity
+    #
+    # If the engine is in an exception state such as encountering an error
+    # condition or reaching the end of stream state, a negative value will
+    # be returned indicating the condition.
+    #
+    # If an error is indicated, further deteails can be obtained from
+    # #error.
+    #
+    # Calls to #process may alter the value of this value. See #process for
+    # more details
+    #
+    # @return [Fixnum] The amount of free space for input following the
+    # transport's tail pointer.
+    #
+    proton_caller :capacity
+
+    # @!attribute [r] head
+    #
+    # This referneces queued output data. It reports the bytes of output data.
+    #
+    # Calls to #pop may alter this attribute, and any data it references.
+    #
+    # @return [String] The transport's head pointer.
+    #
+    proton_caller :head
+
+    # @!attribute [r] tail
+    #
+    # The amount of free space following this data is reported by #capacity.
+    #
+    # Calls to #process may alter the value of this attribute.
+    #
+    # @return [String] The transport's tail pointer.
+    #
+    proton_caller :tail
+
+    # @!attribute [r] pending
+    #
+    # If the ending is in an exceptional state, such as encountering an error
+    # condition or reachign the end of the stream state, a negative value will
+    # be returned indicating the condition.
+    #
+    # If an error is indicated, further details can be obtained from #error.
+    #
+    # Calls to #pop may alter the value of this pointer as well.
+    #
+    # @return [Fixnum] The number of pending output bytes following the header
+    # pointer.
+    #
+    # @raise [TransportError] If any error other than an end of stream occurs.
+    #
+    proton_caller :pending
+
+    # @!attribute [r] closed?
+    #
+    # A transport is defined to be closed when both the tail and the head are
+    # closed. In other words, when both #capacity < 0 and #pending < 0.
+    #
+    # @return [Boolean] Returns true if the tranpsort is closed.
+    #
+    proton_caller :closed?
+
+    # @!attribute [r] frames_output
+    #
+    # @return [Fixnum] The number of frames output by a transport.
+    #
+    proton_reader :frames_output
+
+    # @!attribute [r] frames_input
+    #
+    # @return [Fixnum] The number of frames input by a transport.
+    #
+    proton_reader :frames_input
+
+    # @private
+    include Util::ErrorHandler
+
+    can_raise_error :process, :error_class => TransportError
+    can_raise_error :close_tail, :error_class => TransportError
+    can_raise_error :pending, :error_class => TransportError, :below => 
Error::EOS
+    can_raise_error :close_head, :error_class => TransportError
+
+    # @private
+    include Util::Wrapper
+
+    # @private
+    def self.wrap(impl)
+      return nil if impl.nil?
+
+      self.fetch_instance(impl, :pn_transport_attachments) || 
Transport.new(nil, impl)
+    end
+
+    # Creates a new transport instance.
+    #
+    # @param mode [Fixnum] The transport mode, either CLIENT or SERVER
+    # @param impl [pn_transport_t] Should not be used.
+    #
+    # @raise [TransportError] If the mode is invalid.
+    #
+    def initialize(mode = nil, impl = Cproton.pn_transport)
+      @impl = impl
+      if mode == SERVER
+        Cproton.pn_transport_set_server(@impl)
+      elsif (!mode.nil? && mode != CLIENT)
+        raise TransportError.new("cannot create transport for mode: #{mode}")
+      end
+      self.class.store_instance(self, :pn_transport_attachments)
+    end
+
+    # Returns whether the transport has any buffered data.
+    #
+    # @return [Boolean] True if the transport has no buffered data.
+    #
+    def quiesced?
+      Cproton.pn_transport_quiesced(@impl)
+    end
+
+    # Returns additional information about the condition of the transport.
+    #
+    # When a TRANSPORT_ERROR event occurs, this operaiton can be used to
+    # access the details of the error condition.
+    #
+    # The object returned is valid until the Transport is discarded.
+    #
+    def condition
+      condition_to_object Cproton.pn_transport_condition(@impl)
+    end
+
+    # Binds to the given connection.
+    #
+    # @param connection [Connection] The connection.
+    #
+    def bind(connection)
+      Cproton.pn_transport_bind(@impl, connection.impl)
+    end
+
+    # Unbinds from the previous connection.
+    #
+    def unbind
+      Cproton.pn_transport_unbind(@impl)
+    end
+
+    # Updates the transports trace flags.
+    #
+    # @param level [Fixnum] The trace level.
+    #
+    # @see TRACE_OFF
+    # @see TRACE_RAW
+    # @see TRACE_FRM
+    # @see TRACE_DRV
+    #
+    def trace(level)
+      Cproton.pn_transport_trace(@impl, level)
+    end
+
+    # Return the AMQP connection associated with the transport.
+    #
+    # @return [Connection, nil] The bound connection, or nil.
+    #
+    def connection
+      Connection.wrap(Cproton.pn_transport_connection(@impl))
+    end
+
+    # Log a message to the transport's logging mechanism.
+    #
+    # This can be using in a debugging scenario as the message will be
+    # prepended with the transport's identifier.
+    #
+    # @param message [String] The message to be logged.
+    #
+    def log(message)
+      Cproton.pn_transport_log(@impl, message)
+    end
+
+    # Pushes the supplied bytes into the tail of the transport.
+    #
+    # @param data [String] The bytes to be pushed.
+    #
+    # @return [Fixnum] The number of bytes pushed.
+    #
+    def push(data)
+      Cproton.pn_transport_push(@impl, data, data.length)
+    end
+
+    # Process input data following the tail pointer.
+    #
+    # Calling this function will cause the transport to consume the specified
+    # number of bytes of input occupying the free space following the tail
+    # pointer. It may also change the value for #tail, as well as the amount of
+    # free space reported by #capacity.
+    #
+    # @param size [Fixnum] The number of bytes to process.
+    #
+    # @raise [TransportError] If an error occurs.
+    #
+    def process(size)
+      Cproton.pn_transport_process(@impl, size)
+    end
+
+    # Indicate that the input has reached EOS (end of stream).
+    #
+    # This tells the transport that no more input will be forthcoming.
+    #
+    # @raise [TransportError] If an error occurs.
+    #
+    def close_tail
+      Cproton.pn_transport_close_tail(@impl)
+    end
+
+    # Returns the specified number of bytes from the transport's buffers.
+    #
+    # @param size [Fixnum] The number of bytes to return.
+    #
+    # @return [String] The data peeked.
+    #
+    # @raise [TransportError] If an error occurs.
+    #
+    def peek(size)
+      cd, out = Cproton.pn_transport_peek(@impl, size)
+      return nil if cd == Qpid::Proton::Error::EOS
+      raise TransportError.new if cd < -1
+      out
+    end
+
+    # Removes the specified number of bytes from the pending output queue
+    # following the transport's head pointer.
+    #
+    # @param size [Fixnum] The number of bytes to remove.
+    #
+    def pop(size)
+      Cproton.pn_transport_pop(@impl, size)
+    end
+
+    # Indicate that the output has closed.
+    #
+    # Tells the transport that no more output will be popped.
+    #
+    # @raise [TransportError] If an error occurs.
+    #
+    def close_head
+      Cproton.pn_transport_close_head(@impl)
+    end
+
+    # Process any pending transport timer events.
+    #
+    # This method should be called after all pending input has been
+    # processed by the transport (see #input), and before generating
+    # output (see #output).
+    #
+    # It returns the deadline for the next pending timer event, if any
+    # art present.
+    #
+    # @param now [Time] The timestamp.
+    #
+    # @return [Fixnum] If non-zero, the expiration time of the next pending
+    #   timer event for the transport. The caller must invoke #tick again at
+    #   least once at or before this deadline occurs.
+    #
+    def tick(now)
+      Cproton.pn_transport_tick(@impl, now)
+    end
+
+    def sasl
+      SASL.new(self)
+    end
+
+    # Creates, or returns an existing, SSL object for the transport.
+    #
+    # @param domain [SSLDomain] The SSL domain.
+    # @param session_details [SSLDetails] The SSL session details.
+    #
+    # @return [SSL] The SSL object.
+    #
+    def ssl(domain = nil, session_details = nil)
+      self.ssl = SSL.create(self, domain, session_details) if self.ssl.nil?
+      self.ssl
+    end
+
+    # @private
+    def ssl?
+      self.respond_to?(:ssl) && !self.ssl.nil?
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8e968fa9/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb 
b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 244e318..16394f9 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -67,6 +67,7 @@ require "core/sasl"
 require "core/ssl_domain"
 require "core/ssl_details"
 require "core/ssl"
+require "core/transport"
 
 # Messenger API classes
 require "messenger/filters"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8e968fa9/proton-c/bindings/ruby/ruby.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/ruby.i b/proton-c/bindings/ruby/ruby.i
index 59d37e9..8e4b6a7 100644
--- a/proton-c/bindings/ruby/ruby.i
+++ b/proton-c/bindings/ruby/ruby.i
@@ -273,6 +273,20 @@ ssize_t pn_transport_input(pn_transport_t *transport, char 
*STRING, size_t LENGT
 %}
 %ignore pn_transport_output;
 
+%rename(pn_transport_peek) wrap_pn_transport_peek;
+%inline %{
+  ssize_t wrap_pn_transport_peek(pn_transport_t *transport, char *OUTPUT, 
size_t *OUTPUT_SIZE) {
+    ssize_t sz = pn_transport_peek(transport, OUTPUT, *OUTPUT_SIZE);
+    if (sz >= 0) {
+      *OUTPUT_SIZE = sz;
+    } else {
+      *OUTPUT_SIZE = 0;
+    }
+    return sz;
+  }
+  %}
+%ignore pn_transport_peek;
+
 %rename(pn_delivery) wrap_pn_delivery;
 %inline %{
   pn_delivery_t *wrap_pn_delivery(pn_link_t *link, char *STRING, size_t 
LENGTH) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to