234 lines
8.2 KiB
C++
234 lines
8.2 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "net_base.hxx"
|
|
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
|
|
#include <o3tl/string_view.hxx>
|
|
#include <rtl/ustring.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
|
|
namespace net_uno
|
|
{
|
|
namespace
|
|
{
|
|
const std::unordered_map<std::u16string_view, std::u16string_view> s_typeNames{
|
|
{ u"System.Void", u"void" },
|
|
{ u"System.Boolean", u"boolean" },
|
|
{ u"System.Char", u"char" },
|
|
{ u"System.SByte", u"byte" },
|
|
{ u"System.Int16", u"short" },
|
|
{ u"System.UInt16", u"unsigned short" },
|
|
{ u"System.Int32", u"long" },
|
|
{ u"System.UInt32", u"unsigned long" },
|
|
{ u"System.Int64", u"hyper" },
|
|
{ u"System.UInt64", u"unsigned hyper" },
|
|
{ u"System.Single", u"float" },
|
|
{ u"System.Double", u"double" },
|
|
{ u"System.String", u"string" },
|
|
{ u"System.Type", u"type" },
|
|
{ u"com.sun.star.uno.Any", u"any" },
|
|
{ u"com.sun.star.uno.UnoException", u"com.sun.star.uno.Exception" },
|
|
{ u"com.sun.star.uno.IQueryInterface", u"com.sun.star.uno.XInterface" },
|
|
};
|
|
|
|
const std::unordered_map<OUString, typelib_TypeClass> s_typeClasses{
|
|
{ u"System.Void"_ustr, typelib_TypeClass_VOID },
|
|
{ u"System.Boolean"_ustr, typelib_TypeClass_BOOLEAN },
|
|
{ u"System.Char"_ustr, typelib_TypeClass_CHAR },
|
|
{ u"System.SByte"_ustr, typelib_TypeClass_BYTE },
|
|
{ u"System.Int16"_ustr, typelib_TypeClass_SHORT },
|
|
{ u"System.UInt16"_ustr, typelib_TypeClass_UNSIGNED_SHORT },
|
|
{ u"System.Int32"_ustr, typelib_TypeClass_LONG },
|
|
{ u"System.UInt32"_ustr, typelib_TypeClass_UNSIGNED_LONG },
|
|
{ u"System.Int64"_ustr, typelib_TypeClass_HYPER },
|
|
{ u"System.UInt64"_ustr, typelib_TypeClass_UNSIGNED_HYPER },
|
|
{ u"System.Single"_ustr, typelib_TypeClass_FLOAT },
|
|
{ u"System.Double"_ustr, typelib_TypeClass_DOUBLE },
|
|
{ u"System.String"_ustr, typelib_TypeClass_STRING },
|
|
{ u"System.Type"_ustr, typelib_TypeClass_TYPE },
|
|
{ u"com.sun.star.uno.Any"_ustr, typelib_TypeClass_ANY },
|
|
};
|
|
|
|
void map_uno_type_to_net(typelib_TypeDescriptionReference* pTDRef, OUStringBuffer& buffer)
|
|
{
|
|
switch (pTDRef->eTypeClass)
|
|
{
|
|
case typelib_TypeClass_VOID:
|
|
buffer.append(u"System.Void");
|
|
break;
|
|
case typelib_TypeClass_CHAR:
|
|
buffer.append(u"System.Char");
|
|
break;
|
|
case typelib_TypeClass_BOOLEAN:
|
|
buffer.append(u"System.Boolean");
|
|
break;
|
|
case typelib_TypeClass_BYTE:
|
|
buffer.append(u"System.SByte");
|
|
break;
|
|
case typelib_TypeClass_SHORT:
|
|
buffer.append(u"System.Int16");
|
|
break;
|
|
case typelib_TypeClass_UNSIGNED_SHORT:
|
|
buffer.append(u"System.UInt16");
|
|
break;
|
|
case typelib_TypeClass_LONG:
|
|
buffer.append(u"System.Int32");
|
|
break;
|
|
case typelib_TypeClass_UNSIGNED_LONG:
|
|
buffer.append(u"System.UInt32");
|
|
break;
|
|
case typelib_TypeClass_HYPER:
|
|
buffer.append(u"System.Int64");
|
|
break;
|
|
case typelib_TypeClass_UNSIGNED_HYPER:
|
|
buffer.append(u"System.UInt64");
|
|
break;
|
|
case typelib_TypeClass_FLOAT:
|
|
buffer.append(u"System.Single");
|
|
break;
|
|
case typelib_TypeClass_DOUBLE:
|
|
buffer.append(u"System.Double");
|
|
break;
|
|
case typelib_TypeClass_STRING:
|
|
buffer.append(u"System.String");
|
|
break;
|
|
case typelib_TypeClass_TYPE:
|
|
buffer.append(u"System.Type");
|
|
break;
|
|
case typelib_TypeClass_ANY:
|
|
buffer.append(u"com.sun.star.uno.Any");
|
|
break;
|
|
|
|
case typelib_TypeClass_ENUM:
|
|
case typelib_TypeClass_EXCEPTION:
|
|
// These have the same name on both sides
|
|
buffer.append(OUString::unacquired(&pTDRef->pTypeName));
|
|
break;
|
|
|
|
case typelib_TypeClass_STRUCT:
|
|
// These have the same name on both sides
|
|
// TODO: What about polymorphic structs? Merge this with above cases if fine
|
|
buffer.append(OUString::unacquired(&pTDRef->pTypeName));
|
|
break;
|
|
|
|
case typelib_TypeClass_INTERFACE:
|
|
{
|
|
// These have the same name on both sides
|
|
if (u"com.sun.star.uno.XInterface"_ustr.equals(pTDRef->pTypeName))
|
|
// Except XInterface, which does not exist on the .NET side
|
|
buffer.append(u"com.sun.star.uno.IQueryInterface");
|
|
else
|
|
buffer.append(OUString::unacquired(&pTDRef->pTypeName));
|
|
break;
|
|
}
|
|
|
|
case typelib_TypeClass_SEQUENCE:
|
|
{
|
|
TypeDescHolder seqType(pTDRef);
|
|
typelib_TypeDescriptionReference* pElementTDRef
|
|
= reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType;
|
|
map_uno_type_to_net(pElementTDRef, buffer);
|
|
buffer.append(u"[]");
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
throw BridgeRuntimeError(SAL_WHERE, "could not map given type info "
|
|
+ OUString::unacquired(&pTDRef->pTypeName));
|
|
}
|
|
}
|
|
}
|
|
|
|
void map_net_type_to_uno(std::u16string_view sTypeName, OUStringBuffer& buffer)
|
|
{
|
|
size_t bracketsStart = sTypeName.find_last_not_of(u"[]");
|
|
bool isSequence = bracketsStart != std::u16string_view::npos;
|
|
std::u16string_view sBrackets = isSequence ? sTypeName.substr(bracketsStart + 1) : u"";
|
|
std::u16string_view sFullName = isSequence ? sTypeName.substr(0, bracketsStart + 1) : sTypeName;
|
|
|
|
size_t genericsStart = sFullName.find_first_of(u'<');
|
|
size_t genericsEnd = sFullName.find_last_of(u'>');
|
|
bool hasGenerics = genericsStart != std::u16string_view::npos;
|
|
std::u16string_view sGenericParams
|
|
= hasGenerics ? sFullName.substr(genericsStart + 1, genericsEnd - genericsStart - 1) : u"";
|
|
std::u16string_view sBaseName = hasGenerics ? sFullName.substr(0, genericsStart) : sFullName;
|
|
|
|
// Sequence brackets go at the beginning of UNO name
|
|
for (size_t i = 0; i < sBrackets.size() / 2; i++)
|
|
buffer.append(u"[]");
|
|
|
|
// Builtin types
|
|
auto it = s_typeNames.find(sBaseName);
|
|
if (it != s_typeNames.end())
|
|
{
|
|
buffer.append(it->second);
|
|
}
|
|
else
|
|
{
|
|
buffer.append(sBaseName);
|
|
if (hasGenerics)
|
|
{
|
|
buffer.append(u'<');
|
|
for (size_t i = 0; i != std::string_view::npos;)
|
|
{
|
|
std::u16string_view genericParam(o3tl::getToken(sGenericParams, u',', i));
|
|
map_net_type_to_uno(genericParam, buffer);
|
|
if (i != std::string_view::npos)
|
|
buffer.append(u',');
|
|
}
|
|
buffer.append(u'>');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
OUString map_uno_type_to_net(typelib_TypeDescriptionReference* pTDRef)
|
|
{
|
|
OUStringBuffer buffer;
|
|
map_uno_type_to_net(pTDRef, buffer);
|
|
return buffer.makeStringAndClear();
|
|
}
|
|
|
|
typelib_TypeDescriptionReference* map_net_type_to_uno(const OUString& sTypeName)
|
|
{
|
|
typelib_TypeDescriptionReference* retVal = nullptr;
|
|
|
|
// Simple types
|
|
auto it = s_typeClasses.find(sTypeName);
|
|
if (it != s_typeClasses.end())
|
|
{
|
|
retVal = *typelib_static_type_getByTypeClass(it->second);
|
|
typelib_typedescriptionreference_acquire(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
// Complex types (structs, interfaces, sequences)
|
|
OUStringBuffer buffer;
|
|
map_net_type_to_uno(sTypeName, buffer);
|
|
OUString convertedName = buffer.makeStringAndClear();
|
|
|
|
typelib_TypeDescription* pTD = nullptr;
|
|
typelib_typedescription_getByName(&pTD, convertedName.pData);
|
|
if (pTD)
|
|
{
|
|
retVal = pTD->pWeakRef;
|
|
typelib_typedescriptionreference_acquire(retVal);
|
|
typelib_typedescription_release(pTD);
|
|
return retVal;
|
|
}
|
|
|
|
throw BridgeRuntimeError(SAL_WHERE, "could not map given type name " + sTypeName);
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|