diff options
Diffstat (limited to 'cpp/src/Ice/BasicStream.cpp')
-rw-r--r-- | cpp/src/Ice/BasicStream.cpp | 118 |
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); |