Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfsrv\cl_notification.cpp
18 #include "cl_notification.h"
20 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
22 * The order of the data in the buffer is:
23 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
24 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
25 * Word3 : UID - NOT YET SUPPORTED
26 * Word(s) : Path (TText8) , [Any sub-class members]
28 * The notification size should be located at *this
30 TInt TFsNotification::NotificationSize() const
32 TInt word1 = *(TInt*)this;
37 * The order of the data in the buffer is:
38 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
39 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
40 * Word3 : UID - NOT YET SUPPORTED
41 * Word(s) : Path (TText8) , [Any sub-class members]
43 * The notification type should be located at:
44 * *this + sizeof(NotificationSize) + sizeof(PathSize) + sizeof(NewNameSize)
46 EXPORT_C TFsNotification::TFsNotificationType TFsNotification::NotificationType() const
48 TUint* word2 = PtrAdd((TUint*)this, sizeof(TUint));
49 TFsNotificationType ret = (TFsNotificationType)(*word2 & 0x0000FFFF);
50 //Check it is a valid type
51 __ASSERT_DEBUG(!((TInt)ret & ~KNotificationValidFiltersMask) || (ret == EOverflow), Panic(ENotificationPanic));
52 return ret; //Returns the lower 2 bytes of Word2
56 * The order of the data in the buffer is:
57 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
58 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
59 * Word3 : UID - NOT YET SUPPORTED
60 * Word(s) : Path (TText8) , [Any sub-class members]
62 * The path size should be located at *this + sizeof(NotificationSize)
64 TInt TFsNotification::PathSize() const
66 //Notification of type EOverflow does not have a path associated with it
67 __ASSERT_DEBUG(NotificationType() != EOverflow,Panic(ENotificationPanic));
68 TUint ret = (*(TUint*)this & 0x0000FFFF); //Returns the lower 2 bytes of Word1
73 * The order of the data in the buffer is:
74 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
75 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
76 * Word3 : UID - NOT YET SUPPORTED
77 * Word(s) : Path (TText8) , [Any sub-class members]
79 * The path should be located at: *this + KNotificationHeaderSize
81 EXPORT_C TInt TFsNotification::Path(TPtrC& aPath) const
83 //Notification of type EOverflow does not have a path associated with it
84 if(NotificationType() == EOverflow)
85 return KErrNotSupported;
87 TUint16* pathPtr = PtrAdd((TUint16*)this, KNotificationHeaderSize);
88 aPath.Set(pathPtr,PathSize()/2);
93 * The order of the data in the buffer is:
94 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
95 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
96 * Word3 : UID - NOT YET SUPPORTED
97 * Word(s) : Path (TText8) , [Any sub-class members]
99 * The new name size should be located at: *this + sizeof(NotificationSize) + sizeof(PathSize)
101 TInt TFsNotification::NewNameSize() const
103 //The only notifications containing a new name are ERename, EVolumeName and EDriveName
104 __ASSERT_DEBUG((NotificationType() == ERename ||
105 NotificationType() == EVolumeName ||
106 NotificationType() == EDriveName),Panic(ENotificationPanic));
107 TInt* word2 = PtrAdd((TInt*)this, sizeof(TInt));
108 return ((*word2) >> 16);
112 * The order of the data in the buffer is:
113 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
114 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
115 * Word3 : UID - NOT YET SUPPORTED
116 * Word(s) : Path (TText8) , [Any sub-class members]
118 * The new name should be located at: *this + KNotificationHeaderSize + Align4(PathSize)
120 EXPORT_C TInt TFsNotification::NewName(TPtrC& aNewName) const
122 //Only ERename, EVolumeName and EDriveName have second paths
123 //Notification of type EOverflow does not have a path associated with it
124 TFsNotificationType notificationType = NotificationType();
125 if((notificationType != ERename &&
126 notificationType != EVolumeName &&
127 notificationType != EDriveName) ||
128 notificationType == EOverflow)
130 return KErrNotSupported;
133 TUint16* pathPtr = PtrAdd((TUint16*)this, KNotificationHeaderSize + Align4(PathSize()));
134 aNewName.Set(pathPtr,NewNameSize()/2);
139 * The order of the data in the buffer is:
140 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
141 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
142 * Word3 : UID - NOT YET SUPPORTED
143 * Word(s) : Path (TText8) , [Any sub-class members]
145 * The attribute should be located at: *this + KNotificationHeaderSize + Align4(PathSize)
147 EXPORT_C TInt TFsNotification::Attributes(TUint& aSetAtt, TUint& aClearAtt) const
149 if(NotificationType() != EAttribute)
150 return KErrNotSupported;
152 TUint* clearAttptr = PtrAdd((TUint*)this, KNotificationHeaderSize + Align4(PathSize()));
153 aClearAtt = *clearAttptr;
154 aSetAtt = *PtrAdd((TUint*)clearAttptr, sizeof(TUint));
159 * The order of the data in the buffer is:
160 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
161 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
162 * Word3 : UID - NOT YET SUPPORTED
163 * Word(s) : Path (TText8) , [Any sub-class members]
165 * The size should be located at: *this + KNotificationHeaderSize + Align4(PathSize)
167 EXPORT_C TInt TFsNotification::FileSize(TInt64& aSize) const
169 if(NotificationType() != EFileChange)
170 return KErrNotSupported;
172 aSize = *PtrAdd((TInt64*)this, KNotificationHeaderSize + Align4(PathSize()));
177 * The order of the data in the buffer is:
178 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
179 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
181 * Word(s) : Path (TText8) , [Any sub-class members]
183 EXPORT_C TInt TFsNotification::DriveNumber(TInt& aDriveNumber) const
189 if(path.Length() >= 2 && ((TChar)path[1]==(TChar)':'))
191 r = RFs::CharToDrive(path[0],aDriveNumber);
199 * The order of the data in the buffer is:
200 * Word1 : NotificationSize (2 bytes) , PathSize (2 bytes)
201 * Word2 : NewNameSize (2 bytes) , NotificationType (2 bytes)
203 * Word(s) : Path (TText8) , [Any sub-class members]
205 EXPORT_C TInt TFsNotification::UID(TUid& aUID) const
207 TUint* word3 = PtrAdd((TUint*)this, sizeof(TUint)*2);
214 CFsNotificationList* CFsNotificationList::NewL(TInt aBufferSize)
216 CFsNotificationList* self = new(ELeave) CFsNotificationList;
217 CleanupStack::PushL(self);
218 self->iBuf = HBufC8::NewL(aBufferSize);
219 self->iBufferPtr.Set((TUint8*)self->iBuf->Ptr(),0,self->iBuf->Des().MaxSize());
220 CleanupStack::Pop(self);
224 CFsNotificationList::CFsNotificationList()
225 : iTailPckg(iTail), iBufferPtr(NULL,0)
229 CFsNotificationList::~CFsNotificationList()
234 TInt CFsNotificationList::BufferSize() const
239 const TFsNotification * CFsNotificationList::NextNotification()
241 TFsNotification* notification;
247 TUint* startptr = (TUint*)iBuf->Ptr();
248 TUint* nptr = PtrAdd(startptr, iHead);
249 TInt bufferSize = iBuf->Des().MaxSize();
250 TUint* endOfBuffer = PtrAdd(startptr, bufferSize);
252 if(*nptr == KNotificationBufferFiller || nptr == endOfBuffer)
255 notification = (TFsNotification*)startptr;
259 notification = (TFsNotification*)nptr;
261 iHead += notification->NotificationSize();
262 if(iHead == bufferSize)
269 EXPORT_C CFsNotify* CFsNotify::NewL(RFs& aFs, TInt aBufferSize)
271 CFsNotify* self=new(ELeave) CFsNotify;
272 CleanupStack::PushL(self);
274 //Making sure buffer size is at least minimally large and not too big
275 if(aBufferSize > (KMaxTInt/2))
277 User::Leave(KErrArgument);
279 else if(aBufferSize < KMinNotificationBufferSize)
281 aBufferSize = KMinNotificationBufferSize;
284 self->ConstructL(aFs, Align4(aBufferSize));
285 CleanupStack::Pop(self);
289 void CFsNotify::ConstructL(RFs& aFs,TInt aBufferSize)
291 iBody = new(ELeave) CFsNotifyBody();
292 iBody->iBuffer = CFsNotificationList::NewL(aBufferSize);
293 User::LeaveIfError(iBody->iFsNotify.Open(aFs,iBody->iBuffer,iBody->iBufferStatus));
296 CFsNotify::CFsNotify()
300 EXPORT_C CFsNotify::~CFsNotify()
306 iBody->iBuffer->iTail = 0;
307 iBody->iBuffer->iHead = 0;
308 iBody->iFsNotify.Close();
309 delete iBody->iBuffer;
315 CFsNotifyBody::CFsNotifyBody()
319 CFsNotifyBody::~CFsNotifyBody()
323 EXPORT_C TInt CFsNotify::AddNotification(TUint aNotificationType, const TDesC& aPath, const TDesC& aFilename)
325 if(aNotificationType == 0 || (aPath.Length() <= 0 && aFilename.Length() <= 0))
328 return iBody->iFsNotify.AddNotification(aNotificationType, aPath, aFilename);
331 //Removes notification request, does not close session
332 EXPORT_C TInt CFsNotify::RemoveNotifications()
334 return iBody->iFsNotify.RemoveNotifications();
337 EXPORT_C TInt CFsNotify::RequestNotifications(TRequestStatus& aStatus)
339 if(aStatus == KRequestPending || ((iBody->iClientStatus != NULL) && (*iBody->iClientStatus == KRequestPending)))
342 iBody->iClientStatus = &aStatus;
343 //Read the new notifications which will start at tail.
344 //(Also this forbids user access outside permitted range)
345 iBody->iBuffer->iHead = iBody->iBuffer->iTail;
346 iBody->iFsNotify.RequestNotifications(aStatus, iBody->iBuffer->iTailPckg);
350 //Cancels notification request, does not close session
351 EXPORT_C TInt CFsNotify::CancelNotifications(TRequestStatus& aStatus)
353 if(aStatus != KRequestPending || &aStatus != iBody->iClientStatus)
356 TInt r = iBody->iFsNotify.CancelNotifications();
357 aStatus = !KRequestPending;
358 iBody->iBuffer->iHead = 0;
359 iBody->iBuffer->iTail = 0;
363 EXPORT_C const TFsNotification * CFsNotify::NextNotification()
365 return iBody->iBuffer->NextNotification();
369 TInt RFsNotify::Open(RFs& aFs, CFsNotificationList* aBuffer, TRequestStatus& aBufferStatus)
371 if(aBuffer == NULL || aBuffer->iBuf == NULL || &aFs == NULL || &aBufferStatus==NULL)
374 TInt err = CreateSubSession(aFs,EFsNotificationOpen);
377 aBufferStatus = KRequestPending;
378 //memclr((TUint8*)aBuffer->iBuf->Ptr(),aBuffer->iBuf->Des().MaxSize());
379 SendReceive(EFsNotificationBuffer, TIpcArgs(&aBuffer->iBufferPtr,aBuffer->iBuf->Des().MaxSize()), aBufferStatus);
384 void RFsNotify::Close()
386 CloseSubSession(EFsNotificationSubClose);
390 [Re]Issues notification request
391 Updates buffer, if supplied.
393 @return - last readable index of buffer.
395 void RFsNotify::RequestNotifications(TRequestStatus& aStatus, TPckg<TInt>& aTailPckg)
397 aStatus = KRequestPending;
398 SendReceive(EFsNotificationRequest,TIpcArgs(&aTailPckg),aStatus);
401 TInt RFsNotify::CancelNotifications()
403 //there can only be one outstanding notification request at a time
404 return (SendReceive(EFsNotificationCancel));
407 //Adds notification filter
408 TInt RFsNotify::AddNotification(TUint aNotificationType, const TDesC& aPath, const TDesC& aFilename)
410 if(aNotificationType == 0 || (aPath.Length() <= 0 && aFilename.Length() <= 0))
413 return (SendReceive(EFsNotificationAdd,TIpcArgs(aNotificationType,&aPath,&aFilename)));
416 //Removes request, does not close session
417 TInt RFsNotify::RemoveNotifications()
419 return(SendReceive(EFsNotificationRemove));
421 #else //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
423 EXPORT_C TFsNotification::TFsNotificationType TFsNotification::NotificationType() const
425 Panic(ENotificationPanic);
426 return (TFsNotification::TFsNotificationType)0;
429 EXPORT_C TInt TFsNotification::Path(TPtrC&) const
431 Panic(ENotificationPanic);
432 return KErrNotSupported;
435 EXPORT_C TInt TFsNotification::NewName(TPtrC&) const
437 Panic(ENotificationPanic);
438 return KErrNotSupported;
441 EXPORT_C TInt TFsNotification::Attributes(TUint&,TUint&) const
443 Panic(ENotificationPanic);
444 return KErrNotSupported;
447 EXPORT_C TInt TFsNotification::FileSize(TInt64&) const
449 Panic(ENotificationPanic);
450 return KErrNotSupported;
454 EXPORT_C TInt TFsNotification::DriveNumber(TInt&) const
456 Panic(ENotificationPanic);
457 return KErrNotSupported;
460 EXPORT_C TInt TFsNotification::UID(TUid& aUID) const
462 Panic(ENotificationPanic);
463 return KErrNotSupported;
467 EXPORT_C CFsNotify* CFsNotify::NewL(RFs& , TInt)
469 Panic(ENotificationPanic);
470 User::Leave(KErrNotSupported);
474 EXPORT_C CFsNotify::~CFsNotify()
476 Panic(ENotificationPanic);
479 EXPORT_C TInt CFsNotify::AddNotification(TUint, const TDesC&, const TDesC&)
481 Panic(ENotificationPanic);
482 return KErrNotSupported;
485 EXPORT_C TInt CFsNotify::RemoveNotifications()
487 Panic(ENotificationPanic);
488 return KErrNotSupported;
491 EXPORT_C TInt CFsNotify::RequestNotifications(TRequestStatus&)
493 Panic(ENotificationPanic);
494 return KErrNotSupported;
497 EXPORT_C TInt CFsNotify::CancelNotifications(TRequestStatus&)
499 Panic(ENotificationPanic);
500 return KErrNotSupported;
503 EXPORT_C const TFsNotification * CFsNotify::NextNotification()
505 Panic(ENotificationPanic);
509 CFsNotificationList::~CFsNotificationList()
511 Panic(ENotificationPanic);
514 CFsNotifyBody::CFsNotifyBody()
516 Panic(ENotificationPanic);
519 CFsNotifyBody::~CFsNotifyBody()
521 Panic(ENotificationPanic);
524 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION