Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <ctype.h>
22 : #include <stdio.h>
23 :
24 : #include <rtl/strbuf.hxx>
25 :
26 : #include <object.hxx>
27 : #include <globals.hxx>
28 : #include <database.hxx>
29 :
30 0 : TYPEINIT1( SvClassElement, SvPersistBase );
31 :
32 112 : SvClassElement::SvClassElement()
33 : {
34 112 : };
35 :
36 0 : TYPEINIT1( SvMetaClass, SvMetaType );
37 190 : SvMetaClass::SvMetaClass()
38 190 : : aAutomation( true, false )
39 : {
40 190 : }
41 :
42 184 : void SvMetaClass::ReadAttributesSvIdl( SvIdlDataBase & rBase,
43 : SvTokenStream & rInStm )
44 : {
45 184 : SvMetaType::ReadAttributesSvIdl( rBase, rInStm );
46 184 : aAutomation.ReadSvIdl( SvHash_Automation(), rInStm );
47 184 : }
48 :
49 4385 : void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase,
50 : SvTokenStream & rInStm )
51 : {
52 4385 : sal_uInt32 nTokPos = rInStm.Tell();
53 4385 : SvToken * pTok = rInStm.GetToken_Next();
54 :
55 4385 : if( pTok->Is( SvHash_import() ) )
56 : {
57 112 : SvMetaClass * pClass = rBase.ReadKnownClass( rInStm );
58 112 : if( pClass )
59 : {
60 112 : SvClassElementRef xEle = new SvClassElement();
61 112 : xEle->SetClass( pClass );
62 112 : aClassList.push_back( xEle );
63 :
64 112 : if( rInStm.Read( '[' ) )
65 : {
66 59 : pTok = rInStm.GetToken_Next();
67 59 : if( pTok->Is( SvHash_Automation() ) )
68 : {
69 59 : if( rInStm.Read( ']' ) )
70 : {
71 59 : if( xAutomationInterface.Is() )
72 : {
73 : // set error
74 : rBase.SetError( "Automation already set",
75 0 : rInStm.GetToken() );
76 0 : rBase.WriteError( rInStm );
77 : }
78 59 : xAutomationInterface = pClass;
79 59 : xEle->SetAutomation( true );
80 : }
81 : else
82 : {
83 : // set error
84 0 : rBase.SetError( "missing ]", rInStm.GetToken() );
85 0 : rBase.WriteError( rInStm );
86 : }
87 : }
88 : else
89 : {
90 : // set error
91 : rBase.SetError( "only attribute Automation allowed",
92 0 : rInStm.GetToken() );
93 0 : rBase.WriteError( rInStm );
94 : }
95 : }
96 112 : pTok = rInStm.GetToken();
97 112 : if( pTok->IsString() )
98 : {
99 7 : xEle->SetPrefix( pTok->GetString() );
100 7 : rInStm.GetToken_Next();
101 : }
102 112 : return;
103 : }
104 : else
105 : {
106 : // set error
107 0 : rBase.SetError( "unknown imported interface", rInStm.GetToken() );
108 0 : rBase.WriteError( rInStm );
109 : }
110 : }
111 : else
112 : {
113 4273 : rInStm.Seek( nTokPos );
114 4273 : SvMetaType * pType = rBase.ReadKnownType( rInStm );
115 :
116 4273 : bool bOk = false;
117 4273 : SvMetaAttributeRef xAttr;
118 4273 : if( !pType || pType->IsItem() )
119 : {
120 4257 : xAttr = new SvMetaSlot( pType );
121 4257 : if( xAttr->ReadSvIdl( rBase, rInStm ) )
122 4067 : bOk = xAttr->Test( rBase, rInStm );
123 : }
124 : else
125 : {
126 16 : xAttr = new SvMetaAttribute( pType );
127 16 : if( xAttr->ReadSvIdl( rBase, rInStm ) )
128 16 : bOk = xAttr->Test( rBase, rInStm );
129 : }
130 :
131 4273 : if( bOk )
132 4083 : bOk = TestAttribute( rBase, rInStm, *xAttr );
133 4273 : if( bOk )
134 : {
135 4083 : if( !xAttr->GetSlotId().IsSet() )
136 : {
137 5 : SvNumberIdentifier aI;
138 5 : aI.SetValue( rBase.GetUniqueId() );
139 5 : xAttr->SetSlotId( aI );
140 : }
141 4083 : aAttrList.push_back( xAttr );
142 4083 : return;
143 190 : }
144 : }
145 190 : rInStm.Seek( nTokPos );
146 : }
147 :
148 190 : bool SvMetaClass::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm )
149 : {
150 190 : sal_uLong nTokPos = rInStm.Tell();
151 190 : if( SvMetaType::ReadHeaderSvIdl( rBase, rInStm ) && GetType() == TYPE_CLASS )
152 : {
153 190 : bool bOk = true;
154 190 : if( rInStm.Read( ':' ) )
155 : {
156 59 : aSuperClass = rBase.ReadKnownClass( rInStm );
157 59 : bOk = aSuperClass.Is();
158 59 : if( !bOk )
159 : {
160 : // set error
161 : rBase.SetError( "unknown super class",
162 0 : rInStm.GetToken() );
163 0 : rBase.WriteError( rInStm );
164 : }
165 : }
166 190 : if( bOk )
167 : {
168 190 : rBase.Write(OString('.'));
169 190 : bOk = SvMetaName::ReadSvIdl( rBase, rInStm );
170 : }
171 190 : if( bOk )
172 190 : return bOk;
173 : }
174 0 : rInStm.Seek( nTokPos );
175 0 : return false;
176 : }
177 :
178 4458 : bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm,
179 : SvMetaAttribute & rAttr ) const
180 : {
181 4458 : if ( !rAttr.GetRef() && rAttr.IsA( TYPE( SvMetaSlot ) ) )
182 : {
183 : OSL_FAIL( "Neuer Slot : " );
184 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
185 : }
186 :
187 449294 : for( sal_uLong n = 0; n < aAttrList.size(); n++ )
188 : {
189 444836 : SvMetaAttribute * pS = aAttrList[n];
190 444836 : if( pS->GetName().getString() == rAttr.GetName().getString() )
191 : {
192 : // values have to match
193 11 : if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() )
194 : {
195 : OSL_FAIL( "Same Name in MetaClass : " );
196 : OSL_FAIL( pS->GetName().getString().getStr() );
197 : OSL_FAIL( pS->GetSlotId().getString().getStr() );
198 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
199 :
200 0 : OStringBuffer aStr("Attribute's ");
201 0 : aStr.append(pS->GetName().getString());
202 0 : aStr.append(" with different id's");
203 0 : rBase.SetError(aStr.makeStringAndClear(), rInStm.GetToken());
204 0 : rBase.WriteError( rInStm );
205 0 : return false;
206 : }
207 : }
208 : else
209 : {
210 444825 : sal_uInt32 nId1 = pS->GetSlotId().GetValue();
211 444825 : sal_uInt32 nId2 = rAttr.GetSlotId().GetValue();
212 444825 : if( nId1 == nId2 && nId1 != 0 )
213 : {
214 : OSL_FAIL( "Gleiche Id in MetaClass : " );
215 : OSL_FAIL(OString::number(pS->GetSlotId().GetValue()).getStr());
216 : OSL_FAIL( pS->GetSlotId().getString().getStr() );
217 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
218 :
219 0 : OStringBuffer aStr("Attribute ");
220 0 : aStr.append(pS->GetName().getString());
221 0 : aStr.append(" and Attribute ");
222 0 : aStr.append(rAttr.GetName().getString());
223 0 : aStr.append(" with equal id's");
224 0 : rBase.SetError(aStr.makeStringAndClear(), rInStm.GetToken());
225 0 : rBase.WriteError( rInStm );
226 0 : return false;
227 : }
228 : }
229 : }
230 4458 : SvMetaClass * pSC = aSuperClass;
231 4458 : if( pSC )
232 375 : return pSC->TestAttribute( rBase, rInStm, rAttr );
233 4083 : return true;
234 : }
235 :
236 83 : sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase,
237 : SvSlotElementList & rSlotList,
238 : SvStream & rOutStm )
239 : {
240 83 : sal_uInt16 nCount = 0;
241 5995 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
242 : {
243 5912 : SvSlotElement *pEle = rSlotList[ i ];
244 5912 : SvMetaSlot *pAttr = pEle->xSlot;
245 5912 : nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm );
246 : }
247 :
248 83 : return nCount;
249 : }
250 :
251 83 : sal_uInt16 SvMetaClass::WriteSlots( const OString& rShellName,
252 : sal_uInt16 nCount, SvSlotElementList & rSlotList,
253 : SvIdlDataBase & rBase,
254 : SvStream & rOutStm )
255 : {
256 83 : sal_uInt16 nSCount = 0;
257 5995 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
258 : {
259 5912 : SvSlotElement * pEle = rSlotList[ i ];
260 5912 : SvMetaSlot * pAttr = pEle->xSlot;
261 : nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nCount + nSCount,
262 : rSlotList, i, rBase,
263 5912 : rOutStm );
264 : }
265 :
266 83 : return nSCount;
267 : }
268 :
269 211 : void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& rSuperList,
270 : SvMetaClassList &rClassList,
271 : const OString& rPrefix, SvIdlDataBase& rBase)
272 : {
273 : // was this class already written?
274 574 : for ( size_t i = 0, n = rClassList.size(); i < n ; ++i )
275 380 : if ( rClassList[ i ] == this )
276 228 : return;
277 :
278 194 : rClassList.push_back( this );
279 :
280 : // write all direct attributes
281 : sal_uLong n;
282 6068 : for( n = 0; n < aAttrList.size(); n++ )
283 : {
284 5874 : SvMetaAttribute * pAttr = aAttrList[n];
285 :
286 5874 : sal_uLong nId = pAttr->GetSlotId().GetValue();
287 :
288 : std::vector<sal_uLong>::iterator iter = std::find(rSuperList.begin(),
289 5874 : rSuperList.end(),nId);
290 :
291 5874 : if( iter == rSuperList.end() )
292 : {
293 : // Write only if not already written by subclass or
294 : // imported interface.
295 5853 : rSuperList.push_back(nId);
296 5853 : pAttr->Insert(rList, rPrefix, rBase);
297 : }
298 : }
299 :
300 : // All Interfaces already imported by SuperShells should not be
301 : // written any more.
302 : // It is prohibited that Shell and SuperShell directly import the same
303 : //class.
304 194 : if( IsShell() && aSuperClass.Is() )
305 27 : aSuperClass->FillClasses( rClassList );
306 :
307 : // Write all attributes of the imported classes, as long as they have
308 : // not already been imported by the superclass.
309 288 : for( n = 0; n < aClassList.size(); n++ )
310 : {
311 94 : SvClassElement * pEle = aClassList[n];
312 94 : SvMetaClass * pCl = pEle->GetClass();
313 94 : OStringBuffer rPre(rPrefix);
314 94 : if( !rPre.isEmpty() && !pEle->GetPrefix().isEmpty() )
315 0 : rPre.append('.');
316 94 : rPre.append(pEle->GetPrefix());
317 :
318 : // first of all write direct imported interfaces
319 : pCl->InsertSlots( rList, rSuperList, rClassList,
320 94 : rPre.makeStringAndClear(), rBase );
321 94 : }
322 :
323 : // only write superclass if no shell and not in the list
324 194 : if( !IsShell() && aSuperClass.Is() )
325 : {
326 34 : aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase );
327 : }
328 : }
329 :
330 99 : void SvMetaClass::FillClasses( SvMetaClassList & rList )
331 : {
332 : // Am I not yet in?
333 357 : for ( size_t i = 0, n = rList.size(); i < n; ++i )
334 263 : if ( rList[ i ] == this )
335 104 : return;
336 :
337 94 : rList.push_back( this );
338 :
339 : // my imports
340 135 : for( sal_uInt32 n = 0; n < aClassList.size(); n++ )
341 : {
342 41 : SvClassElement * pEle = aClassList[n];
343 41 : SvMetaClass * pCl = pEle->GetClass();
344 41 : pCl->FillClasses( rList );
345 : }
346 :
347 : // my superclass
348 94 : if( aSuperClass.Is() )
349 31 : aSuperClass->FillClasses( rList );
350 : }
351 :
352 :
353 83 : void SvMetaClass::WriteSlotStubs( const OString& rShellName,
354 : SvSlotElementList & rSlotList,
355 : ByteStringList & rList,
356 : SvStream & rOutStm )
357 : {
358 : // write all attributes
359 5995 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
360 : {
361 5912 : SvSlotElement *pEle = rSlotList[ i ];
362 5912 : SvMetaSlot *pAttr = pEle->xSlot;
363 5912 : pAttr->WriteSlotStubs( rShellName, rList, rOutStm );
364 : }
365 83 : }
366 :
367 190 : void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm )
368 : {
369 190 : WriteStars( rOutStm );
370 : // define class
371 190 : rOutStm.WriteCharPtr( "#ifdef " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
372 190 : rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl;
373 190 : rOutStm.WriteCharPtr( "#undef " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
374 190 : rOutStm.WriteCharPtr( "#define ShellClass " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
375 :
376 : // no slotmaps get written for interfaces
377 190 : if( !IsShell() )
378 : {
379 107 : rOutStm.WriteCharPtr( "#endif" ) << endl << endl;
380 297 : return;
381 : }
382 : // write parameter array
383 83 : rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Args_Impl[] =") << endl;
384 83 : rOutStm.WriteChar('{') << endl;
385 :
386 83 : std::vector<sal_uLong> aSuperList;
387 166 : SvMetaClassList classList;
388 166 : SvSlotElementList aSlotList;
389 83 : InsertSlots(aSlotList, aSuperList, classList, OString(), rBase);
390 5995 : for ( size_t i = 0, n = aSlotList.size(); i < n; ++i )
391 : {
392 5912 : SvSlotElement *pEle = aSlotList[ i ];
393 5912 : SvMetaSlot *pSlot = pEle->xSlot;
394 5912 : pSlot->SetListPos( i );
395 : }
396 :
397 83 : size_t nSlotCount = aSlotList.size();
398 :
399 : // write all attributes
400 83 : sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm );
401 83 : if( nArgCount )
402 61 : Back2Delemitter( rOutStm );
403 : else
404 : {
405 : // at leaast one dummy
406 22 : WriteTab( rOutStm, 1 );
407 22 : rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl;
408 : }
409 83 : rOutStm << endl;
410 83 : rOutStm.WriteCharPtr( "};" ) << endl << endl;
411 :
412 166 : ByteStringList aStringList;
413 83 : WriteSlotStubs( GetName().getString(), aSlotList, aStringList, rOutStm );
414 715 : for ( size_t i = 0, n = aStringList.size(); i < n; ++i )
415 632 : delete aStringList[ i ];
416 83 : aStringList.clear();
417 :
418 83 : rOutStm << endl;
419 :
420 : // write slotmap
421 83 : rOutStm.WriteCharPtr("static SfxSlot a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Slots_Impl[] =") << endl;
422 83 : rOutStm.WriteChar( '{' ) << endl;
423 :
424 : // write all attributes
425 83 : WriteSlots( GetName().getString(), 0, aSlotList, rBase, rOutStm );
426 83 : if( nSlotCount )
427 76 : Back2Delemitter( rOutStm );
428 : else
429 : {
430 : // at least one dummy
431 7 : WriteTab( rOutStm, 1 );
432 7 : rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteCharPtr( GetName().getString().getStr() )
433 7 : .WriteCharPtr( ", 0, 0, " )
434 7 : .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," )
435 7 : .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," )
436 7 : .WriteCharPtr( "0, SfxVoidItem, 0, 0, \"\", 0 )" ) << endl;
437 : }
438 83 : rOutStm << endl;
439 83 : rOutStm.WriteCharPtr( "};" ) << endl;
440 83 : rOutStm.WriteCharPtr( "#endif" ) << endl << endl;
441 :
442 5995 : for( size_t i = 0, n = aSlotList.size(); i < n; ++i )
443 : {
444 5912 : SvSlotElement* pEle = aSlotList[ i ];
445 5912 : SvMetaSlot* pAttr = pEle->xSlot;
446 5912 : pAttr->ResetSlotPointer();
447 : }
448 :
449 5995 : for( size_t i = 0, n = aSlotList.size(); i < n; ++i )
450 5912 : delete aSlotList[ i ];
451 166 : aSlotList.clear();
452 : }
453 :
454 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|