/* -*- 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/.
*/
if (data)
std::memcpy(seq->elements, data, nElements * nElementSize);
return seq;
}
void marshal_data(void* pUnoData, void* pNetData, typelib_TypeDescriptionReference* pTDRef, bool bDestructValue, Bridge& bridge)
{ switch (pTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM:
std::memcpy(pNetData, pUnoData, net_sizeof(pTDRef->eTypeClass)); break; case typelib_TypeClass_STRING:
{
IntPtr* ppNetStr = static_cast<IntPtr*>(pNetData);
rtl_uString* pUnoStr = *static_cast<rtl_uString**>(pUnoData);
if (bDestructValue && pNetData)
std::free(pNetData);
switch (pUnoAny->pType->eTypeClass)
{ case typelib_TypeClass_VOID:
ppNetAny->data = nullptr; break; case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_FLOAT: case typelib_TypeClass_ENUM:
std::memcpy(&ppNetAny->data, pUnoAny->pData, sizeof(IntPtr)); break; case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_DOUBLE:
{
size_t size = net_sizeof(pUnoAny->pType->eTypeClass); if (size <= sizeof(IntPtr))
{
std::memcpy(&ppNetAny->data, pUnoAny->pData, sizeof(IntPtr));
} else
{
IntPtr mem = std::malloc(size);
std::memcpy(mem, pUnoAny->pData, size);
std::free(ppNetAny->data);
ppNetAny->data = mem;
} break;
} case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE:
{
IntPtr mem = std::malloc(net_sizeof(pUnoAny->pType->eTypeClass));
marshal_data(pUnoAny->pData, mem, pUnoAny->pType, bDestructValue, bridge);
std::free(ppNetAny->data);
ppNetAny->data = mem; break;
} case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_INTERFACE: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
marshal_data(pUnoAny->pData, &ppNetAny->data, pUnoAny->pType, bDestructValue,
bridge); break; default:
{ throw BridgeRuntimeError(SAL_WHERE, "could not map "
+ OUString::unacquired(&pUnoAny->pType->pTypeName)
+ " out of an UNO any");
}
} break;
} case typelib_TypeClass_SEQUENCE:
{
Value::Sequence* ppNetSeq = static_cast<Value::Sequence*>(pNetData);
uno_Sequence* pUnoSeq = *static_cast<uno_Sequence**>(pUnoData);
if (bDestructValue && ppNetSeq->data)
std::free(ppNetSeq->data);
switch (pElemTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM:
{
ppNetSeq->data = std::malloc(nNetElemSize * ppNetSeq->length);
std::memcpy(ppNetSeq->data, pUnoSeq->elements, nNetElemSize * ppNetSeq->length); break;
} case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_INTERFACE: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
{
TypeDescHolder elemType(pElemTDRef);
sal_Int32 nUnoElemSize = elemType.get()->nSize;
// Convert each element for (int nPos = 0; nPos < ppNetSeq->length; ++nPos)
{ void* pNetElem = static_cast<char*>(ppNetSeq->data) + (nPos * nNetElemSize); void* pUnoElem = pUnoSeq->elements + (nPos * nUnoElemSize);
marshal_data(pUnoElem, pNetElem, pElemTDRef, bDestructValue, bridge);
} break;
} default:
{ throw BridgeRuntimeError(
SAL_WHERE, "could not map " + OUString::unacquired(&pElemTDRef->pTypeName)
+ " out of an UNO sequence");
}
} break;
} case typelib_TypeClass_INTERFACE:
{
IntPtr* ppNetI = static_cast<IntPtr*>(pNetData);
uno_Interface* pUnoI = *static_cast<uno_Interface**>(pUnoData);
if (pUnoI)
{
Context* pCtx = static_cast<Context*>(bridge.m_net_env->pContext);
// Get oid and type name
rtl_uString* pOid = nullptr;
(*bridge.m_uno_env->getObjectIdentifier)(bridge.m_uno_env, &pOid, pUnoI); const OUString& sOid = OUString::unacquired(&pOid);
OUString sTypeName = map_uno_type_to_net(pTDRef);
// Get the proxy if already created, else create new
*ppNetI = pCtx->lookupInterface(sOid.getStr(), sTypeName.getStr()); if (!*ppNetI)
{
TypeDescHolder type(pTDRef);
typelib_InterfaceTypeDescription* pTD
= reinterpret_cast<typelib_InterfaceTypeDescription*>(type.get());
switch (pMemberTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM:
std::memcpy(pNetField, pUnoField, net_sizeof(pMemberTDRef->eTypeClass)); break; case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_INTERFACE: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
marshal_data(pUnoField, pNetField, pMemberTDRef, bDestructValue, bridge); break; default:
{ throw BridgeRuntimeError(
SAL_WHERE, "could not map " + OUString::unacquired(&pMemberTDRef->pTypeName)
+ " out of an UNO " + OUString::unacquired(&pTDRef->pTypeName));
}
}
nNetOffset += net_sizeof(pMemberTDRef->eTypeClass);
} break;
} default:
{ throw BridgeRuntimeError(SAL_WHERE, "could not map "
+ OUString::unacquired(&pTDRef->pTypeName)
+ " value to .NET");
}
}
}
void unmarshal_data(void* pUnoData, void* pNetData, typelib_TypeDescriptionReference* pTDRef, bool bDestructObject, bool bAssignData, Bridge& bridge)
{ switch (pTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM: if (bAssignData)
std::memcpy(pUnoData, pNetData, net_sizeof(pTDRef->eTypeClass)); break; case typelib_TypeClass_STRING:
{
rtl_uString** ppUnoStr = static_cast<rtl_uString**>(pUnoData);
IntPtr pNetStr = *static_cast<IntPtr*>(pNetData);
if (bDestructObject && ppUnoStr)
rtl_uString_release(*ppUnoStr);
if (bAssignData)
{
*ppUnoStr = nullptr; if (pNetStr)
rtl_uString_newFromStr(ppUnoStr, static_cast<String>(pNetStr)); else
rtl_uString_new(ppUnoStr);
}
switch (pElemTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM: if (bAssignData)
*ppUnoSeq
= alloc_uno_sequence(pNetSeq->length, nNetElemSize, pNetSeq->data); break; case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_INTERFACE: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
{
TypeDescHolder elemType(pElemTDRef);
sal_Int32 nUnoElemSize = elemType.get()->nSize;
// Get the proxy if already created, else create new
*ppUnoI = nullptr;
(*bridge.m_uno_env->getRegisteredInterface)(bridge.m_uno_env, reinterpret_cast<void**>(ppUnoI),
sOid.pData, pInterfaceTD);
if (!*ppUnoI)
*ppUnoI = new NetProxy(bridge, pNetI, pInterfaceTD, sOid);
} else
{
*ppUnoI = nullptr;
}
}
break;
} case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
{ void* pUnoStruct = pUnoData;
IntPtr pNetStruct = *static_cast<IntPtr*>(pNetData);
TypeDescHolder type(pTDRef); if (bDestructObject && pNetStruct)
uno_destructData(pNetStruct, type.get(), nullptr);
typelib_CompoundTypeDescription* pCompTD
= reinterpret_cast<typelib_CompoundTypeDescription*>(type.get()); if (!type.get()->bComplete)
typelib_typedescription_complete( reinterpret_cast<typelib_TypeDescription**>(&pCompTD));
std::vector<std::pair<typelib_TypeDescriptionReference*, sal_Int32>> vecMembers; for (typelib_CompoundTypeDescription* pHierTD = pCompTD; pHierTD;
pHierTD = pHierTD->pBaseTypeDescription)
{ for (int n = pHierTD->nMembers - 1; n >= 0; n--)
{
vecMembers.emplace_back(pHierTD->ppTypeRefs[n], pHierTD->pMemberOffsets[n]);
}
}
switch (pMemberTDRef->eTypeClass)
{ case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_FLOAT: case typelib_TypeClass_DOUBLE: case typelib_TypeClass_ENUM: if (bAssignData)
std::memcpy(pUnoField, pNetField,
net_sizeof(pMemberTDRef->eTypeClass)); break; case typelib_TypeClass_ANY: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_STRING: case typelib_TypeClass_TYPE: case typelib_TypeClass_INTERFACE: case typelib_TypeClass_EXCEPTION: case typelib_TypeClass_STRUCT:
unmarshal_data(pUnoField, pNetField, pMemberTDRef, bDestructObject,
bAssignData, bridge); break; default:
{ throw BridgeRuntimeError(
SAL_WHERE, "could not map " + OUString::unacquired(&pMemberTDRef->pTypeName)
+ " into an UNO " + OUString::unacquired(&pTDRef->pTypeName));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.