summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/BasicStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/BasicStream.cpp')
-rw-r--r--cpp/src/Ice/BasicStream.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp
index bcef19cc5ee..77a48fe5eac 100644
--- a/cpp/src/Ice/BasicStream.cpp
+++ b/cpp/src/Ice/BasicStream.cpp
@@ -29,6 +29,8 @@ using namespace IceInternal;
IceInternal::BasicStream::BasicStream(Instance* instance) :
_instance(instance),
+ _stringConverter(instance->initializationData().stringConverter),
+ _wstringConverter(instance->initializationData().wstringConverter),
_currentReadEncaps(0),
_currentWriteEncaps(0),
_traceSlicing(-1),
@@ -1318,6 +1320,64 @@ IceInternal::BasicStream::write(const char*)
*/
void
+IceInternal::BasicStream::writeConverted(const string& v)
+{
+ //
+ // What is the size of the resulting UTF-8 encoded string?
+ // Impossible to tell, so we guess. If we don't guess correctly,
+ // we'll have to fix the mistake afterwards
+ //
+
+ Int guessedSize = static_cast<Int>(v.size());
+ writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space.
+
+ size_t firstIndex = b.size();
+ UTF8BufferI buffer(*this);
+
+ Byte* lastByte = _stringConverter->toUTF8(v.data(), v.data() + v.size(), buffer);
+ if(lastByte != b.end())
+ {
+ b.resize(lastByte - b.begin());
+ }
+ size_t lastIndex = b.size();
+
+ Int actualSize = static_cast<Int>(lastIndex - firstIndex);
+
+ //
+ // Check against the guess
+ //
+ if(guessedSize != actualSize)
+ {
+ if(guessedSize <= 254 && actualSize > 254)
+ {
+ //
+ // Move the UTF-8 sequence 4 bytes further
+ // Use memmove instead of memcpy since the source and destination typically overlap.
+ //
+ resize(b.size() + 4);
+ std::memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize);
+ }
+ else if(guessedSize > 254 && actualSize <= 254)
+ {
+ //
+ // Move the UTF-8 sequence 4 bytes back
+ //
+ std::memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize);
+ resize(b.size() - 4);
+ }
+
+ if(guessedSize <= 254)
+ {
+ rewriteSize(actualSize, b.begin() + firstIndex - 1);
+ }
+ else
+ {
+ rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4);
+ }
+ }
+}
+
+void
IceInternal::BasicStream::write(const string* begin, const string* end)
{
Int sz = static_cast<Int>(end - begin);
@@ -1355,6 +1415,64 @@ IceInternal::BasicStream::read(vector<string>& v)
}
void
+IceInternal::BasicStream::writeConverted(const wstring& v)
+{
+ //
+ // What is the size of the resulting UTF-8 encoded string?
+ // Impossible to tell, so we guess. If we don't guess correctly,
+ // we'll have to fix the mistake afterwards
+ //
+
+ Int guessedSize = static_cast<Int>(v.size());
+ writeSize(guessedSize); // writeSize() only writes the size; it does not reserve any buffer space.
+
+ size_t firstIndex = b.size();
+ UTF8BufferI buffer(*this);
+
+ Byte* lastByte = _wstringConverter->toUTF8(v.data(), v.data() + v.size(), buffer);
+ if(lastByte != b.end())
+ {
+ b.resize(lastByte - b.begin());
+ }
+ size_t lastIndex = b.size();
+
+ Int actualSize = static_cast<Int>(lastIndex - firstIndex);
+
+ //
+ // Check against the guess
+ //
+ if(guessedSize != actualSize)
+ {
+ if(guessedSize <= 254 && actualSize > 254)
+ {
+ //
+ // Move the UTF-8 sequence 4 bytes further
+ // Use memmove instead of memcpy since the source and destination typically overlap.
+ //
+ resize(b.size() + 4);
+ std::memmove(b.begin() + firstIndex + 4, b.begin() + firstIndex, actualSize);
+ }
+ else if(guessedSize > 254 && actualSize <= 254)
+ {
+ //
+ // Move the UTF-8 sequence 4 bytes back
+ //
+ std::memmove(b.begin() + firstIndex - 4, b.begin() + firstIndex, actualSize);
+ resize(b.size() - 4);
+ }
+
+ if(guessedSize <= 254)
+ {
+ rewriteSize(actualSize, b.begin() + firstIndex - 1);
+ }
+ else
+ {
+ rewriteSize(actualSize, b.begin() + firstIndex - 1 - 4);
+ }
+ }
+}
+
+void
IceInternal::BasicStream::write(const wstring* begin, const wstring* end)
{
Int sz = static_cast<Int>(end - begin);