summaryrefslogtreecommitdiff
path: root/cppe/include
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2006-05-01 18:31:55 +0000
committerDwayne Boone <dwayne@zeroc.com>2006-05-01 18:31:55 +0000
commit75ae8f6e9822d23c83c5e1efec31a82d27a0047b (patch)
tree59e538a9a7e601768574e3179390a73fbb0b933b /cppe/include
parentremoving redundant 'Client' portion from filter property names (diff)
downloadice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.tar.bz2
ice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.tar.xz
ice-75ae8f6e9822d23c83c5e1efec31a82d27a0047b.zip
Added ability to configure string converters
Diffstat (limited to 'cppe/include')
-rw-r--r--cppe/include/IceE/BasicStream.h143
-rw-r--r--cppe/include/IceE/Initialize.h3
-rwxr-xr-xcppe/include/IceE/StringConverter.h87
3 files changed, 213 insertions, 20 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