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