diff options
author | Benoit Foucher <benoit@zeroc.com> | 2016-09-07 18:09:21 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2016-09-07 18:09:21 +0200 |
commit | 6c2e83d4c5418efa07af0af6d8c1aed1625c74a6 (patch) | |
tree | e874c3a845b1d50a1ad6acc084b49eb4354fcdee /cpp/src/Ice/InputStream.cpp | |
parent | ICE-7316 - JavaScript test/Ice/enum hang (diff) | |
download | ice-6c2e83d4c5418efa07af0af6d8c1aed1625c74a6.tar.bz2 ice-6c2e83d4c5418efa07af0af6d8c1aed1625c74a6.tar.xz ice-6c2e83d4c5418efa07af0af6d8c1aed1625c74a6.zip |
Fixed ICE-7279 - Fixed input stream to use zero-copy for string reads if there's no string converter
Diffstat (limited to 'cpp/src/Ice/InputStream.cpp')
-rw-r--r-- | cpp/src/Ice/InputStream.cpp | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/cpp/src/Ice/InputStream.cpp b/cpp/src/Ice/InputStream.cpp index 7563f412ae4..132012b07b2 100644 --- a/cpp/src/Ice/InputStream.cpp +++ b/cpp/src/Ice/InputStream.cpp @@ -1130,11 +1130,8 @@ Ice::InputStream::read(std::string& v, bool convert) { throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); } - if(convert) - { - readConverted(v, sz); - } - else + + if(!convert || !readConverted(v, sz)) { string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); } @@ -1167,22 +1164,29 @@ Ice::InputStream::read(const char*& vdata, size_t& vsize, bool convert) else { string converted; - readConverted(converted, sz); - if(converted.size() <= static_cast<size_t>(sz)) + if(readConverted(converted, sz)) { - // - // Write converted string directly into buffer - // - std::memcpy(i, converted.data(), converted.size()); - vdata = reinterpret_cast<const char*>(&*i); - vsize = converted.size(); + if(converted.size() <= static_cast<size_t>(sz)) + { + // + // Write converted string directly into buffer + // + std::memcpy(i, converted.data(), converted.size()); + vdata = reinterpret_cast<const char*>(&*i); + vsize = converted.size(); + } + else + { + auto holder = new string(std::move(converted)); + _deleters.push_back([holder] { delete holder; }); + vdata = holder->data(); + vsize = holder->size(); + } } else { - auto holder = new string(std::move(converted)); - _deleters.push_back([holder] { delete holder; }); - vdata = holder->data(); - vsize = holder->size(); + vdata = reinterpret_cast<const char*>(&*i); + vsize = static_cast<size_t>(sz); } i += sz; } @@ -1229,10 +1233,17 @@ Ice::InputStream::read(const char*& vdata, size_t& vsize, string& holder) throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); } - readConverted(holder, sz); + if(readConverted(holder, sz)) + { + vdata = holder.data(); + vsize = holder.size(); + } + else + { + vdata = reinterpret_cast<const char*>(&*i); + vsize = static_cast<size_t>(sz); + } i += sz; - vdata = holder.data(); - vsize = holder.size(); } else { @@ -1243,13 +1254,18 @@ Ice::InputStream::read(const char*& vdata, size_t& vsize, string& holder) } #endif -void +bool Ice::InputStream::readConverted(string& v, int sz) { try { bool converted = false; + // + // NOTE: When using an _instance, we get a const& on the string reference to + // not have to increment unecessarily its reference count. + // + if(_instance) { const StringConverterPtr& stringConverter = _instance->getStringConverter(); @@ -1269,10 +1285,7 @@ Ice::InputStream::readConverted(string& v, int sz) } } - if(!converted) - { - string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); - } + return converted; } catch(const IllegalConversionException& ex) { |