From 53df223b3e2d08aed1bb70649c1f0269e0639f84 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Thu, 18 Mar 2010 18:37:28 +0000 Subject: QPID-2452: Fixed control over the encoding used when sending a string valued variant. The user is currently responsible for correctly setting any encoding (e.g. utf8). If none is specified it will be transfered as an amqp0-10 vbin. Fixed bug preventing correct assignment of encoding in variants. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@924939 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/client/amqp0_10/Codecs.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'cpp/src/qpid/client') diff --git a/cpp/src/qpid/client/amqp0_10/Codecs.cpp b/cpp/src/qpid/client/amqp0_10/Codecs.cpp index e6d51ae725..3e17fc968b 100644 --- a/cpp/src/qpid/client/amqp0_10/Codecs.cpp +++ b/cpp/src/qpid/client/amqp0_10/Codecs.cpp @@ -25,8 +25,10 @@ #include "qpid/framing/FieldTable.h" #include "qpid/framing/FieldValue.h" #include "qpid/framing/List.h" +#include "qpid/log/Statement.h" #include #include +#include using namespace qpid::framing; using namespace qpid::messaging; @@ -39,6 +41,7 @@ namespace { const std::string iso885915("iso-8859-15"); const std::string utf8("utf8"); const std::string utf16("utf16"); +const std::string binary("binary"); const std::string amqp0_10_binary("amqp0-10:binary"); const std::string amqp0_10_bit("amqp0-10:bit"); const std::string amqp0_10_datetime("amqp0-10:datetime"); @@ -163,8 +166,8 @@ Variant toVariant(boost::shared_ptr in) case 0x96: case 0xa0: case 0xab: - setEncodingFor(out, in->getType()); out = in->get(); + setEncodingFor(out, in->getType()); break; case 0xa8: @@ -188,6 +191,28 @@ Variant toVariant(boost::shared_ptr in) return out; } +boost::shared_ptr convertString(const std::string& value, const std::string& encoding) +{ + bool large = value.size() > std::numeric_limits::max(); + if (encoding.empty() || encoding == amqp0_10_binary || encoding == binary) { + if (large) { + return boost::shared_ptr(new Var32Value(value, 0xa0)); + } else { + return boost::shared_ptr(new Var16Value(value, 0x90)); + } + } else if (encoding == utf8 && !large) { + return boost::shared_ptr(new Str16Value(value)); + } else if (encoding == utf16 && !large) { + return boost::shared_ptr(new Var16Value(value, 0x96)); + } else if (encoding == iso885915 && !large) { + return boost::shared_ptr(new Var16Value(value, 0x94)); + } else { + //either the string is too large for the encoding in amqp 0-10, or the encoding was not recognised + QPID_LOG(warning, "Could not encode " << value.size() << " byte value as " << encoding << ", encoding as vbin32."); + return boost::shared_ptr(new Var32Value(value, 0xa0)); + } +} + boost::shared_ptr toFieldValue(const Variant& in) { boost::shared_ptr out; @@ -204,8 +229,7 @@ boost::shared_ptr toFieldValue(const Variant& in) case VAR_INT64: out = boost::shared_ptr(new Integer64Value(in.asInt64())); break; case VAR_FLOAT: out = boost::shared_ptr(new FloatValue(in.asFloat())); break; case VAR_DOUBLE: out = boost::shared_ptr(new DoubleValue(in.asDouble())); break; - //TODO: check encoding (and length?) when deciding what AMQP type to treat string as - case VAR_STRING: out = boost::shared_ptr(new Str16Value(in.asString())); break; + case VAR_STRING: out = convertString(in.asString(), in.getEncoding()); break; case VAR_UUID: out = boost::shared_ptr(new UuidValue(in.asUuid().data())); break; case VAR_MAP: out = boost::shared_ptr(toFieldTableValue(in.asMap())); -- cgit v1.2.1