From f0038e766a4f6e6a75f2db3389b089d6a26ddd31 Mon Sep 17 00:00:00 2001
From: Peter Soetens <peter@thesourceworks.com>
Date: Mon, 12 Nov 2012 23:31:55 +0100
Subject: [PATCH 2/3] ports: provide InputPort::getDataSample()

This is the counterpart of OutputPort::setDataSample() and allows receiving
parties to initialize internal data structures according to the expected
size of the data on this port.

Signed-off-by: Peter Soetens <peter@thesourceworks.com>
---
 rtt/InputPort.hpp                     |   16 ++++++++++++++++
 rtt/base/BufferInterface.hpp          |    5 +++++
 rtt/base/BufferLockFree.hpp           |   11 +++++++++++
 rtt/base/BufferLocked.hpp             |    6 ++++++
 rtt/base/BufferUnSync.hpp             |    5 +++++
 rtt/base/ChannelElement.hpp           |    8 ++++++++
 rtt/base/DataObjectUnSync.hpp         |    6 ++++++
 rtt/internal/ChannelBufferElement.hpp |    4 ++++
 rtt/internal/ChannelDataElement.hpp   |    5 +++++
 rtt/internal/InputPortSource.hpp      |    4 +++-
 10 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/rtt/InputPort.hpp b/rtt/InputPort.hpp
index 56bb6b4..edae637 100644
--- a/rtt/InputPort.hpp
+++ b/rtt/InputPort.hpp
@@ -174,6 +174,22 @@ namespace RTT
             return RTT::NewData;
         }
 
+        /**
+         * Get a sample of the data on this port, without actually reading the port's data.
+         * It's the complement of OutputPort::setDataSample() and serves to retrieve the size
+         * of a variable sized data type T. Returns default T if !connected() or if the 
+         * OutputPort did not use setDataSample(). Returns an example T otherwise.
+         * In case multiple inputs are connected to this port a sample from the currently read
+         * connection will be returned.
+         */
+        void getDataSample(T& sample)
+        {
+            typename base::ChannelElement<T>::shared_ptr input = static_cast< base::ChannelElement<T>* >( cmanager.getCurrentChannel() );
+            if ( input ) {
+                sample = input->data_sample();
+            }
+        }
+
         /** Returns the types::TypeInfo object for the port's type */
         virtual const types::TypeInfo* getTypeInfo() const
         { return internal::DataSourceTypeInfo<T>::getTypeInfo(); }
diff --git a/rtt/base/BufferInterface.hpp b/rtt/base/BufferInterface.hpp
index fe666a7..ead17ba 100644
--- a/rtt/base/BufferInterface.hpp
+++ b/rtt/base/BufferInterface.hpp
@@ -131,6 +131,11 @@ namespace RTT
          * @nrt
          */
         virtual void data_sample( const T& sample ) = 0;
+
+        /**
+         * Reads back a data sample.
+         */
+        virtual T data_sample() const = 0;
     };
 }}
 
diff --git a/rtt/base/BufferLockFree.hpp b/rtt/base/BufferLockFree.hpp
index fbc4abc..8ad75b5 100644
--- a/rtt/base/BufferLockFree.hpp
+++ b/rtt/base/BufferLockFree.hpp
@@ -100,6 +100,17 @@ namespace RTT
             mpool.data_sample(sample);
         }
 
+        virtual T data_sample() const
+        {
+            T result = T();
+            Item* mitem = mpool.allocate();
+            if (mitem != 0) {
+                result = *mitem;
+                mpool.deallocate( mitem );
+            }
+            return result;
+        }
+
 
         size_type capacity() const
         {
diff --git a/rtt/base/BufferLocked.hpp b/rtt/base/BufferLocked.hpp
index c14207b..3e4a56c 100644
--- a/rtt/base/BufferLocked.hpp
+++ b/rtt/base/BufferLocked.hpp
@@ -84,6 +84,12 @@ namespace RTT
         {
             buf.resize(cap, sample);
             buf.resize(0);
+            lastSample = sample;
+        }
+
+        virtual T data_sample() const
+        {
+            return lastSample;
         }
 
         /**
diff --git a/rtt/base/BufferUnSync.hpp b/rtt/base/BufferUnSync.hpp
index c006df5..741eb37 100644
--- a/rtt/base/BufferUnSync.hpp
+++ b/rtt/base/BufferUnSync.hpp
@@ -79,6 +79,11 @@ namespace RTT
             buf.resize(0);
         }
 
+        virtual T data_sample() const
+        {
+            return lastSample;
+        }
+
         /**
          * Destructor
          */
diff --git a/rtt/base/ChannelElement.hpp b/rtt/base/ChannelElement.hpp
index f03e856..20cd7fa 100644
--- a/rtt/base/ChannelElement.hpp
+++ b/rtt/base/ChannelElement.hpp
@@ -87,6 +87,14 @@ namespace RTT { namespace base {
             return false;
         }
 
+        virtual value_t data_sample()
+        {
+            typename ChannelElement<T>::shared_ptr input = boost::static_pointer_cast< ChannelElement<T> >(getInput());
+            if (input)
+                return input->data_sample();
+            return value_t();
+        }
+
         /** Writes a new sample on this connection. \a sample is the sample to
          * write. 
          *
diff --git a/rtt/base/DataObjectUnSync.hpp b/rtt/base/DataObjectUnSync.hpp
index 9f3d8db..a235033 100644
--- a/rtt/base/DataObjectUnSync.hpp
+++ b/rtt/base/DataObjectUnSync.hpp
@@ -82,6 +82,12 @@ namespace RTT
         virtual void data_sample( const DataType& sample ) {
             Set(sample);
         }
+
+        virtual T data_sample() const
+        {
+            return data;
+        }
+
     };
 }}
 
diff --git a/rtt/internal/ChannelBufferElement.hpp b/rtt/internal/ChannelBufferElement.hpp
index 4e143bd..c38a007 100644
--- a/rtt/internal/ChannelBufferElement.hpp
+++ b/rtt/internal/ChannelBufferElement.hpp
@@ -118,6 +118,10 @@ namespace RTT { namespace internal {
             return base::ChannelElement<T>::data_sample(sample);
         }
 
+        virtual T data_sample()
+        {
+            return buffer->data_sample();
+        }
     };
 }}
 
diff --git a/rtt/internal/ChannelDataElement.hpp b/rtt/internal/ChannelDataElement.hpp
index 6559f5d..a6958de 100644
--- a/rtt/internal/ChannelDataElement.hpp
+++ b/rtt/internal/ChannelDataElement.hpp
@@ -107,6 +107,11 @@ namespace RTT { namespace internal {
             return base::ChannelElement<T>::data_sample(sample);
         }
 
+        virtual T data_sample()
+        {
+            return data->Get();
+        }
+
     };
 }}
 
diff --git a/rtt/internal/InputPortSource.hpp b/rtt/internal/InputPortSource.hpp
index cc9d76b..29ae77d 100644
--- a/rtt/internal/InputPortSource.hpp
+++ b/rtt/internal/InputPortSource.hpp
@@ -73,7 +73,9 @@ namespace RTT
         typedef typename boost::intrusive_ptr<InputPortSource<T> > shared_ptr;
 
         InputPortSource(InputPort<T>& port)
-            : port(&port), mvalue() { }
+            : port(&port), mvalue() { 
+            port.getDataSample( mvalue );
+        }
 
         /**
          * Called by owner port to notify that it is being
-- 
1.7.5.4

