|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implements CNcdNodeFolder class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "ncdnodefolder.h" |
|
20 #include "ncdnodefolderlink.h" |
|
21 #include "ncdnodefoldermetadata.h" |
|
22 #include "ncdnodemanager.h" |
|
23 #include "ncdnodeclassids.h" |
|
24 #include "ncdnodeidentifier.h" |
|
25 #include "ncdnodefunctionids.h" |
|
26 #include "catalogsbasemessage.h" |
|
27 #include "catalogsutils.h" |
|
28 #include "ncdchildentity.h" |
|
29 #include "ncdnodefolderlink.h" |
|
30 #include "ncdnodeseenfolderimpl.h" |
|
31 #include "ncdexpirednode.h" |
|
32 |
|
33 #include "catalogsdebug.h" |
|
34 |
|
35 CNcdNodeFolder::CNcdNodeFolder( CNcdNodeManager& aNodeManager, |
|
36 NcdNodeClassIds::TNcdNodeClassId aNodeClassId, |
|
37 NcdNodeClassIds::TNcdNodeClassId aAcceptedLinkClassId, |
|
38 NcdNodeClassIds::TNcdNodeClassId aAcceptedMetaDataClassId ) |
|
39 : CNcdNode( aNodeManager, |
|
40 aNodeClassId, |
|
41 aAcceptedLinkClassId, |
|
42 aAcceptedMetaDataClassId ), |
|
43 iPreviousChildCount( KErrNotFound ) |
|
44 { |
|
45 } |
|
46 |
|
47 void CNcdNodeFolder::ConstructL( const CNcdNodeIdentifier& aIdentifier ) |
|
48 { |
|
49 DLTRACEIN(("this: %X", this )); |
|
50 |
|
51 CNcdNode::ConstructL( aIdentifier ); |
|
52 |
|
53 iNodeSeenFolder = CNcdNodeSeenFolder::NewL( *this ); |
|
54 |
|
55 DLTRACEOUT(("")); |
|
56 } |
|
57 |
|
58 |
|
59 CNcdNodeFolder::~CNcdNodeFolder() |
|
60 { |
|
61 DLTRACEIN(("this: %X", this)); |
|
62 for ( TInt i = 0; i < iChildren.Count(); ++i ) |
|
63 { |
|
64 DLINFO(( _L("Child %d, ns: %S, id: %S"), i, |
|
65 &iChildren[i]->Identifier().NodeNameSpace(), |
|
66 &iChildren[i]->Identifier().NodeId() )); |
|
67 } |
|
68 RemoveChildren(); |
|
69 |
|
70 if ( iNodeSeenFolder ) |
|
71 { |
|
72 DLINFO(("Closing node seen folder")); |
|
73 iNodeSeenFolder->Close(); |
|
74 iNodeSeenFolder = NULL; |
|
75 } |
|
76 |
|
77 iPreviousChildren.ResetAndDestroy(); |
|
78 |
|
79 DLTRACEOUT(("")); |
|
80 } |
|
81 |
|
82 |
|
83 CNcdNodeFolder* CNcdNodeFolder::NewL( CNcdNodeManager& aNodeManager, |
|
84 const CNcdNodeIdentifier& aIdentifier ) |
|
85 { |
|
86 CNcdNodeFolder* self = |
|
87 CNcdNodeFolder::NewLC( aNodeManager, aIdentifier ); |
|
88 CleanupStack::Pop( self ); |
|
89 return self; |
|
90 } |
|
91 |
|
92 CNcdNodeFolder* CNcdNodeFolder::NewLC( CNcdNodeManager& aNodeManager, |
|
93 const CNcdNodeIdentifier& aIdentifier ) |
|
94 { |
|
95 CNcdNodeFolder* self = |
|
96 new( ELeave ) CNcdNodeFolder( aNodeManager ); |
|
97 CleanupClosePushL( *self ); |
|
98 self->ConstructL( aIdentifier ); |
|
99 return self; |
|
100 } |
|
101 |
|
102 |
|
103 TInt CNcdNodeFolder::ChildCount() const |
|
104 { |
|
105 DLTRACEIN(( "this: %X, ChildCount: %d", this, iChildren.Count() )); |
|
106 return iChildren.Count(); |
|
107 } |
|
108 |
|
109 |
|
110 const CNcdNodeIdentifier& CNcdNodeFolder::ChildL( TInt aIndex ) const |
|
111 { |
|
112 DLTRACEIN(( "" )); |
|
113 if( aIndex < 0 || aIndex > iChildren.Count() ) |
|
114 { |
|
115 User::Leave( KErrArgument ); |
|
116 } |
|
117 return iChildren[aIndex]->Identifier(); |
|
118 } |
|
119 |
|
120 TInt CNcdNodeFolder::ServerChildCountL() const |
|
121 { |
|
122 DLTRACEIN(("")); |
|
123 TInt serverChildCount = FolderLinkL().ExpectedChildrenCount(); |
|
124 DLTRACEOUT(("this: %X, ServerChildCount: %d", this, serverChildCount )); |
|
125 return serverChildCount; |
|
126 } |
|
127 |
|
128 const CNcdNodeIdentifier& CNcdNodeFolder::ChildByServerIndexL( TInt aIndex ) const |
|
129 { |
|
130 DLTRACEIN(("")); |
|
131 return ChildEntityByServerIndexL( aIndex ).Identifier(); |
|
132 } |
|
133 |
|
134 const CNcdChildEntity& CNcdNodeFolder::ChildEntityByServerIndexL( TInt aIndex ) const |
|
135 { |
|
136 DLTRACEIN(( "aIndex: %d", aIndex )); |
|
137 |
|
138 // search for a child with given index |
|
139 const CNcdChildEntity* child = NULL; |
|
140 for( TInt i = 0 ; i < iChildren.Count() ; i++ ) |
|
141 { |
|
142 if ( iChildren[i]->Index() == aIndex ) |
|
143 { |
|
144 child = iChildren[i]; |
|
145 break; |
|
146 } |
|
147 else if ( iChildren[i]->Index() > aIndex ) |
|
148 { |
|
149 // no sense in searching further |
|
150 break; |
|
151 } |
|
152 } |
|
153 |
|
154 if ( child == NULL ) |
|
155 { |
|
156 // Leave because the child is set NULL. |
|
157 // NULL can not be returned as a reference value. |
|
158 DLINFO(("Child node identifier was NULL. So, leave with KErrNotFound")) |
|
159 User::Leave( KErrNotFound ); |
|
160 } |
|
161 |
|
162 DLTRACEOUT(("")); |
|
163 |
|
164 return *child; |
|
165 } |
|
166 |
|
167 const RPointerArray<CNcdChildEntity>& CNcdNodeFolder::ChildArray() const |
|
168 { |
|
169 return iChildren; |
|
170 } |
|
171 |
|
172 |
|
173 TBool CNcdNodeFolder::ReplaceChildL( |
|
174 const CNcdNodeIdentifier& aNodeIdentifier, |
|
175 TInt aIndex, |
|
176 TBool aTransparent, |
|
177 CNcdNodeFactory::TNcdNodeType aNodeType ) |
|
178 { |
|
179 DLTRACEIN(( _L("this: %X, Parent ns, id: %S, %S, Child ns, id: %S, %S, aIndex: %d childCount: %d"), |
|
180 this, &Identifier().NodeNameSpace(), &Identifier().NodeId(), |
|
181 &aNodeIdentifier.NodeNameSpace(), &aNodeIdentifier.NodeId(), |
|
182 aIndex, iChildren.Count() )); |
|
183 |
|
184 TInt expectedChildCount = FolderLinkL().ExpectedChildrenCount(); |
|
185 if ( aIndex < 0 /*|| aIndex >= expectedChildCount*/ ) |
|
186 { |
|
187 // For debugging purposes |
|
188 DLERROR(("Wrong child index")); |
|
189 DASSERT( EFalse ); |
|
190 |
|
191 User::Leave( KErrArgument ); |
|
192 } |
|
193 |
|
194 |
|
195 TBool childFound = EFalse; |
|
196 TInt i = 0; |
|
197 for ( ; i < iChildren.Count() ; i++ ) |
|
198 { |
|
199 if( iChildren[i]->Index() == aIndex ) |
|
200 { |
|
201 DLTRACE(("Child with the same index found.")); |
|
202 if( ! (iChildren[i]->Identifier().Equals( aNodeIdentifier ) ) ) |
|
203 { |
|
204 DLTRACE(("Not the same child, replace.")); |
|
205 iChildren[i]->SetIdentifierL( aNodeIdentifier ); |
|
206 iChildren[i]->SetTransparent( aTransparent ); |
|
207 iChildren[i]->SetNodeType( aNodeType ); |
|
208 // Should the old child be expired via nodemgr? |
|
209 } |
|
210 else |
|
211 { |
|
212 iChildren[i]->SetTransparent( aTransparent ); |
|
213 iChildren[i]->SetNodeType( aNodeType ); |
|
214 // exactly the same child, do nothing |
|
215 } |
|
216 childFound = ETrue; |
|
217 break; |
|
218 } |
|
219 else if ( iChildren[i]->Index() > aIndex ) |
|
220 { |
|
221 // no sense in searching further |
|
222 break; |
|
223 } |
|
224 } |
|
225 |
|
226 if ( !childFound ) |
|
227 { |
|
228 DLTRACE(("Child not found, create new")) |
|
229 CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( |
|
230 aIndex, |
|
231 aNodeIdentifier, |
|
232 aTransparent, |
|
233 aNodeType ); |
|
234 |
|
235 if ( i == iChildren.Count() ) |
|
236 { |
|
237 // last child, append |
|
238 DLTRACE(("Appending")); |
|
239 iChildren.AppendL( childEntity ); |
|
240 } |
|
241 else |
|
242 { |
|
243 DLTRACE(("Inserting")); |
|
244 iChildren.InsertL( childEntity, i ); |
|
245 } |
|
246 CleanupStack::Pop( childEntity ); |
|
247 } |
|
248 |
|
249 #ifdef CATALOGS_BUILD_CONFIG_DEBUG |
|
250 for( TInt j = 0 ; j < iChildren.Count() ; j++ ) |
|
251 { |
|
252 CNcdChildEntity* child = iChildren[j]; |
|
253 DLINFO((_L("Child id: %S, array index: %d, real index: %d"), |
|
254 &child->Identifier().NodeId(), j, child->Index() )); |
|
255 } |
|
256 #endif |
|
257 |
|
258 return !childFound; |
|
259 } |
|
260 |
|
261 |
|
262 TBool CNcdNodeFolder::InsertChildL( |
|
263 const CNcdNodeIdentifier& aNodeIdentifier, |
|
264 TInt aIndex, |
|
265 TBool aTransparent, |
|
266 CNcdNodeFactory::TNcdNodeType aNodeType ) |
|
267 { |
|
268 DLTRACEIN(( _L("this: %X, Parent ns, id: %S, %S, Child ns, id: %S, %S, aIndex: %d, childCount: %d"), |
|
269 this, &Identifier().NodeNameSpace(), &Identifier().NodeId(), |
|
270 &aNodeIdentifier.NodeNameSpace(), &aNodeIdentifier.NodeId(), |
|
271 aIndex, iChildren.Count() )); |
|
272 |
|
273 DPROFILING_BEGIN( x ); |
|
274 if ( aIndex < 0 || aIndex > iChildren.Count() ) |
|
275 { |
|
276 // For debugging purposes |
|
277 DLERROR(("Wrong child index")); |
|
278 DASSERT( EFalse ); |
|
279 |
|
280 User::Leave( KErrArgument ); |
|
281 } |
|
282 |
|
283 CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( |
|
284 aIndex, |
|
285 aNodeIdentifier, |
|
286 aTransparent, |
|
287 aNodeType ); |
|
288 if( aIndex == iChildren.Count() ) |
|
289 { |
|
290 // last index, append |
|
291 DLTRACE(("Appending")); |
|
292 iChildren.AppendL( childEntity ); |
|
293 } |
|
294 else |
|
295 { |
|
296 DLTRACE(("Inserting")); |
|
297 iChildren.InsertL( childEntity, aIndex ); |
|
298 } |
|
299 CleanupStack::Pop( childEntity ); |
|
300 |
|
301 #ifdef CATALOGS_BUILD_CONFIG_DEBUG |
|
302 for( TInt i = 0 ; i < iChildren.Count() ; i++ ) |
|
303 { |
|
304 DLINFO(( _L("Child: index: %d, real index: %d, id: %S, ns: %S "), |
|
305 i, iChildren[i]->Index(), &iChildren[i]->Identifier().NodeId(), |
|
306 &iChildren[i]->Identifier().NodeNameSpace() )); |
|
307 } |
|
308 #endif |
|
309 |
|
310 DPROFILING_END( x ); |
|
311 return ETrue; |
|
312 } |
|
313 |
|
314 |
|
315 TBool CNcdNodeFolder::AppendChildL( |
|
316 const CNcdNodeIdentifier& aNodeIdentifier, |
|
317 TBool aTransparent, |
|
318 CNcdNodeFactory::TNcdNodeType aNodeType ) |
|
319 { |
|
320 DLTRACEIN(("")); |
|
321 return InsertChildL( aNodeIdentifier, iChildren.Count(), aTransparent, |
|
322 aNodeType ); |
|
323 } |
|
324 |
|
325 CNcdNodeFolderLink& CNcdNodeFolder::FolderLinkL() const |
|
326 { |
|
327 // safe to cast because folders always have folder links |
|
328 return static_cast<CNcdNodeFolderLink&>( NodeLinkL() ); |
|
329 } |
|
330 |
|
331 |
|
332 CNcdNodeSeenFolder& CNcdNodeFolder::NodeSeenFolder() const |
|
333 { |
|
334 return *iNodeSeenFolder; |
|
335 } |
|
336 |
|
337 |
|
338 void CNcdNodeFolder::RemoveChild( const CNcdNodeIdentifier& aNodeIdentifier ) |
|
339 { |
|
340 DLTRACEIN(( _L("this: %X, Parent ns, id: %S, %S"), this, |
|
341 &Identifier().NodeNameSpace(), &Identifier().NodeId() )); |
|
342 DLINFO(( _L("child to remove ns, id: %S, %S"), |
|
343 &aNodeIdentifier.NodeNameSpace(), &aNodeIdentifier.NodeId() )); |
|
344 DPROFILING_BEGIN( x ); |
|
345 for ( TInt i = 0 ; i < iChildren.Count() ; i++ ) |
|
346 { |
|
347 if( iChildren[i]->Identifier().Equals( aNodeIdentifier ) ) |
|
348 { |
|
349 DeleteFromArray( iChildren, i ); |
|
350 DPROFILING_END( x ); |
|
351 return; |
|
352 } |
|
353 } |
|
354 |
|
355 DPROFILING_END( x ); |
|
356 DLWARNING(("Unable to remove nonexisting child")); |
|
357 } |
|
358 |
|
359 |
|
360 void CNcdNodeFolder::RemoveChildrenL() |
|
361 { |
|
362 DLTRACEIN(("")); |
|
363 DPROFILING_BEGIN( x ); |
|
364 NodeManager().RemoveChildrenL( *this ); |
|
365 DPROFILING_END( x ); |
|
366 } |
|
367 |
|
368 |
|
369 void CNcdNodeFolder::RemoveChildren() |
|
370 { |
|
371 DLTRACEIN(("")); |
|
372 iChildren.ResetAndDestroy(); |
|
373 // Also set children previously loaded flag to false, |
|
374 // because child list is no longer valid |
|
375 iChildrenPreviouslyLoaded = EFalse; |
|
376 DLTRACE((_L("node id: %S"), &Identifier().NodeId() )); |
|
377 DLTRACE(("iChildrenPreviouslyLoaded: %d",iChildrenPreviouslyLoaded )); |
|
378 } |
|
379 |
|
380 void CNcdNodeFolder::StoreChildrenToPreviousListL() |
|
381 { |
|
382 DLTRACEIN(("")); |
|
383 StoreChildrenToPreviousListL( iChildren, |
|
384 FolderLinkL().ExpectedChildrenCount() ); |
|
385 } |
|
386 |
|
387 void CNcdNodeFolder::StoreChildrenToPreviousListL( |
|
388 const RPointerArray<CNcdChildEntity>& aPreviousChildren, |
|
389 TInt aPreviousChildCount ) |
|
390 { |
|
391 DLTRACEIN(("")); |
|
392 // First clear previous list. |
|
393 iPreviousChildren.ResetAndDestroy(); |
|
394 for( TInt i = 0 ; i < aPreviousChildren.Count() ; i++ ) |
|
395 { |
|
396 CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( |
|
397 *aPreviousChildren[i] ); |
|
398 DLTRACE((_L("Adding child entity, identifier: %S, index: %d"), |
|
399 &childEntity->Identifier().NodeId(), childEntity->Index() )); |
|
400 iPreviousChildren.AppendL( childEntity ); |
|
401 CleanupStack::Pop( childEntity ); |
|
402 } |
|
403 DLTRACE(("Setting previous child count: %d", aPreviousChildCount )); |
|
404 iPreviousChildCount = aPreviousChildCount; |
|
405 } |
|
406 |
|
407 TBool CNcdNodeFolder::ChildrenPreviouslyLoaded() |
|
408 { |
|
409 DLTRACEIN(("")); |
|
410 DLINFO(("ret: %d",iChildrenPreviouslyLoaded)); |
|
411 return iChildrenPreviouslyLoaded; |
|
412 } |
|
413 |
|
414 void CNcdNodeFolder::SetChildrenPreviouslyLoaded( TBool aChildrenPreviouslyLoaded ) |
|
415 { |
|
416 DLTRACEIN(("")); |
|
417 iChildrenPreviouslyLoaded = aChildrenPreviouslyLoaded; |
|
418 } |
|
419 |
|
420 TInt CNcdNodeFolder::PreviousChildCount() |
|
421 { |
|
422 DLTRACEIN(("")); |
|
423 return iPreviousChildCount; |
|
424 } |
|
425 |
|
426 const RPointerArray<CNcdChildEntity>& CNcdNodeFolder::PreviousChildArray() |
|
427 { |
|
428 DLTRACEIN(("")); |
|
429 return iPreviousChildren; |
|
430 } |
|
431 |
|
432 |
|
433 void CNcdNodeFolder::ExpireAndRemoveChildrenL() |
|
434 { |
|
435 DLTRACEIN(("")); |
|
436 TInt count = iChildren.Count(); |
|
437 |
|
438 CNcdNode* node = NULL; |
|
439 |
|
440 RPointerArray<CNcdExpiredNode> expiredNodes; |
|
441 CleanupResetAndDestroyPushL( expiredNodes ); |
|
442 expiredNodes.ReserveL( count ); |
|
443 |
|
444 while( count-- ) |
|
445 { |
|
446 node = NodeManager().NodePtrL( iChildren[ count ]->Identifier() ); |
|
447 if ( node ) |
|
448 { |
|
449 NodeManager().SetNodeExpiredL( *node, EFalse, EFalse, expiredNodes ); |
|
450 |
|
451 } |
|
452 } |
|
453 CleanupStack::PopAndDestroy( &expiredNodes ); |
|
454 // Delete child metadatas from disk cache |
|
455 NodeManager().RemoveChildrenMetadataL( *this ); |
|
456 |
|
457 // Empty children lists |
|
458 RemoveChildren(); |
|
459 } |
|
460 |
|
461 |
|
462 void CNcdNodeFolder::ReceiveMessage( |
|
463 MCatalogsBaseMessage* aMessage, |
|
464 TInt aFunctionNumber ) |
|
465 { |
|
466 DLTRACEIN(("this-ptr: %x", this)); |
|
467 |
|
468 DASSERT( aMessage ); |
|
469 |
|
470 // Now, we can be sure that rest of the time iMessage exists. |
|
471 // This member variable is set for the CounterPartLost function. |
|
472 iMessage = aMessage; |
|
473 |
|
474 TInt trapError( KErrNone ); |
|
475 |
|
476 switch( aFunctionNumber ) |
|
477 { |
|
478 case NcdNodeFunctionIds::ENcdNodeSeenFolderHandle: |
|
479 TRAP( trapError, NodeSeenFolderHandleRequestL( *aMessage ) ); |
|
480 break; |
|
481 |
|
482 default: |
|
483 // Let base class handle this |
|
484 iMessage = NULL; |
|
485 CNcdNode::ReceiveMessage( aMessage, aFunctionNumber ); |
|
486 return; |
|
487 } |
|
488 |
|
489 if ( trapError != KErrNone ) |
|
490 { |
|
491 // Because something went wrong the complete has not been |
|
492 // yet called for the message. |
|
493 // So, inform the client about the error. |
|
494 DLTRACEIN(("Complete with error message")); |
|
495 aMessage->CompleteAndRelease( trapError ); |
|
496 } |
|
497 |
|
498 // Because the message should not be used after this, set it NULL. |
|
499 // So, CounterPartLost function will know that no messages are |
|
500 // waiting the response at the moment. |
|
501 iMessage = NULL; |
|
502 } |
|
503 |
|
504 |
|
505 |
|
506 void CNcdNodeFolder::ExternalizeL( RWriteStream& aStream ) |
|
507 { |
|
508 DLTRACEIN(("this: %X, children: %d", this, iChildren.Count() )); |
|
509 |
|
510 // First use the parent to externalize the general data |
|
511 CNcdNode::ExternalizeL( aStream ); |
|
512 |
|
513 ExternalizeChildArrayL( aStream ); |
|
514 |
|
515 aStream.WriteInt8L( iChildrenPreviouslyLoaded ); |
|
516 DLTRACE((_L("node id: %S"), &Identifier().NodeId() )); |
|
517 DLTRACE(("wrote iChildrenPreviouslyLoaded: %d",iChildrenPreviouslyLoaded )); |
|
518 |
|
519 DLTRACEOUT(("")); |
|
520 } |
|
521 |
|
522 void CNcdNodeFolder::InternalizeL( RReadStream& aStream ) |
|
523 { |
|
524 DLTRACEIN(("this: %X", this)); |
|
525 |
|
526 // First use the parent to internalize the general data |
|
527 CNcdNode::InternalizeL( aStream ); |
|
528 |
|
529 DLINFO(("Parent class internalized")); |
|
530 // Now internalize the data of this specific class |
|
531 |
|
532 // Insert child information to iChildren array |
|
533 // But first release previous info if it exists. |
|
534 iChildren.ResetAndDestroy(); |
|
535 |
|
536 |
|
537 TInt childCount( aStream.ReadInt32L() ); |
|
538 DLINFO(("Children: %d", childCount )); |
|
539 NcdNodeClassIds::TNcdNodeClassId classObjectType = |
|
540 NcdNodeClassIds::ENcdNullObjectClassId; |
|
541 |
|
542 for ( TInt i = 0; i < childCount; ++i ) |
|
543 { |
|
544 // This is safe casting because enum is same as TInt |
|
545 classObjectType = |
|
546 static_cast<NcdNodeClassIds::TNcdNodeClassId>(aStream.ReadInt32L()); |
|
547 if ( NcdNodeClassIds::ENcdChildEntityClassId == classObjectType ) |
|
548 { |
|
549 CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( aStream ); |
|
550 iChildren.AppendL( childEntity ); |
|
551 CleanupStack::Pop( childEntity ); |
|
552 } |
|
553 else |
|
554 { |
|
555 // Wrong kind of class object info |
|
556 User::Leave( KErrCorrupt ); |
|
557 } |
|
558 } |
|
559 |
|
560 iChildrenPreviouslyLoaded = aStream.ReadInt8L(); |
|
561 DLTRACE((_L("node id: %S"), &Identifier().NodeId() )); |
|
562 DLTRACE(("read iChildrenPreviouslyLoaded: %d",iChildrenPreviouslyLoaded )); |
|
563 DLTRACEOUT(("")); |
|
564 } |
|
565 |
|
566 |
|
567 CNcdNodeLink* CNcdNodeFolder::CreateLinkL() |
|
568 { |
|
569 DLTRACEIN(("")); |
|
570 CNcdNodeLink* link = NodeLink(); |
|
571 |
|
572 if ( link != NULL ) |
|
573 { |
|
574 DLTRACEOUT(("Link already exists")); |
|
575 // The link was already created |
|
576 return link; |
|
577 } |
|
578 else |
|
579 { |
|
580 DLTRACEOUT(("Creating a new link")); |
|
581 // Link was not already created. |
|
582 // So, create new. |
|
583 return CNcdNodeFolderLink::NewL( *this ); |
|
584 } |
|
585 } |
|
586 |
|
587 |
|
588 void CNcdNodeFolder::ExternalizeDataForRequestL( RWriteStream& aStream ) const |
|
589 { |
|
590 DLTRACEIN(("this: %X", this)); |
|
591 |
|
592 CNcdNode::ExternalizeDataForRequestL( aStream ); |
|
593 |
|
594 // Return also, the child information. |
|
595 // Use the virtual function here. So, different children may provide their |
|
596 // own functionality here. For example. Root folder may work differently than |
|
597 // normal folder. |
|
598 ExternalizeChildArrayForRequestL( aStream ); |
|
599 |
|
600 DLTRACEOUT(("")); |
|
601 } |
|
602 |
|
603 |
|
604 void CNcdNodeFolder::ExternalizeChildArrayL( RWriteStream& aStream ) const |
|
605 { |
|
606 DLTRACEIN(("this: %X, childcount: %d", this, iChildren.Count() )); |
|
607 DPROFILING_BEGIN( x ); |
|
608 // Now externalize the data of this specific class |
|
609 aStream.WriteInt32L( iChildren.Count() ); |
|
610 |
|
611 for( TInt i = 0; i < iChildren.Count(); ++i ) |
|
612 { |
|
613 DASSERT( iChildren[i] ); |
|
614 aStream.WriteInt32L( NcdNodeClassIds::ENcdChildEntityClassId ); |
|
615 iChildren[ i ]->ExternalizeL( aStream ); |
|
616 /* |
|
617 DLINFO((_L("Child id: %S, array index: %d, real index: %d"), |
|
618 &iChildren[i]->Identifier().NodeId(), i, iChildren[i]->Index() )); |
|
619 */ |
|
620 |
|
621 } |
|
622 DPROFILING_END( x ); |
|
623 DLTRACEOUT(("")); |
|
624 } |
|
625 |
|
626 |
|
627 void CNcdNodeFolder::ExternalizeChildArrayForRequestL( RWriteStream& aStream ) const |
|
628 { |
|
629 DLTRACEIN(("this: %X", this)); |
|
630 |
|
631 // No special functionality needed here. |
|
632 ExternalizeChildArrayL( aStream ); |
|
633 |
|
634 DLTRACEOUT(("")); |
|
635 } |
|
636 |
|
637 |
|
638 void CNcdNodeFolder::NodeSeenFolderHandleRequestL( MCatalogsBaseMessage& aMessage ) const |
|
639 { |
|
640 DLTRACEIN((("this-ptr: %x"), this)); |
|
641 DASSERT( iNodeSeenFolder ); |
|
642 |
|
643 // Get the session that will contain the handle of the node seen folder object |
|
644 MCatalogsSession& requestSession( aMessage.Session() ); |
|
645 |
|
646 // Add the node seen folder object to the session and get the handle. |
|
647 // If the object already existed in the session we will still |
|
648 // get a new handle to the same object. |
|
649 TInt32 handle( requestSession.AddObjectL( iNodeSeenFolder ) ); |
|
650 |
|
651 DLINFO(("Node seen folder handle: %d", handle )); |
|
652 |
|
653 // Send the information to the client side |
|
654 // If this leaves, ReceiveMessage will complete the message. |
|
655 aMessage.CompleteAndReleaseL( handle, KErrNone ); |
|
656 } |
|
657 |