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_idlc.hxx" 30 #include <idlc/astmodule.hxx> 31 #include <idlc/asttypedef.hxx> 32 #include <idlc/astservice.hxx> 33 #include <idlc/astconstant.hxx> 34 #include <idlc/astattribute.hxx> 35 #include <idlc/astinterfacemember.hxx> 36 #ifndef _IDLC_ASTSERVICEEMEMBER_HXX_ 37 #include <idlc/astservicemember.hxx> 38 #endif 39 #include <idlc/astobserves.hxx> 40 #include <idlc/astneeds.hxx> 41 #include <idlc/astsequence.hxx> 42 #include "idlc/astoperation.hxx" 43 44 #include "registry/version.h" 45 #include "registry/writer.hxx" 46 47 using namespace ::rtl; 48 49 sal_Bool AstModule::dump(RegistryKey& rKey) 50 { 51 OUString emptyStr; 52 RegistryKey localKey; 53 if ( getNodeType() == NT_root ) 54 { 55 localKey = rKey; 56 }else 57 { 58 if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) 59 { 60 fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", 61 idlc()->getOptions()->getProgramName().getStr(), 62 getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 63 return sal_False; 64 } 65 } 66 67 sal_uInt16 nConst = getNodeCount(NT_const); 68 69 if ( nConst > 0 ) 70 { 71 RTTypeClass typeClass = RT_TYPE_MODULE; 72 if ( getNodeType() == NT_constants ) 73 typeClass = RT_TYPE_CONSTANTS; 74 75 typereg::Writer aBlob( 76 m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, 77 getDocumentation(), emptyStr, typeClass, 78 m_bPublished, 79 OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, 80 nConst, 0, 0); 81 82 DeclList::const_iterator iter = getIteratorBegin(); 83 DeclList::const_iterator end = getIteratorEnd(); 84 AstDeclaration* pDecl = NULL; 85 sal_uInt16 index = 0; 86 while ( iter != end ) 87 { 88 pDecl = *iter; 89 if ( pDecl->getNodeType() == NT_const && 90 pDecl->isInMainfile() ) 91 { 92 ((AstConstant*)pDecl)->dumpBlob( 93 aBlob, index++, 94 getNodeType() == NT_module && pDecl->isPublished()); 95 } 96 ++iter; 97 } 98 99 sal_uInt32 aBlobSize; 100 void const * pBlob = aBlob.getBlob(&aBlobSize); 101 102 if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, 103 (RegValue)pBlob, aBlobSize)) 104 { 105 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", 106 idlc()->getOptions()->getProgramName().getStr(), 107 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 108 return sal_False; 109 } 110 } else 111 { 112 RTTypeClass typeClass = RT_TYPE_MODULE; 113 if ( getNodeType() == NT_constants ) 114 typeClass = RT_TYPE_CONSTANTS; 115 116 typereg::Writer aBlob( 117 m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, 118 getDocumentation(), emptyStr, typeClass, m_bPublished, 119 OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, 0, 0, 120 0); 121 122 sal_uInt32 aBlobSize; 123 void const * pBlob = aBlob.getBlob(&aBlobSize); 124 125 if ( getNodeType() != NT_root ) 126 { 127 if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, 128 (RegValue)pBlob, aBlobSize)) 129 { 130 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", 131 idlc()->getOptions()->getProgramName().getStr(), 132 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 133 return sal_False; 134 } 135 } 136 } 137 if ( getNodeType() == NT_root ) 138 { 139 localKey.releaseKey(); 140 } 141 return AstDeclaration::dump(rKey); 142 } 143 144 sal_Bool AstTypeDef::dump(RegistryKey& rKey) 145 { 146 OUString emptyStr; 147 RegistryKey localKey; 148 if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) 149 { 150 fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", 151 idlc()->getOptions()->getProgramName().getStr(), 152 getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 153 return sal_False; 154 } 155 156 typereg::Writer aBlob( 157 m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, 158 getDocumentation(), emptyStr, RT_TYPE_TYPEDEF, m_bPublished, 159 OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, 0, 0, 0); 160 aBlob.setSuperTypeName( 161 0, 162 OStringToOUString( 163 getBaseType()->getRelativName(), RTL_TEXTENCODING_UTF8)); 164 165 sal_uInt32 aBlobSize; 166 void const * pBlob = aBlob.getBlob(&aBlobSize); 167 168 if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize)) 169 { 170 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", 171 idlc()->getOptions()->getProgramName().getStr(), 172 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 173 return sal_False; 174 } 175 176 return sal_True; 177 } 178 179 sal_Bool AstService::dump(RegistryKey& rKey) 180 { 181 OUString emptyStr; 182 typereg_Version version = m_bPublished 183 ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0; 184 OString superName; 185 sal_uInt16 constructors = 0; 186 sal_uInt16 properties = 0; 187 sal_uInt16 references = 0; 188 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); 189 ++i) 190 { 191 switch ((*i)->getNodeType()) { 192 case NT_interface: 193 case NT_typedef: 194 version = TYPEREG_VERSION_1; 195 OSL_ASSERT(superName.getLength() == 0); 196 superName = (*i)->getRelativName(); 197 break; 198 199 case NT_operation: 200 OSL_ASSERT(getNodeType() == NT_service); 201 ++constructors; 202 break; 203 204 case NT_property: 205 OSL_ASSERT(getNodeType() == NT_service); 206 ++properties; 207 break; 208 209 case NT_service_member: 210 if (getNodeType() == NT_singleton) { 211 OSL_ASSERT(superName.getLength() == 0); 212 superName = ((AstServiceMember *)(*i))-> 213 getRealService()->getRelativName(); 214 break; 215 } 216 case NT_interface_member: 217 case NT_observes: 218 case NT_needs: 219 OSL_ASSERT(getNodeType() == NT_service); 220 ++references; 221 break; 222 223 default: 224 OSL_ASSERT(false); 225 break; 226 } 227 }} 228 OSL_ASSERT(constructors == 0 || !m_defaultConstructor); 229 if (m_defaultConstructor) { 230 constructors = 1; 231 } 232 RegistryKey localKey; 233 if (rKey.createKey( 234 rtl::OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8), 235 localKey)) { 236 fprintf( 237 stderr, "%s: warning, could not create key '%s' in '%s'\n", 238 idlc()->getOptions()->getProgramName().getStr(), 239 getFullName().getStr(), 240 rtl::OUStringToOString( 241 rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 242 return false; 243 } 244 typereg::Writer writer( 245 version, getDocumentation(), emptyStr, 246 getNodeType() == NT_singleton ? RT_TYPE_SINGLETON : RT_TYPE_SERVICE, 247 m_bPublished, 248 rtl::OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 249 superName.getLength() == 0 ? 0 : 1, properties, constructors, 250 references); 251 if (superName.getLength() != 0) { 252 writer.setSuperTypeName( 253 0, rtl::OStringToOUString(superName, RTL_TEXTENCODING_UTF8)); 254 } 255 sal_uInt16 constructorIndex = 0; 256 sal_uInt16 propertyIndex = 0; 257 sal_uInt16 referenceIndex = 0; 258 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); 259 ++i) 260 { 261 switch ((*i)->getNodeType()) { 262 case NT_operation: 263 // static_cast< AstOperation * >(*i)->dumpBlob( 264 ((AstOperation *)(*i))->dumpBlob( 265 writer, constructorIndex++); 266 break; 267 268 case NT_property: 269 // static_cast< AstAttribute * >(*i)->dumpBlob( 270 ((AstAttribute *)(*i))->dumpBlob( 271 writer, propertyIndex++, 0); 272 break; 273 274 case NT_interface_member: 275 { 276 // AstInterfaceMember * decl = static_cast< AstInterfaceMember *>(*i); 277 AstInterfaceMember * decl = (AstInterfaceMember *)(*i); 278 writer.setReferenceData( 279 referenceIndex++, decl->getDocumentation(), RT_REF_SUPPORTS, 280 (decl->isOptional() 281 ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID), 282 rtl::OStringToOUString( 283 decl->getRealInterface()->getRelativName(), 284 RTL_TEXTENCODING_UTF8)); 285 break; 286 } 287 288 case NT_service_member: 289 if (getNodeType() == NT_service) { 290 // AstServiceMember * decl = static_cast< AstServiceMember * >(*i); 291 AstServiceMember * decl = (AstServiceMember *)(*i); 292 writer.setReferenceData( 293 referenceIndex++, decl->getDocumentation(), RT_REF_EXPORTS, 294 (decl->isOptional() 295 ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID), 296 rtl::OStringToOUString( 297 decl->getRealService()->getRelativName(), 298 RTL_TEXTENCODING_UTF8)); 299 } 300 break; 301 302 case NT_observes: 303 { 304 // AstObserves * decl = static_cast< AstObserves * >(*i); 305 AstObserves * decl = (AstObserves *)(*i); 306 writer.setReferenceData( 307 referenceIndex++, decl->getDocumentation(), RT_REF_OBSERVES, 308 RT_ACCESS_INVALID, 309 rtl::OStringToOUString( 310 decl->getRealInterface()->getRelativName(), 311 RTL_TEXTENCODING_UTF8)); 312 break; 313 } 314 315 case NT_needs: 316 { 317 // AstNeeds * decl = static_cast< AstNeeds * >(*i); 318 AstNeeds * decl = (AstNeeds *)(*i); 319 writer.setReferenceData( 320 referenceIndex++, decl->getDocumentation(), RT_REF_NEEDS, 321 RT_ACCESS_INVALID, 322 rtl::OStringToOUString( 323 decl->getRealService()->getRelativName(), 324 RTL_TEXTENCODING_UTF8)); 325 break; 326 } 327 328 default: 329 OSL_ASSERT( 330 (*i)->getNodeType() == NT_interface 331 || (*i)->getNodeType() == NT_typedef); 332 break; 333 } 334 }} 335 if (m_defaultConstructor) { 336 writer.setMethodData( 337 constructorIndex++, emptyStr, RT_MODE_TWOWAY, 338 emptyStr, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), 339 0, 0); 340 } 341 sal_uInt32 size; 342 void const * blob = writer.getBlob(&size); 343 if (localKey.setValue( 344 emptyStr, RG_VALUETYPE_BINARY, const_cast< void * >(blob), 345 size)) 346 { 347 fprintf( 348 stderr, "%s: warning, could not set value of key \"%s\" in %s\n", 349 idlc()->getOptions()->getProgramName().getStr(), 350 getFullName().getStr(), 351 rtl::OUStringToOString( 352 localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 353 return false; 354 } 355 return true; 356 } 357 358 sal_Bool AstAttribute::dumpBlob( 359 typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex) 360 { 361 RTFieldAccess accessMode = RT_ACCESS_INVALID; 362 363 if (isReadonly()) 364 { 365 accessMode |= RT_ACCESS_READONLY; 366 } else 367 { 368 accessMode |= RT_ACCESS_READWRITE; 369 } 370 if (isOptional()) 371 { 372 accessMode |= RT_ACCESS_OPTIONAL; 373 } 374 if (isBound()) 375 { 376 accessMode |= RT_ACCESS_BOUND; 377 } 378 if (isMayBeVoid()) 379 { 380 accessMode |= RT_ACCESS_MAYBEVOID; 381 } 382 if (isConstrained()) 383 { 384 accessMode |= RT_ACCESS_CONSTRAINED; 385 } 386 if (isTransient()) 387 { 388 accessMode |= RT_ACCESS_TRANSIENT; 389 } 390 if (isMayBeAmbiguous()) 391 { 392 accessMode |= RT_ACCESS_MAYBEAMBIGUOUS; 393 } 394 if (isMayBeDefault()) 395 { 396 accessMode |= RT_ACCESS_MAYBEDEFAULT; 397 } 398 if (isRemoveable()) 399 { 400 accessMode |= RT_ACCESS_REMOVEABLE; 401 } 402 403 OUString name(OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8)); 404 rBlob.setFieldData( 405 index, getDocumentation(), OUString(), accessMode, name, 406 OStringToOUString(getType()->getRelativName(), RTL_TEXTENCODING_UTF8), 407 RTConstValue()); 408 dumpExceptions( 409 rBlob, m_getDocumentation, m_getExceptions, RT_MODE_ATTRIBUTE_GET, 410 methodIndex); 411 dumpExceptions( 412 rBlob, m_setDocumentation, m_setExceptions, RT_MODE_ATTRIBUTE_SET, 413 methodIndex); 414 415 return sal_True; 416 } 417 418 void AstAttribute::dumpExceptions( 419 typereg::Writer & writer, rtl::OUString const & documentation, 420 DeclList const & exceptions, RTMethodMode flags, sal_uInt16 * methodIndex) 421 { 422 if (!exceptions.empty()) { 423 OSL_ASSERT(methodIndex != 0); 424 sal_uInt16 idx = (*methodIndex)++; 425 // exceptions.size() <= SAL_MAX_UINT16 already checked in 426 // AstInterface::dump: 427 writer.setMethodData( 428 idx, documentation, flags, 429 OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8), 430 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), 0, 431 static_cast< sal_uInt16 >(exceptions.size())); 432 sal_uInt16 exceptionIndex = 0; 433 for (DeclList::const_iterator i(exceptions.begin()); 434 i != exceptions.end(); ++i) 435 { 436 writer.setMethodExceptionTypeName( 437 idx, exceptionIndex++, 438 rtl::OStringToOUString( 439 (*i)->getRelativName(), RTL_TEXTENCODING_UTF8)); 440 } 441 } 442 } 443 444 const sal_Char* AstSequence::getRelativName() const 445 { 446 if ( !m_pRelativName ) 447 { 448 m_pRelativName = new OString("[]"); 449 AstDeclaration const * pType = resolveTypedefs( m_pMemberType ); 450 *m_pRelativName += pType->getRelativName(); 451 } 452 453 return m_pRelativName->getStr(); 454 } 455