summaryrefslogtreecommitdiff
path: root/qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp')
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp455
1 files changed, 455 insertions, 0 deletions
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp b/qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp
new file mode 100644
index 0000000000..b515095323
--- /dev/null
+++ b/qpid/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp
@@ -0,0 +1,455 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+#include <windows.h>
+#include <msclr\lock.h>
+#include <oletx2xa.h>
+#include <typeinfo.h>
+#include <string>
+#include <limits>
+#include <iostream>
+
+#include "TypeTranslator.h"
+#include "QpidTypeCheck.h"
+#include "QpidMarshal.h"
+
+namespace Org {
+namespace Apache {
+namespace Qpid {
+namespace Messaging {
+
+ /// <summary>
+ /// Translate between managed and native types.
+ /// </summary>
+
+ //
+ // The given object is a Dictionary.
+ // Add its elements to the qpid map.
+ //
+ void TypeTranslator::ManagedToNative(QpidMap ^ theDictionary,
+ ::qpid::types::Variant::Map & qpidMap)
+ {
+ // iterate the items, converting each to a variant and adding to the map
+ for each (System::Collections::Generic::KeyValuePair
+ <System::String^, System::Object^> kvp in theDictionary)
+ {
+ if (QpidTypeCheck::ObjectIsMap(kvp.Value))
+ {
+ // Recurse on inner map
+ // Allocate a map
+ ::qpid::types::Variant::Map newMap;
+
+ // Add the map variables to the map
+ ManagedToNative((QpidMap ^)kvp.Value, newMap);
+
+ // Create a variant entry for the inner map
+ std::auto_ptr<::qpid::types::Variant> newVariantp(new ::qpid::types::Variant(newMap));
+
+ // Get map's name
+ std::string entryName = QpidMarshal::ToNative(kvp.Key);
+
+ // Add inner map to outer map
+ qpidMap.insert(std::make_pair<std::string, ::qpid::types::Variant>(entryName, *newVariantp));
+ }
+ else if (QpidTypeCheck::ObjectIsList(kvp.Value))
+ {
+ // Recurse on inner list
+ // Allocate a list
+ ::qpid::types::Variant::List newList;
+
+ // Add the List variables to the list
+ ManagedToNative((QpidList ^)kvp.Value, newList);
+
+ // Create a variant entry for the inner map
+ ::qpid::types::Variant::List newVariant(newList);
+
+ //std::auto_ptr<::qpid::types::Variant> newVariantp(new ::qpid::types::Variant(newList));
+
+ // Get list's name
+ std::string entryName = QpidMarshal::ToNative(kvp.Key);
+
+ // Add inner list to outer map
+ qpidMap.insert(std::make_pair<std::string, ::qpid::types::Variant>(entryName, newVariant));
+ }
+ else
+ {
+ // Add a simple native type to map
+ ::qpid::types::Variant entryValue;
+ if (nullptr != kvp.Value)
+ {
+ ManagedToNativeObject(kvp.Value, entryValue);
+ }
+ std::string entryName = QpidMarshal::ToNative(kvp.Key);
+ qpidMap.insert(std::make_pair<std::string, ::qpid::types::Variant>(entryName, entryValue));
+ }
+ }
+ }
+
+
+
+ //
+ // The given object is a List.
+ // Add its elements to the qpid list.
+ //
+ void TypeTranslator::ManagedToNative(QpidList ^ theList,
+ ::qpid::types::Variant::List & qpidList)
+ {
+ // iterate the items, converting each to a variant and adding to the map
+ for each (System::Object ^ listObj in theList)
+ {
+ if (QpidTypeCheck::ObjectIsMap(listObj))
+ {
+ // Recurse on inner map
+ // Allocate a map
+ ::qpid::types::Variant::Map newMap;
+
+ // Add the map variables to the map
+ ManagedToNative((QpidMap ^)listObj, newMap);
+
+ // Create a variant entry for the inner map
+ std::auto_ptr<::qpid::types::Variant> newVariantp(new ::qpid::types::Variant(newMap));
+
+ // Add inner map to outer list
+ qpidList.push_back(*newVariantp);
+ }
+ else if (QpidTypeCheck::ObjectIsList(listObj))
+ {
+ // Recurse on inner list
+ // Allocate a list
+ ::qpid::types::Variant::List newList;
+
+ // Add the List variables to the list
+ ManagedToNative((QpidList ^)listObj, newList);
+
+ // Create a variant entry for the inner list
+ std::auto_ptr<::qpid::types::Variant> newVariantp(new ::qpid::types::Variant(newList));
+
+ // Add inner list to outer list
+ qpidList.push_back(*newVariantp);
+ }
+ else
+ {
+ // Add a simple native type to list
+ ::qpid::types::Variant entryValue;
+ if (nullptr != listObj)
+ {
+ ManagedToNativeObject(listObj, entryValue);
+ }
+ qpidList.push_back(entryValue);
+ }
+ }
+ }
+
+
+
+ //
+ // Returns a variant representing simple native type object.
+ // Not to be called for Map/List objects.
+ //
+ void TypeTranslator::ManagedToNativeObject(System::Object ^ managedValue,
+ ::qpid::types::Variant & qpidVariant)
+ {
+ System::Type ^ typeP = (*managedValue).GetType();
+ System::TypeCode typeCode = System::Type::GetTypeCode( typeP );
+
+ switch (typeCode)
+ {
+ case System::TypeCode::Boolean :
+ qpidVariant = System::Convert::ToBoolean(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Byte :
+ qpidVariant = System::Convert::ToByte(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::UInt16 :
+ qpidVariant = System::Convert::ToUInt16(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::UInt32 :
+ qpidVariant = System::Convert::ToUInt32(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::UInt64 :
+ qpidVariant = System::Convert::ToUInt64(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Char :
+ case System::TypeCode::SByte :
+ qpidVariant = System::Convert::ToSByte(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Int16 :
+ qpidVariant = System::Convert::ToInt16(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Int32 :
+ qpidVariant = System::Convert::ToInt32(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Int64 :
+ qpidVariant = System::Convert::ToInt64(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Single :
+ qpidVariant = System::Convert::ToSingle(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::Double :
+ qpidVariant = System::Convert::ToDouble(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ break;
+
+ case System::TypeCode::String :
+ {
+ std::string rString;
+ System::String ^ rpString;
+
+ rpString = System::Convert::ToString(managedValue, System::Globalization::CultureInfo::InvariantCulture);
+ rString = QpidMarshal::ToNative(rpString);
+ qpidVariant = rString;
+ qpidVariant.setEncoding(QpidMarshal::ToNative("utf8"));
+ }
+ break;
+
+ case System::TypeCode::Object :
+ {
+ //
+ // Derived classes
+ //
+ if ("System.Guid" == typeP->ToString())
+ {
+ cli::array<System::Byte> ^ guidBytes = ((System::Guid)managedValue).ToByteArray();
+ pin_ptr<unsigned char> pinnedBuf = &guidBytes[0];
+ ::qpid::types::Uuid newUuid = ::qpid::types::Uuid(pinnedBuf);
+ qpidVariant = newUuid;
+ }
+ else
+ {
+ throw gcnew System::NotImplementedException();
+ }
+ }
+ break;
+
+ default:
+
+ throw gcnew System::NotImplementedException();
+
+ }
+ }
+
+
+ // Given a user Dictionary and a qpid map,
+ // extract the qpid elements and put them into the dictionary.
+ //
+ void TypeTranslator::NativeToManaged(::qpid::types::Variant::Map & qpidMap,
+ QpidMap ^ dict)
+ {
+ // For each object in the message map,
+ // create a .NET object and add it to the dictionary.
+ for (::qpid::types::Variant::Map::const_iterator i = qpidMap.begin(); i != qpidMap.end(); ++i) {
+ // Get the name
+ System::String ^ elementName = gcnew String(i->first.c_str());
+
+ ::qpid::types::Variant variant = i->second;
+ ::qpid::types::VariantType vType = variant.getType();
+
+ switch (vType)
+ {
+ case ::qpid::types::VAR_VOID:
+ dict[elementName] = nullptr;
+ break;
+
+ case ::qpid::types::VAR_BOOL:
+ dict[elementName] = variant.asBool();
+ break;
+
+ case ::qpid::types::VAR_UINT8:
+ dict[elementName] = variant.asUint8();
+ break;
+
+ case ::qpid::types::VAR_UINT16:
+ dict[elementName] = variant.asUint16();
+ break;
+
+ case ::qpid::types::VAR_UINT32:
+ dict[elementName] = variant.asUint32();
+ break;
+
+ case ::qpid::types::VAR_UINT64:
+ dict[elementName] = variant.asUint64();
+ break;
+
+ case ::qpid::types::VAR_INT8:
+ dict[elementName] = variant.asInt8();
+ break;
+
+ case ::qpid::types::VAR_INT16:
+ dict[elementName] = variant.asInt16();
+ break;
+
+ case ::qpid::types::VAR_INT32:
+ dict[elementName] = variant.asInt32();
+ break;
+
+ case ::qpid::types::VAR_INT64:
+ dict[elementName] = variant.asInt64();
+ break;
+
+ case ::qpid::types::VAR_FLOAT:
+ dict[elementName] = variant.asFloat();
+ break;
+
+ case ::qpid::types::VAR_DOUBLE:
+ dict[elementName] = variant.asDouble();
+ break;
+
+ case ::qpid::types::VAR_STRING:
+ {
+ System::String ^ elementValue = gcnew System::String(variant.asString().c_str());
+ dict[elementName] = elementValue;
+ break;
+ }
+ case ::qpid::types::VAR_MAP:
+ {
+ QpidMap ^ newDict = gcnew QpidMap();
+
+ NativeToManaged(variant.asMap(), newDict);
+
+ dict[elementName] = newDict;
+ break;
+ }
+
+ case ::qpid::types::VAR_LIST:
+ {
+ QpidList ^ newList = gcnew QpidList();
+
+ NativeToManaged(variant.asList(), newList);
+
+ dict[elementName] = newList;
+ break;
+ }
+
+ case ::qpid::types::VAR_UUID:
+ {
+ System::String ^ elementValue = gcnew System::String(variant.asUuid().str().c_str());
+ System::Guid ^ newGuid = System::Guid(elementValue);
+ dict[elementName] = newGuid;
+ }
+ break;
+ }
+ }
+ }
+
+
+ void TypeTranslator::NativeToManaged(::qpid::types::Variant::List & qpidList, QpidList ^ managedList)
+ {
+ // For each object in the qpidList
+ // create a .NET object and add it to the managed List.
+ for (::qpid::types::Variant::List::const_iterator i = qpidList.begin(); i != qpidList.end(); ++i)
+ {
+ ::qpid::types::Variant variant = *i;
+ ::qpid::types::VariantType vType = variant.getType();
+
+ switch (vType)
+ {
+ case ::qpid::types::VAR_VOID:
+ (*managedList).Add(nullptr);
+ break;
+
+ case ::qpid::types::VAR_BOOL:
+ (*managedList).Add(variant.asBool());
+ break;
+
+ case ::qpid::types::VAR_UINT8:
+ (*managedList).Add(variant.asUint8());
+ break;
+
+ case ::qpid::types::VAR_UINT16:
+ (*managedList).Add(variant.asUint16());
+ break;
+
+ case ::qpid::types::VAR_UINT32:
+ (*managedList).Add(variant.asUint32());
+ break;
+
+ case ::qpid::types::VAR_UINT64:
+ (*managedList).Add(variant.asUint64());
+ break;
+
+ case ::qpid::types::VAR_INT8:
+ (*managedList).Add(variant.asInt8());
+ break;
+
+ case ::qpid::types::VAR_INT16:
+ (*managedList).Add(variant.asInt16());
+ break;
+
+ case ::qpid::types::VAR_INT32:
+ (*managedList).Add(variant.asInt32());
+ break;
+
+ case ::qpid::types::VAR_INT64:
+ (*managedList).Add(variant.asInt64());
+ break;
+
+ case ::qpid::types::VAR_FLOAT:
+ (*managedList).Add(variant.asFloat());
+ break;
+
+ case ::qpid::types::VAR_DOUBLE:
+ (*managedList).Add(variant.asDouble());
+ break;
+
+ case ::qpid::types::VAR_STRING:
+ {
+ System::String ^ elementValue = gcnew System::String(variant.asString().c_str());
+ (*managedList).Add(elementValue);
+ break;
+ }
+ case ::qpid::types::VAR_MAP:
+ {
+ QpidMap ^ newDict = gcnew QpidMap();
+
+ NativeToManaged(variant.asMap(), newDict);
+
+ (*managedList).Add(newDict);
+ break;
+ }
+
+ case ::qpid::types::VAR_LIST:
+ {
+ QpidList ^ newList = gcnew QpidList();
+
+ NativeToManaged(variant.asList(), newList);
+
+ (*managedList).Add(newList);
+ break;
+ }
+
+ case ::qpid::types::VAR_UUID:
+ {
+ System::String ^ elementValue = gcnew System::String(variant.asUuid().str().c_str());
+ System::Guid ^ newGuid = System::Guid(elementValue);
+ (*managedList).Add(newGuid);
+ }
+ break;
+ }
+ }
+ }
+}}}}