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