summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2013-01-28 11:18:25 +0100
committerBenoit Foucher <benoit@zeroc.com>2013-01-28 11:18:25 +0100
commit505c27be641d9855aa682affb204f118b1ce69f1 (patch)
tree406d1323320961802695285315ce6f72cce6447a
parentICE-5191: support for zero-copy on x86_64 (diff)
downloadice-505c27be641d9855aa682affb204f118b1ce69f1.tar.bz2
ice-505c27be641d9855aa682affb204f118b1ce69f1.tar.xz
ice-505c27be641d9855aa682affb204f118b1ce69f1.zip
ICE-5198: zero-copy OutputStream::finished method
-rw-r--r--CHANGES6
-rw-r--r--cpp/include/Ice/Stream.h31
-rw-r--r--cpp/src/Ice/StreamI.cpp13
-rw-r--r--cpp/src/Ice/StreamI.h13
-rw-r--r--cpp/test/Ice/stream/Client.cpp3
5 files changed, 45 insertions, 21 deletions
diff --git a/CHANGES b/CHANGES
index b7488ee2a0a..644918d9444 100644
--- a/CHANGES
+++ b/CHANGES
@@ -92,6 +92,12 @@ General Changes
C++ Changes
===========
+- Added support for zero-copy Ice::OutputStream::finished() method. If
+ supported by the stream implementation, the memory returned by this
+ method points to the output stream internal buffer. Special care
+ must be taken to ensure the memory isn't accessed after the
+ de-allocation of the output stream object.
+
- Added support for zero-copy on x86_64 processors when using the
sequence C++ array mapping.
diff --git a/cpp/include/Ice/Stream.h b/cpp/include/Ice/Stream.h
index 4af0bc8b930..0251d3dcbfe 100644
--- a/cpp/include/Ice/Stream.h
+++ b/cpp/include/Ice/Stream.h
@@ -175,17 +175,17 @@ public:
virtual void endSlice() = 0;
virtual void skipSlice() = 0;
- virtual Ice::EncodingVersion startEncapsulation() = 0;
+ virtual EncodingVersion startEncapsulation() = 0;
virtual void endEncapsulation() = 0;
- virtual Ice::EncodingVersion skipEncapsulation() = 0;
+ virtual EncodingVersion skipEncapsulation() = 0;
- virtual Ice::EncodingVersion getEncoding() const = 0;
+ virtual EncodingVersion getEncoding() const = 0;
virtual void readPendingObjects() = 0;
virtual void rewind() = 0;
- virtual void skip(Ice::Int) = 0;
+ virtual void skip(Int) = 0;
virtual void skipSize() = 0;
virtual void read(bool&) = 0;
@@ -226,14 +226,14 @@ public:
StreamHelper<T, StreamableTraits<T>::helper>::read(this, v);
}
- template<typename T> inline void read(Ice::Int tag, IceUtil::Optional<T>& v)
+ template<typename T> inline void read(Int tag, IceUtil::Optional<T>& v)
{
if(readOptional(tag, StreamOptionalHelper<T,
- Ice::StreamableTraits<T>::helper,
- Ice::StreamableTraits<T>::fixedLength>::optionalFormat))
+ StreamableTraits<T>::helper,
+ StreamableTraits<T>::fixedLength>::optionalFormat))
{
v.__setIsSet();
- StreamOptionalHelper<T, Ice::StreamableTraits<T>::helper, Ice::StreamableTraits<T>::fixedLength>::read(this, *v);
+ StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::read(this, *v);
}
}
@@ -298,15 +298,16 @@ public:
virtual void startSlice(const ::std::string&, int, bool) = 0;
virtual void endSlice() = 0;
- virtual void startEncapsulation(const Ice::EncodingVersion&, FormatType) = 0;
+ virtual void startEncapsulation(const EncodingVersion&, FormatType) = 0;
virtual void startEncapsulation() = 0;
virtual void endEncapsulation() = 0;
- virtual Ice::EncodingVersion getEncoding() const = 0;
+ virtual EncodingVersion getEncoding() const = 0;
virtual void writePendingObjects() = 0;
virtual void finished(::std::vector<Byte>&) = 0;
+ virtual std::pair<const Byte*, const Byte*> finished() = 0;
virtual size_type pos() = 0;
virtual void rewrite(Int, size_type) = 0;
@@ -348,14 +349,14 @@ public:
StreamHelper<T, StreamableTraits<T>::helper>::write(this, v);
}
- template<typename T> inline void write(Ice::Int tag, const IceUtil::Optional<T>& v)
+ template<typename T> inline void write(Int tag, const IceUtil::Optional<T>& v)
{
if(v)
{
writeOptional(tag, StreamOptionalHelper<T,
- Ice::StreamableTraits<T>::helper,
- Ice::StreamableTraits<T>::fixedLength>::optionalFormat);
- StreamOptionalHelper<T, Ice::StreamableTraits<T>::helper, Ice::StreamableTraits<T>::fixedLength>::write(this, *v);
+ StreamableTraits<T>::helper,
+ StreamableTraits<T>::fixedLength>::optionalFormat);
+ StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::write(this, *v);
}
}
@@ -364,7 +365,7 @@ public:
//
template<typename T> void write(const T* begin, const T* end)
{
- writeSize(static_cast<Ice::Int>(end - begin));
+ writeSize(static_cast<Int>(end - begin));
for(const T* p = begin; p != end; ++p)
{
write(*p);
diff --git a/cpp/src/Ice/StreamI.cpp b/cpp/src/Ice/StreamI.cpp
index 04e616c0a49..08487647785 100644
--- a/cpp/src/Ice/StreamI.cpp
+++ b/cpp/src/Ice/StreamI.cpp
@@ -671,6 +671,19 @@ OutputStreamI::finished(vector<Byte>& bytes)
vector<Byte>(_os->b.begin(), _os->b.end()).swap(bytes);
}
+pair<const Byte*, const Byte*>
+OutputStreamI::finished()
+{
+ if(_os->b.empty())
+ {
+ return pair<const Byte*, const Byte*>(reinterpret_cast<Ice::Byte*>(0), reinterpret_cast<Ice::Byte*>(0));
+ }
+ else
+ {
+ return pair<const Byte*, const Byte*>(&_os->b[0], &_os->b[0] + _os->b.size());
+ }
+}
+
void
OutputStreamI::reset(bool clearBuffer)
{
diff --git a/cpp/src/Ice/StreamI.h b/cpp/src/Ice/StreamI.h
index f1490faddc2..30b21efe76b 100644
--- a/cpp/src/Ice/StreamI.h
+++ b/cpp/src/Ice/StreamI.h
@@ -57,17 +57,17 @@ public:
virtual void endSlice();
virtual void skipSlice();
- virtual Ice::EncodingVersion startEncapsulation();
+ virtual EncodingVersion startEncapsulation();
virtual void endEncapsulation();
- virtual Ice::EncodingVersion skipEncapsulation();
+ virtual EncodingVersion skipEncapsulation();
- virtual Ice::EncodingVersion getEncoding() const;
+ virtual EncodingVersion getEncoding() const;
virtual void readPendingObjects();
virtual void rewind();
- virtual void skip(Ice::Int);
+ virtual void skip(Int);
virtual void skipSize();
virtual void read(bool&);
@@ -163,15 +163,16 @@ public:
virtual void startSlice(const std::string&, int, bool);
virtual void endSlice();
- virtual void startEncapsulation(const Ice::EncodingVersion&, FormatType);
+ virtual void startEncapsulation(const EncodingVersion&, FormatType);
virtual void startEncapsulation();
virtual void endEncapsulation();
- virtual Ice::EncodingVersion getEncoding() const;
+ virtual EncodingVersion getEncoding() const;
virtual void writePendingObjects();
virtual void finished(std::vector< Byte >&);
+ virtual std::pair<const Byte*, const Byte*> finished();
virtual void reset(bool);
diff --git a/cpp/test/Ice/stream/Client.cpp b/cpp/test/Ice/stream/Client.cpp
index f8c72f07ebe..bc3bb6f95f9 100644
--- a/cpp/test/Ice/stream/Client.cpp
+++ b/cpp/test/Ice/stream/Client.cpp
@@ -175,6 +175,9 @@ run(int, char**, const Ice::CommunicatorPtr& communicator)
out->write(true);
out->endEncapsulation();
out->finished(data);
+ pair<const Ice::Byte*, const Ice::Byte*> d = out->finished();
+ test(d.second - d.first == data.size());
+ test(vector<Ice::Byte>(d.first, d.second) == data);
out = 0;
in = Ice::createInputStream(communicator, data);