diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2006-05-01 18:31:55 +0000 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2006-05-01 18:31:55 +0000 |
commit | 75ae8f6e9822d23c83c5e1efec31a82d27a0047b (patch) | |
tree | 59e538a9a7e601768574e3179390a73fbb0b933b /cppe | |
parent | removing redundant 'Client' portion from filter property names (diff) | |
download | ice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.tar.bz2 ice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.tar.xz ice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.zip |
Added ability to configure string converters
Diffstat (limited to 'cppe')
-rw-r--r-- | cppe/include/IceE/BasicStream.h | 143 | ||||
-rw-r--r-- | cppe/include/IceE/Initialize.h | 3 | ||||
-rwxr-xr-x | cppe/include/IceE/StringConverter.h | 87 | ||||
-rw-r--r-- | cppe/src/IceE/BasicStream.cpp | 116 | ||||
-rwxr-xr-x | cppe/src/IceE/Connection.cpp | 23 | ||||
-rw-r--r-- | cppe/src/IceE/Incoming.cpp | 3 | ||||
-rw-r--r-- | cppe/src/IceE/Outgoing.cpp | 4 | ||||
-rw-r--r-- | cppe/test/IceE/custom/Client.cpp | 3 | ||||
-rw-r--r-- | cppe/test/IceE/custom/Collocated.cpp | 3 | ||||
-rw-r--r-- | cppe/test/IceE/custom/Makefile | 9 | ||||
-rw-r--r-- | cppe/test/IceE/custom/Server.cpp | 3 | ||||
-rw-r--r-- | cppe/test/IceE/custom/StringConverterI.cpp | 102 | ||||
-rw-r--r-- | cppe/test/IceE/custom/StringConverterI.h | 43 |
13 files changed, 510 insertions, 32 deletions
diff --git a/cppe/include/IceE/BasicStream.h b/cppe/include/IceE/BasicStream.h index fc968be6833..289f30b2839 100644 --- a/cppe/include/IceE/BasicStream.h +++ b/cppe/include/IceE/BasicStream.h @@ -16,6 +16,7 @@ #include <IceE/AutoArray.h> #include <IceE/Protocol.h> #include <IceE/Unicode.h> +#include <IceE/StringConverter.h> namespace Ice { @@ -33,11 +34,55 @@ class ICE_API BasicStream : public Buffer { public: - BasicStream(Instance* instance, int messageSizeMax) : + class UTF8BufferI : public Ice::UTF8Buffer + { + public: + + UTF8BufferI(BasicStream& stream) : + _stream(stream) + { + } + + Ice::Byte* + getMoreBytes(size_t howMany, Ice::Byte* firstUnused) + { + assert(howMany > 0); + + if(firstUnused != 0) + { + // + // Return unused bytes + // + _stream.b.resize(firstUnused - _stream.b.begin()); + } + + // + // Index of first unused byte + // + Container::size_type pos = _stream.b.size(); + + // + // Since resize may reallocate the buffer, when firstUnused != 0, the + // return value can be != firstUnused + // + _stream.resize(pos + howMany); + + return &_stream.b[pos]; + } + + private: + + BasicStream& _stream; + }; + + BasicStream(Instance* instance, int messageSizeMax, Ice::StringConverterPtr stringConverter, + Ice::WstringConverterPtr wstringConverter) : _instance(instance), _currentReadEncaps(0), _currentWriteEncaps(0), _messageSizeMax(messageSizeMax), + _stringConverter(stringConverter), + _wstringConverter(wstringConverter), _seqDataStack(0) { // Inlined for performance reasons. @@ -254,6 +299,32 @@ public: } } + void rewriteSize(Ice::Int v, Container::iterator dest) + { + assert(v >= 0); + if(v > 254) + { + *dest++ = Ice::Byte(255); +#ifdef ICE_BIG_ENDIAN + const Ice::Byte* src = reinterpret_cast<const Ice::Byte*>(&v) + sizeof(Ice::Int) - 1; + *dest++ = *src--; + *dest++ = *src--; + *dest++ = *src--; + *dest = *src; +#else + const Ice::Byte* src = reinterpret_cast<const Ice::Byte*>(&v); + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest = *src; +#endif + } + else + { + *dest = static_cast<Ice::Byte>(v); + } + } + void readSize(Ice::Int& v) // Inlined for performance reasons. { @@ -418,16 +489,24 @@ public: // void write(const char*); + void writeConverted(const std::string& v); void write(const std::string& v) { - Ice::Int sz = static_cast<Ice::Int>(v.size()); - writeSize(sz); - if(sz > 0) - { - Container::size_type pos = b.size(); - resize(pos + sz); - memcpy(&b[pos], v.c_str(), sz); - } + Ice::Int sz = static_cast<Ice::Int>(v.size()); + if(sz > 0 && _stringConverter) + { + writeConverted(v); + } + else + { + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + sz); + memcpy(&b[pos], v.data(), sz); + } + } } void write(const std::string*, const std::string*); void read(std::string& v) @@ -440,8 +519,15 @@ public: { throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); } - std::string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); -// v.assign(reinterpret_cast<const char*>(&(*i)), sz); + if(_stringConverter) + { + _stringConverter->fromUTF8(i, i + sz, v); + } + else + { + std::string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v); +// v.assign(reinterpret_cast<const char*>(&(*i)), sz); + } i += sz; } else @@ -451,16 +537,24 @@ public: } void read(std::vector<std::string>&); + void writeConverted(const std::wstring& v); void write(const std::wstring& v) { - std::string s = IceUtil::wstringToString(v); - Ice::Int sz = static_cast<Ice::Int>(s.size()); - writeSize(sz); - if(sz > 0) + if(v.size() > 0 && _wstringConverter) { - Container::size_type pos = b.size(); - resize(pos + sz); - memcpy(&b[pos], s.c_str(), sz); + writeConverted(v); + } + else + { + std::string s = IceUtil::wstringToString(v); + Ice::Int sz = static_cast<Ice::Int>(s.size()); + writeSize(sz); + if(sz > 0) + { + Container::size_type pos = b.size(); + resize(pos + sz); + memcpy(&b[pos], s.data(), sz); + } } } void write(const std::wstring*, const std::wstring*); @@ -474,8 +568,15 @@ public: { throwUnmarshalOutOfBoundsException(__FILE__, __LINE__); } - std::string s(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz); - IceUtil::stringToWstring(s).swap(v); + if(_wstringConverter) + { + _wstringConverter->fromUTF8(i, i + sz, v); + } + else + { + std::string s(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz); + IceUtil::stringToWstring(s).swap(v); + } i += sz; } else @@ -556,6 +657,8 @@ private: Container::size_type _writeSlice; const Container::size_type _messageSizeMax; + const Ice::StringConverterPtr _stringConverter; + const Ice::WstringConverterPtr _wstringConverter; struct SeqData { diff --git a/cppe/include/IceE/Initialize.h b/cppe/include/IceE/Initialize.h index 3b25713c0c9..0d186ecebb2 100644 --- a/cppe/include/IceE/Initialize.h +++ b/cppe/include/IceE/Initialize.h @@ -14,6 +14,7 @@ #include <IceE/PropertiesF.h> #include <IceE/LoggerF.h> #include <IceE/InstanceF.h> +#include <IceE/StringConverter.h> #include <IceE/BuiltinSequences.h> namespace Ice @@ -37,6 +38,8 @@ struct InitializationData PropertiesPtr properties; LoggerPtr logger; Context defaultContext; + StringConverterPtr stringConverter; + WstringConverterPtr wstringConverter; }; ICE_API CommunicatorPtr initialize(int&, char*[], InitializationData = InitializationData(), Int = ICEE_INT_VERSION); diff --git a/cppe/include/IceE/StringConverter.h b/cppe/include/IceE/StringConverter.h new file mode 100755 index 00000000000..3c50dabf835 --- /dev/null +++ b/cppe/include/IceE/StringConverter.h @@ -0,0 +1,87 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_STRING_CONVERTER_H +#define ICE_STRING_CONVERTER_H + +#include <IceE/Config.h> +#include <IceE/Exception.h> +#include <IceE/Shared.h> +#include <IceE/Handle.h> + +#include <string> + +namespace Ice +{ + +// +// Provides bytes to toUTF8. Raises MemoryLimitException when too many +// bytes are requested. +// +class ICE_API UTF8Buffer +{ +public: + virtual Byte* getMoreBytes(size_t howMany, Byte* firstUnused) = 0; + + virtual ~UTF8Buffer() {} +}; + +// +// A StringConverter converts narrow or wide-strings to and from UTF-8 byte sequences. +// It's used by the communicator during marshaling (toUTF8) and unmarshaling (fromUTF8). +// It report errors by raising StringConversionFailed or MemoryLimitException. +// +template<typename charT> +class BasicStringConverter : public IceUtil::Shared +{ +public: + + // + // Returns a pointer to byte after the last written byte (which may be + // past the last byte returned by getMoreBytes). + // + virtual Byte* toUTF8(const charT* sourceStart, const charT* sourceEnd, + UTF8Buffer&) const = 0; + + // + // This fromUTF8 function allocates the result (targetStart and targetEnd are + // out parameters); when it succeeds, the caller is responsible to free the + // allocated target with freeTarget. + // This way, an implementation of fromUTF8 using iconv() can use a single iconv_t + // even when it discovers during conversion that it needs a larger target buffer. + // + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + const charT*& targetStart, const charT*& targetEnd) const = 0; + + virtual void freeTarget(const charT* targetStart) const = 0; + + + // + // You may want to override this fromUTF8 function to provide a more efficient + // implementation, without a temporary charT buffer. + // + virtual void fromUTF8(const Byte* sourceStart, const Byte* sourceEnd, + std::basic_string<charT>& target) const + { + const charT* targetStart = 0; + const charT* targetEnd = 0; + fromUTF8(sourceStart, sourceEnd, targetStart, targetEnd); + std::basic_string<charT> s(targetStart, static_cast<size_t>(targetEnd - targetStart)); + freeTarget(targetStart); + s.swap(target); + } +}; + +typedef BasicStringConverter<char> StringConverter; +typedef IceUtil::Handle<StringConverter> StringConverterPtr; + +typedef BasicStringConverter<wchar_t> WstringConverter; +typedef IceUtil::Handle<WstringConverter> WstringConverterPtr; +} +#endif diff --git a/cppe/src/IceE/BasicStream.cpp b/cppe/src/IceE/BasicStream.cpp index e39fa2053a2..611f9bc9b78 100644 --- a/cppe/src/IceE/BasicStream.cpp +++ b/cppe/src/IceE/BasicStream.cpp @@ -1291,6 +1291,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); @@ -1328,6 +1386,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); diff --git a/cppe/src/IceE/Connection.cpp b/cppe/src/IceE/Connection.cpp index 9b76b84b31a..08b13996902 100755 --- a/cppe/src/IceE/Connection.cpp +++ b/cppe/src/IceE/Connection.cpp @@ -578,7 +578,8 @@ Ice::Connection::abortBatchRequest() // safe old requests in the batch stream, as they might be // corrupted due to incomplete marshaling. // - BasicStream dummy(_instance.get(), _instance->messageSizeMax()); + BasicStream dummy(_instance.get(), _instance->messageSizeMax(), _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter); _batchStream.swap(dummy); _batchRequestNum = 0; @@ -697,7 +698,8 @@ Ice::Connection::flushBatchRequests() // // Reset the batch stream, and notify that flushing is over. // - BasicStream dummy(_instance.get(), _instance->messageSizeMax()); + BasicStream dummy(_instance.get(), _instance->messageSizeMax(), _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter); _batchStream.swap(dummy); _batchRequestNum = 0; _batchStreamInUse = false; @@ -912,10 +914,12 @@ Ice::Connection::Connection(const InstancePtr& instance, _in(_instance.get(), this, _stream, adapter), #endif #ifndef ICEE_PURE_BLOCKING_CLIENT - _stream(_instance.get(), _instance->messageSizeMax()), + _stream(_instance.get(), _instance->messageSizeMax(), _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter), #endif #ifdef ICEE_HAS_BATCH - _batchStream(_instance.get(), _instance->messageSizeMax()), + _batchStream(_instance.get(), _instance->messageSizeMax(), _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter), _batchStreamInUse(false), _batchRequestNum(0), #endif @@ -1054,7 +1058,9 @@ Ice::Connection::validate() #ifndef ICEE_PURE_CLIENT if(active) { - BasicStream os(_instance.get(), _instance->messageSizeMax()); + BasicStream os(_instance.get(), _instance->messageSizeMax(), + _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter); os.write(magic[0]); os.write(magic[1]); os.write(magic[2]); @@ -1083,7 +1089,9 @@ Ice::Connection::validate() else #endif { - BasicStream is(_instance.get(), _instance->messageSizeMax()); + BasicStream is(_instance.get(), _instance->messageSizeMax(), + _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter); is.b.resize(headerSize); is.i = is.b.begin(); try @@ -1353,7 +1361,8 @@ Ice::Connection::initiateShutdown() const // // Before we shut down, we send a close connection message. // - BasicStream os(_instance.get(), _instance->messageSizeMax()); + BasicStream os(_instance.get(), _instance->messageSizeMax(), _instance->initializationData().stringConverter, + _instance->initializationData().wstringConverter); os.write(magic[0]); os.write(magic[1]); os.write(magic[2]); diff --git a/cppe/src/IceE/Incoming.cpp b/cppe/src/IceE/Incoming.cpp index f9de4efb110..b986dbf3a2e 100644 --- a/cppe/src/IceE/Incoming.cpp +++ b/cppe/src/IceE/Incoming.cpp @@ -25,7 +25,8 @@ using namespace Ice; using namespace IceInternal; IceInternal::Incoming::Incoming(Instance* inst, Connection* con, BasicStream& is, const ObjectAdapterPtr& adapter) : - _os(inst, inst->messageSizeMax()), + _os(inst, inst->messageSizeMax(), inst->initializationData().stringConverter, + inst->initializationData().wstringConverter), _is(is), _connection(con) { diff --git a/cppe/src/IceE/Outgoing.cpp b/cppe/src/IceE/Outgoing.cpp index 0da4ad89209..6e1d64206b6 100644 --- a/cppe/src/IceE/Outgoing.cpp +++ b/cppe/src/IceE/Outgoing.cpp @@ -49,7 +49,9 @@ IceInternal::Outgoing::Outgoing(Connection* connection, Reference* ref, const st _connection(connection), _reference(ref), _state(StateUnsent), - _stream(ref->getInstance().get(), ref->getInstance()->messageSizeMax()) + _stream(ref->getInstance().get(), ref->getInstance()->messageSizeMax(), + ref->getInstance()->initializationData().stringConverter, + ref->getInstance()->initializationData().wstringConverter) { switch(_reference->getMode()) { diff --git a/cppe/test/IceE/custom/Client.cpp b/cppe/test/IceE/custom/Client.cpp index c80c581c5c4..2f90fa23ee4 100644 --- a/cppe/test/IceE/custom/Client.cpp +++ b/cppe/test/IceE/custom/Client.cpp @@ -11,6 +11,7 @@ #include <TestCommon.h> #include <TestApplication.h> #include <Test.h> +#include <StringConverterI.h> using namespace std; @@ -28,6 +29,8 @@ public: { Ice::InitializationData initData; initData.properties = Ice::createProperties(); + initData.stringConverter = new Test::StringConverterI(); + initData.wstringConverter = new Test::WstringConverterI(); loadConfig(initData.properties); initData.logger = getLogger(); diff --git a/cppe/test/IceE/custom/Collocated.cpp b/cppe/test/IceE/custom/Collocated.cpp index 7b440949847..33c128799e1 100644 --- a/cppe/test/IceE/custom/Collocated.cpp +++ b/cppe/test/IceE/custom/Collocated.cpp @@ -12,6 +12,7 @@ #include <TestApplication.h> #include <TestI.h> #include <WstringI.h> +#include <StringConverterI.h> using namespace std; @@ -29,6 +30,8 @@ public: { Ice::InitializationData initData; initData.properties = Ice::createProperties(); + initData.stringConverter = new Test::StringConverterI(); + initData.wstringConverter = new Test::WstringConverterI(); initData.properties->setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); //initData.properties->setProperty("Ice.Trace.Network", "5"); diff --git a/cppe/test/IceE/custom/Makefile b/cppe/test/IceE/custom/Makefile index bb9b1ec76dc..e6d1e41d07e 100644 --- a/cppe/test/IceE/custom/Makefile +++ b/cppe/test/IceE/custom/Makefile @@ -19,14 +19,16 @@ COBJS = Test.o \ Wstring.o \ Client.o \ AllTests.o \ - MyByteSeq.o + MyByteSeq.o \ + StringConverterI.o SOBJS = Test.o \ TestI.o \ Wstring.o \ WstringI.o \ Server.o \ - MyByteSeq.o + MyByteSeq.o \ + StringConverterI.o COLOBJS = Test.o \ TestI.o \ @@ -34,7 +36,8 @@ COLOBJS = Test.o \ WstringI.o \ Collocated.o \ AllTests.o \ - MyByteSeq.o + MyByteSeq.o \ + StringConverterI.o SRCS = $(COBJS:.o=.cpp) \ $(SOBJS:.o=.cpp) \ diff --git a/cppe/test/IceE/custom/Server.cpp b/cppe/test/IceE/custom/Server.cpp index ba435f5310b..1672d2eda42 100644 --- a/cppe/test/IceE/custom/Server.cpp +++ b/cppe/test/IceE/custom/Server.cpp @@ -12,6 +12,7 @@ #include <TestApplication.h> #include <TestI.h> #include <WstringI.h> +#include <StringConverterI.h> using namespace std; @@ -29,6 +30,8 @@ public: { Ice::InitializationData initData; initData.properties = Ice::createProperties(); + initData.stringConverter = new Test::StringConverterI(); + initData.wstringConverter = new Test::WstringConverterI(); initData.properties->setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); //initData.properties->setProperty("Ice.Trace.Network", "5"); diff --git a/cppe/test/IceE/custom/StringConverterI.cpp b/cppe/test/IceE/custom/StringConverterI.cpp new file mode 100644 index 00000000000..118f8cd43ba --- /dev/null +++ b/cppe/test/IceE/custom/StringConverterI.cpp @@ -0,0 +1,102 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <StringConverterI.h> +#include <IceE/Unicode.h> + +Ice::Byte* +Test::StringConverterI::toUTF8(const char* sourceStart, const char* sourceEnd, Ice::UTF8Buffer& buffer) const +{ + size_t size = static_cast<size_t>(sourceEnd - sourceStart); + Ice::Byte* targetStart = buffer.getMoreBytes(size, 0); + Ice::Byte* targetEnd = targetStart + size; + + char* p = const_cast<char*>(sourceEnd); + for(unsigned int i = 0; i < size; ++i) + { + targetStart[i] = *(--p); + } + return targetEnd; +} + +void +Test::StringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, + const char*& targetStart, const char*& targetEnd) const +{ + size_t size = static_cast<size_t>(sourceEnd - sourceStart); + char* buf = new char[size]; + + Ice::Byte* p = const_cast<Ice::Byte*>(sourceEnd); + for(unsigned int i = 0; i < size; ++i) + { + buf[i] = *(--p); + } + + targetStart = buf; + targetEnd = targetStart + size; +} + +void +Test::StringConverterI::freeTarget(const char* target) const +{ + delete[] target; +} + +Ice::Byte* +Test::WstringConverterI::toUTF8(const wchar_t* sourceStart, const wchar_t* sourceEnd, Ice::UTF8Buffer& buffer) const +{ + std::wstring ws(sourceStart, sourceEnd); + std::string s = IceUtil::wstringToString(ws); + + size_t size = s.size(); + Ice::Byte* targetStart = buffer.getMoreBytes(size, 0); + Ice::Byte* targetEnd = targetStart + size; + + char* p = const_cast<char*>(s.c_str() + size); + for(unsigned int i = 0; i < size; ++i) + { + targetStart[i] = static_cast<Ice::Byte>(*(--p)); + } + return targetEnd; +} + +void +Test::WstringConverterI::fromUTF8(const Ice::Byte* sourceStart, const Ice::Byte* sourceEnd, + const wchar_t*& targetStart, const wchar_t*& targetEnd) const +{ + size_t size = static_cast<size_t>(sourceEnd - sourceStart); + std::string s(sourceStart, sourceEnd); + + Ice::Byte* p = const_cast<Ice::Byte*>(sourceEnd); + for(unsigned int i = 0; i < size; ++i) + { + s[i] = *(--p); + } + + std::wstring ws = IceUtil::stringToWstring(s); + size = ws.size(); + wchar_t* buf = new wchar_t[size]; + for(unsigned int i = 0; i < size; ++i) + { + buf[i] = ws[i]; + } + + targetStart = buf; + targetEnd = targetStart + size; +} + +void +Test::WstringConverterI::freeTarget(const wchar_t* target) const +{ +#if defined(_MSC_VER) && _MSC_VER < 1300 + delete[] const_cast<wchar_t*>(target); +#else + delete[] target; +#endif +} diff --git a/cppe/test/IceE/custom/StringConverterI.h b/cppe/test/IceE/custom/StringConverterI.h new file mode 100644 index 00000000000..f30489e5cc0 --- /dev/null +++ b/cppe/test/IceE/custom/StringConverterI.h @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef STRING_CONVERTER_I_H +#define STRING_CONVERTER_I_H + +#include <IceE/StringConverter.h> + +// +// Simple contrived string converters which simply reverse the order of the +// characters being sent. +// + +namespace Test +{ + +class StringConverterI : public Ice::StringConverter +{ +public: + + virtual Ice::Byte* toUTF8(const char*, const char*, Ice::UTF8Buffer&) const; + virtual void fromUTF8(const Ice::Byte*, const Ice::Byte*, const char*&, const char*&) const; + virtual void freeTarget(const char*) const; +}; + +class WstringConverterI : public Ice::WstringConverter +{ +public: + + virtual Ice::Byte* toUTF8(const wchar_t*, const wchar_t*, Ice::UTF8Buffer&) const; + virtual void fromUTF8(const Ice::Byte*, const Ice::Byte*, const wchar_t*&, const wchar_t*&) const; + virtual void freeTarget(const wchar_t*) const; +}; + +} + +#endif |