1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_cppu.hxx" 30 31 #include "cppu/helper/purpenv/Environment.hxx" 32 33 #include "osl/diagnose.h" 34 #include "uno/lbnames.h" 35 36 #include "typelib/typedescription.h" 37 #include "osl/interlck.h" 38 39 #ifdef debug 40 # define LOG_LIFECYCLE_cppu_helper_purpenv_Base 41 #endif 42 43 #ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Base 44 # include <iostream> 45 # define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) x 46 47 #else 48 # define LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(x) 49 50 #endif 51 52 53 extern "C" { 54 typedef void SAL_CALL EnvFun_P (uno_Environment *); 55 typedef void SAL_CALL EnvFun_PP_P(uno_Environment ** ppHardEnv, uno_Environment *); 56 typedef void SAL_CALL ExtEnv_registerProxyInterface (uno_ExtEnvironment *, 57 void ** ppProxy, 58 uno_freeProxyFunc freeProxy, 59 rtl_uString * pOId, 60 typelib_InterfaceTypeDescription * pTypeDescr); 61 typedef void SAL_CALL ExtEnv_revokeInterface (uno_ExtEnvironment *, 62 void * pInterface); 63 typedef void SAL_CALL ExtEnv_getObjectIdentifier (uno_ExtEnvironment *, 64 rtl_uString **, 65 void *); 66 typedef void SAL_CALL ExtEnv_getRegisteredInterface (uno_ExtEnvironment *, 67 void **, 68 rtl_uString *, 69 typelib_InterfaceTypeDescription *); 70 typedef void SAL_CALL ExtEnv_getRegisteredInterfaces(uno_ExtEnvironment *, 71 void *** pppInterfaces, 72 sal_Int32 * pnLen, 73 uno_memAlloc memAlloc); 74 typedef void SAL_CALL ExtEnv_computeObjectIdentifier(uno_ExtEnvironment *, 75 rtl_uString ** ppOId, 76 void * pInterface); 77 typedef void SAL_CALL ExtEnv_acquireInterface (uno_ExtEnvironment *, 78 void * pInterface); 79 typedef void SAL_CALL ExtEnv_releaseInterface (uno_ExtEnvironment *, 80 void * pInterface); 81 } 82 83 class Base : public cppu::Enterable 84 { 85 public: 86 explicit Base(uno_Environment * pEnv, cppu::Enterable * pEnterable); 87 88 void acquireWeak(void); 89 void releaseWeak(void); 90 void harden (uno_Environment ** ppHardEnv); 91 void acquire (void); 92 void release (void); 93 94 void registerProxyInterface (void ** ppProxy, 95 uno_freeProxyFunc freeProxy, 96 rtl::OUString const & oid, 97 typelib_InterfaceTypeDescription * pTypeDescr); 98 void revokeInterface (void * pInterface); 99 void getObjectIdentifier (void * pInterface, 100 rtl::OUString * pOid); 101 void getRegisteredInterface (void **, 102 rtl::OUString const & oid, 103 typelib_InterfaceTypeDescription *); 104 void getRegisteredInterfaces(void ***, 105 sal_Int32 * pnLen, 106 uno_memAlloc memAlloc); 107 void computeObjectIdentifier(void * pInterface, 108 rtl::OUString * pOid); 109 void acquireInterface (void * pInterface); 110 void releaseInterface (void * pInterface); 111 112 virtual void v_enter (void); 113 virtual void v_leave (void); 114 virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); 115 virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); 116 virtual int v_isValid (rtl::OUString * pReason); 117 118 protected: 119 oslInterlockedCount m_nRef; 120 uno_Environment * m_pEnv; 121 cppu::Enterable * m_pEnterable; 122 123 EnvFun_P * m_env_acquire; 124 EnvFun_P * m_env_release; 125 EnvFun_PP_P * m_env_harden; 126 EnvFun_P * m_env_acquireWeak; 127 EnvFun_P * m_env_releaseWeak; 128 129 ExtEnv_registerProxyInterface * m_env_registerProxyInterface; 130 ExtEnv_revokeInterface * m_env_revokeInterface; 131 ExtEnv_getObjectIdentifier * m_env_getObjectIdentifier; 132 ExtEnv_getRegisteredInterface * m_env_getRegisteredInterface; 133 ExtEnv_getRegisteredInterfaces * m_env_getRegisteredInterfaces; 134 ExtEnv_computeObjectIdentifier * m_env_computeObjectIdentifier; 135 ExtEnv_acquireInterface * m_env_acquireInterface; 136 ExtEnv_releaseInterface * m_env_releaseInterface; 137 138 virtual ~Base(); 139 }; 140 141 extern "C" { 142 static void SAL_CALL s_acquire(uno_Environment * pEnv) //SAL_THROW_EXTERN_C() 143 { 144 Base * pBase = static_cast<Base *>(pEnv->pReserved); 145 pBase->acquire(); 146 } 147 148 static void SAL_CALL s_release(uno_Environment * pEnv) SAL_THROW_EXTERN_C() 149 { 150 Base * pBase = static_cast<Base *>(pEnv->pReserved); 151 pBase->release(); 152 } 153 154 static void SAL_CALL s_harden(uno_Environment ** ppHardEnv, uno_Environment * pEnv) SAL_THROW_EXTERN_C() 155 { 156 Base * pBase = static_cast<Base *>(pEnv->pReserved); 157 pBase->harden(ppHardEnv); 158 } 159 160 static void SAL_CALL s_acquireWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C() 161 { 162 Base * pBase = static_cast<Base *>(pEnv->pReserved); 163 pBase->acquireWeak(); 164 } 165 166 static void SAL_CALL s_releaseWeak(uno_Environment * pEnv) SAL_THROW_EXTERN_C() 167 { 168 Base * pBase = static_cast<Base *>(pEnv->pReserved); 169 pBase->releaseWeak(); 170 } 171 172 173 static void SAL_CALL s_registerProxyInterface(uno_ExtEnvironment * pExtEnv, 174 void ** ppProxy, 175 uno_freeProxyFunc freeProxy, 176 rtl_uString * pOId, 177 typelib_InterfaceTypeDescription * pTypeDescr) 178 { 179 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 180 pBase->registerProxyInterface(ppProxy, freeProxy, pOId, pTypeDescr); 181 } 182 183 static void SAL_CALL s_revokeInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) 184 { 185 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 186 pBase->revokeInterface(pInterface); 187 } 188 189 static void SAL_CALL s_getObjectIdentifier(uno_ExtEnvironment * pExtEnv, 190 rtl_uString ** ppOId, 191 void * pInterface) 192 { 193 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 194 pBase->getObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId)); 195 } 196 197 static void SAL_CALL s_getRegisteredInterface(uno_ExtEnvironment * pExtEnv, 198 void ** ppInterface, 199 rtl_uString * pOId, 200 typelib_InterfaceTypeDescription * pTypeDescr) 201 { 202 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 203 pBase->getRegisteredInterface(ppInterface, pOId, pTypeDescr); 204 } 205 206 static void SAL_CALL s_getRegisteredInterfaces(uno_ExtEnvironment * pExtEnv, 207 void *** pppInterface, 208 sal_Int32 * pnLen, 209 uno_memAlloc memAlloc) 210 { 211 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 212 pBase->getRegisteredInterfaces(pppInterface, pnLen, memAlloc); 213 } 214 215 static void SAL_CALL s_computeObjectIdentifier(uno_ExtEnvironment * pExtEnv, 216 rtl_uString ** ppOId, 217 void * pInterface) 218 { 219 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 220 pBase->computeObjectIdentifier(pInterface, reinterpret_cast<rtl::OUString *>(ppOId)); 221 } 222 223 static void SAL_CALL s_acquireInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) { 224 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 225 pBase->acquireInterface(pInterface); 226 } 227 228 static void SAL_CALL s_releaseInterface(uno_ExtEnvironment * pExtEnv, void * pInterface) { 229 Base * pBase = static_cast<Base *>(pExtEnv->aBase.pReserved); 230 pBase->releaseInterface(pInterface); 231 } 232 233 } 234 235 Base::Base(uno_Environment * pEnv, cppu::Enterable * pEnterable) 236 :m_nRef(1), 237 m_pEnv(pEnv), 238 m_pEnterable (pEnterable), 239 m_env_acquire (pEnv->acquire), 240 m_env_release (pEnv->release), 241 m_env_harden (pEnv->harden), 242 m_env_acquireWeak(pEnv->acquireWeak), 243 m_env_releaseWeak(pEnv->releaseWeak), 244 m_env_registerProxyInterface (pEnv->pExtEnv->registerProxyInterface), 245 m_env_revokeInterface (pEnv->pExtEnv->revokeInterface), 246 m_env_getObjectIdentifier (pEnv->pExtEnv->getObjectIdentifier), 247 m_env_getRegisteredInterface (pEnv->pExtEnv->getRegisteredInterface), 248 m_env_getRegisteredInterfaces(pEnv->pExtEnv->getRegisteredInterfaces), 249 m_env_computeObjectIdentifier(pEnv->pExtEnv->computeObjectIdentifier), 250 m_env_acquireInterface (pEnv->pExtEnv->acquireInterface), 251 m_env_releaseInterface (pEnv->pExtEnv->releaseInterface) 252 { 253 LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::Base(uno_Environment * pEnv)", this)); 254 OSL_ENSURE( 255 rtl_ustr_ascii_compare_WithLength(pEnv->pTypeName->buffer, rtl_str_getLength(UNO_LB_UNO), UNO_LB_UNO) 256 == 0, 257 "### wrong environment type!"); 258 259 pEnv->acquire = s_acquire; 260 pEnv->release = s_release; 261 pEnv->harden = s_harden; 262 pEnv->acquireWeak = s_acquireWeak; 263 pEnv->releaseWeak = s_releaseWeak; 264 265 pEnv->pExtEnv->registerProxyInterface = s_registerProxyInterface; 266 pEnv->pExtEnv->revokeInterface = s_revokeInterface; 267 pEnv->pExtEnv->getObjectIdentifier = s_getObjectIdentifier; 268 pEnv->pExtEnv->getRegisteredInterface = s_getRegisteredInterface; 269 pEnv->pExtEnv->getRegisteredInterfaces = s_getRegisteredInterfaces; 270 pEnv->pExtEnv->computeObjectIdentifier = s_computeObjectIdentifier; 271 pEnv->pExtEnv->acquireInterface = s_acquireInterface; 272 pEnv->pExtEnv->releaseInterface = s_releaseInterface; 273 274 pEnv->pReserved = this; 275 } 276 277 Base::~Base() 278 { 279 LOG_LIFECYCLE_cppu_helper_purpenv_Base_emit(fprintf(stderr, "LIFE: %s -> %p\n", "cppu::helper::purpenv::Base::~Base()", this)); 280 281 m_pEnv->acquire = m_env_acquire; 282 m_pEnv->release = m_env_release; 283 m_pEnv->harden = m_env_harden; 284 m_pEnv->acquireWeak = m_env_acquireWeak; 285 m_pEnv->releaseWeak = m_env_releaseWeak; 286 287 m_pEnv->pReserved = NULL; 288 289 delete m_pEnterable; 290 m_pEnv->release(m_pEnv); 291 } 292 293 void Base::acquire(void) 294 { 295 m_env_acquire(m_pEnv); 296 297 osl_incrementInterlockedCount(&m_nRef); 298 } 299 300 void Base::release(void) 301 { 302 if (osl_decrementInterlockedCount(&m_nRef) == 0) 303 delete this; 304 305 else 306 m_env_release(m_pEnv); 307 } 308 309 void Base::harden(uno_Environment ** ppHardEnv) 310 { 311 m_env_harden(ppHardEnv, m_pEnv); 312 osl_incrementInterlockedCount(&m_nRef); 313 } 314 315 void Base::acquireWeak(void) 316 { 317 m_env_acquireWeak(m_pEnv); 318 } 319 320 void Base::releaseWeak(void) 321 { 322 m_env_releaseWeak(m_pEnv); 323 } 324 325 326 extern "C" { static void s_registerProxyInterface_v(va_list * pParam) 327 { 328 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 329 void ** ppProxy = va_arg(*pParam, void **); 330 uno_freeProxyFunc freeProxy = va_arg(*pParam, uno_freeProxyFunc); 331 rtl_uString * pOId = va_arg(*pParam, rtl_uString *); 332 typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); 333 ExtEnv_registerProxyInterface * pRegisterProxyInterface 334 = va_arg(*pParam, ExtEnv_registerProxyInterface *); 335 336 pRegisterProxyInterface(pExtEnv, ppProxy, freeProxy, pOId, pTypeDescr); 337 }} 338 339 void Base::registerProxyInterface(void ** ppProxy, 340 uno_freeProxyFunc freeProxy, 341 rtl::OUString const & oid, 342 typelib_InterfaceTypeDescription * pTypeDescr) 343 { 344 uno_Environment_invoke(m_pEnv, 345 s_registerProxyInterface_v, 346 m_pEnv->pExtEnv, 347 ppProxy, 348 freeProxy, 349 oid.pData, 350 pTypeDescr, 351 m_env_registerProxyInterface); 352 } 353 354 355 extern "C" { static void s_revokeInterface_v(va_list * pParam) 356 { 357 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 358 void * pInterface = va_arg(*pParam, void *); 359 ExtEnv_revokeInterface * pRevokeInterface = va_arg(*pParam, ExtEnv_revokeInterface *); 360 361 pRevokeInterface(pExtEnv, pInterface); 362 }} 363 364 void Base::revokeInterface(void * pInterface) 365 { 366 uno_Environment_invoke(m_pEnv, 367 s_revokeInterface_v, 368 m_pEnv->pExtEnv, 369 pInterface, 370 m_env_revokeInterface); 371 } 372 373 374 extern "C" { static void s_getObjectIdentifier_v(va_list * pParam) 375 { 376 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 377 void * pInterface = va_arg(*pParam, void *); 378 rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *); 379 ExtEnv_getObjectIdentifier * pGetObjectIdentifier 380 = va_arg(*pParam, ExtEnv_getObjectIdentifier *); 381 382 pGetObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface); 383 }} 384 385 void Base::getObjectIdentifier(void * pInterface, rtl::OUString * pOid) 386 { 387 uno_Environment_invoke(m_pEnv, 388 s_getObjectIdentifier_v, 389 m_pEnv->pExtEnv, 390 pInterface, 391 pOid, 392 m_env_getObjectIdentifier); 393 } 394 395 396 extern "C" { static void s_getRegisteredInterface_v(va_list * pParam) 397 { 398 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 399 void ** ppInterface = va_arg(*pParam, void **); 400 rtl_uString * pOId = va_arg(*pParam, rtl_uString *); 401 typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *); 402 ExtEnv_getRegisteredInterface * pGetRegisteredInterface 403 = va_arg(*pParam, ExtEnv_getRegisteredInterface *); 404 405 pGetRegisteredInterface(pExtEnv, ppInterface, pOId, pTypeDescr); 406 }} 407 408 void Base::getRegisteredInterface(void ** ppInterface, 409 rtl::OUString const & oid, 410 typelib_InterfaceTypeDescription * pTypeDescr) 411 { 412 uno_Environment_invoke(m_pEnv, 413 s_getRegisteredInterface_v, 414 m_pEnv->pExtEnv, 415 ppInterface, 416 oid.pData, 417 pTypeDescr, 418 m_env_getRegisteredInterface); 419 } 420 421 422 extern "C" { static void s_getRegisteredInterfaces_v(va_list * pParam) 423 { 424 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 425 void *** pppInterface = va_arg(*pParam, void ***); 426 sal_Int32 * pnLen = va_arg(*pParam, sal_Int32 *); 427 uno_memAlloc memAlloc = va_arg(*pParam, uno_memAlloc); 428 ExtEnv_getRegisteredInterfaces * pGetRegisteredInterfaces 429 = va_arg(*pParam, ExtEnv_getRegisteredInterfaces *); 430 431 pGetRegisteredInterfaces(pExtEnv, pppInterface, pnLen, memAlloc); 432 }} 433 434 void Base::getRegisteredInterfaces(void *** pppInterface, 435 sal_Int32 * pnLen, 436 uno_memAlloc memAlloc) 437 { 438 uno_Environment_invoke(m_pEnv, 439 s_getRegisteredInterfaces_v, 440 m_pEnv->pExtEnv, 441 pppInterface, 442 pnLen, 443 memAlloc, 444 m_env_getRegisteredInterfaces); 445 } 446 447 448 extern "C" { static void s_computeObjectIdentifier_v(va_list * pParam) 449 { 450 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 451 void * pInterface = va_arg(*pParam, void *); 452 rtl::OUString * pOId = va_arg(*pParam, rtl::OUString *); 453 ExtEnv_computeObjectIdentifier * pComputeObjectIdentifier 454 = va_arg(*pParam, ExtEnv_computeObjectIdentifier *); 455 456 pComputeObjectIdentifier(pExtEnv, reinterpret_cast<rtl_uString **>(pOId), pInterface); 457 }} 458 459 void Base::computeObjectIdentifier(void * pInterface, rtl::OUString * pOid) 460 { 461 uno_Environment_invoke(m_pEnv, 462 s_computeObjectIdentifier_v, 463 m_pEnv->pExtEnv, 464 pInterface, 465 pOid, 466 m_env_computeObjectIdentifier); 467 } 468 469 470 extern "C" { static void s_acquireInterface_v(va_list * pParam) 471 { 472 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 473 void * pInterface = va_arg(*pParam, void *); 474 ExtEnv_acquireInterface * pAcquireInterface 475 = va_arg(*pParam, ExtEnv_acquireInterface *); 476 477 pAcquireInterface(pExtEnv, pInterface); 478 }} 479 480 void Base::acquireInterface(void * pInterface) 481 { 482 uno_Environment_invoke(m_pEnv, s_acquireInterface_v, m_pEnv->pExtEnv, pInterface, m_env_acquireInterface); 483 } 484 485 486 extern "C" { static void s_releaseInterface_v(va_list * pParam) 487 { 488 uno_ExtEnvironment * pExtEnv = va_arg(*pParam, uno_ExtEnvironment *); 489 void * pInterface = va_arg(*pParam, void *); 490 ExtEnv_releaseInterface * pReleaseInterface 491 = va_arg(*pParam, ExtEnv_releaseInterface *); 492 493 pReleaseInterface(pExtEnv, pInterface); 494 }} 495 496 void Base::releaseInterface(void * pInterface) 497 { 498 uno_Environment_invoke(m_pEnv, 499 s_releaseInterface_v, 500 m_pEnv->pExtEnv, 501 pInterface, 502 m_env_releaseInterface); 503 } 504 505 void Base::v_enter(void) 506 { 507 m_pEnterable->enter(); 508 } 509 510 void Base::v_leave(void) 511 { 512 m_pEnterable->leave(); 513 } 514 515 void Base::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) 516 { 517 m_pEnterable->callInto_v(pCallee, pParam); 518 } 519 520 void Base::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) 521 { 522 m_pEnterable->callOut_v(pCallee, pParam); 523 } 524 525 int Base::v_isValid(rtl::OUString * pReason) 526 { 527 return m_pEnterable->isValid(pReason); 528 } 529 530 namespace cppu { namespace helper { namespace purpenv { 531 532 void Environment_initWithEnterable(uno_Environment * pEnvironment, cppu::Enterable * pEnterable) 533 { 534 new Base(pEnvironment, pEnterable); 535 } 536 537 }}} 538