/*
* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: metadata struct for a remote file entry
*
*/
#include <bautils.h>
#include "rsfwfileentry.h"
#include "rsfwfiletable.h"
#include "rsfwconfig.h"
#include "rsfwvolumetable.h"
#include "rsfwvolume.h"
#include "rsfwrfeserver.h"
#include "rsfwlockmanager.h"
#include "mdebug.h"
#include "rsfwdirentattr.h"
// ----------------------------------------------------------------------------
// CRsfwFileEntry::NewLC
// ----------------------------------------------------------------------------
//
CRsfwFileEntry* CRsfwFileEntry::NewLC(const TDesC& aName, CRsfwFileEntry* aParent)
{
CRsfwFileEntry* self = new (ELeave) CRsfwFileEntry();
CleanupStack::PushL(self);
self->ConstructL(aName, aParent);
return self;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::NewL
// ----------------------------------------------------------------------------
//
CRsfwFileEntry* CRsfwFileEntry::NewL(const TDesC& aName, CRsfwFileEntry* aParent)
{
CRsfwFileEntry* self = NewLC(aName, aParent);
CleanupStack::Pop(self);
return self;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::NewL
// ----------------------------------------------------------------------------
//
CRsfwFileEntry* CRsfwFileEntry::NewL(RReadStream& aStream)
{
CRsfwFileEntry* self = new (ELeave) CRsfwFileEntry();
CleanupStack::PushL(self);
self->ConstructL(aStream);
CleanupStack::Pop(self);
return self;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ConstructL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ConstructL(const TDesC& aName, CRsfwFileEntry* aParent)
{
iType = KNodeTypeUnknown;
iParent = aParent;
iName = aName.AllocL();
iAtt = KEntryAttRemote;
iCachePriority = ECachePriorityNormal;
SetLockTimeout();
// Note that we don't yet attach the kid to its parent
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ConstructL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ConstructL(RReadStream& aStream)
{
// aStream >> *this;
this->InternalizeL(aStream);
SetLockTimeout();
// Note that we don't yet attach the kid to its parent
}
void CRsfwFileEntry::SetLockTimeout()
{
// When creating a file entry, the lock timeout is set to default
// even when internalizing from stream.
// We do not assume any locks that would survive server restarts
TInt timeout;
TInt err = CRsfwRfeServer::Env()->iRsfwConfig->Get(RsfwConfigKeys::KLockTimeout,
timeout);
if (!err)
{
iLockTimeout = (TUint)timeout;
}
else
{
iLockTimeout = KDefaultLockTimeout;
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::~CRsfwFileEntry
// ----------------------------------------------------------------------------
//
CRsfwFileEntry::~CRsfwFileEntry()
{
if (iFlags & KNodeHasValidLock)
{
if (iLockManager)
{
iLockManager->RemoveLockedEntry(this);
}
}
delete iName;
delete iMimeType;
delete iOpaqueFileId;
delete iLockToken;
if (!iFileTable || !iFileTable->Permanence())
{
RemoveCacheFile();
}
if ( iFileTable )
{
iFileTable->Volume()->iVolumeTable->RemoveFromMetadataLRUPriorityList(this);
}
delete iLockTimer;
// delete kids
TInt i;
for(i = 0; i < iKids.Count(); i++)
{
delete iKids[i];
}
iKids.Close();
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::FindKidByName
// ----------------------------------------------------------------------------
//
CRsfwFileEntry* CRsfwFileEntry::FindKidByName(const TDesC& aName)
{
DEBUGSTRING(("CRsfwFileEntry::FindKidByName"));
// finds a kid from a parent directory
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
CRsfwFileEntry* kid = iKids[i];
if (kid->iName->Compare(aName) == 0)
{
return iKids[i];
}
}
DEBUGSTRING(("...kid not found!"));
return NULL;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::RenameL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::RenameL(const TDesC& aName)
{
delete iName;
iName = NULL;
iName = aName.AllocL();
ReportEvent(KNotifyNodeModified);
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::AddKid
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::AddKid(CRsfwFileEntry& aFe)
{
// if this is the first kid to be added then probably
// we have to remove the entry from metadata LRU list
if ( iKids.Count() == 0 )
{
iFileTable->Volume()->iVolumeTable->RemoveFromMetadataLRUPriorityList(this);
}
iKids.Append(&aFe);
// (This assignment is sometimes redundant)
aFe.SetParent(this);
ReportEvent(KNotifyNodeModified);
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::RemoveKidL
// ----------------------------------------------------------------------------
//
TInt CRsfwFileEntry::RemoveKidL(CRsfwFileEntry* aFep)
{
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
if (iKids[i] == aFep)
{
ReportEvent(KNotifyNodeModified);
iKids.Remove(i);
// if we've just removed the last kid of the entry
// we can add the entry to metadata LRU list
if ( iKids.Count() == 0 )
{
iFileTable->Volume()->iVolumeTable->AddToMetadataLRUPriorityListL(this, ECachePriorityNormal);
}
return KErrNone;
}
}
DEBUGSTRING(("remove kid %d not found in %d",
aFep->Fid().iNodeId,
Fid().iNodeId));
return KErrNotFound;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::KidsCount
// ----------------------------------------------------------------------------
//
TInt CRsfwFileEntry::KidsCount()
{
return iKids.Count();
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::UnmarkKids
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::UnmarkKids()
{
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
iKids[i]->Unmark();
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::DropUnmarkedKidsL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::DropUnmarkedKidsL()
{
TInt i = 0;
while (i < iKids.Count())
{
if (!iKids[i]->IsMarked())
{
iKids[i]->DropLD();
}
else
{
i++;
}
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::DropLD
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::DropLD()
{
DEBUGSTRING(("CRsfwFileEntry::DropLD"));
TInt i = 0;
while (i < iKids.Count())
{
iKids[i]->DropLD();
}
iFileTable->RemoveL(this);
delete this;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::GetAttributes
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::GetAttributes(TDirEntAttr& aAttr) const
{
aAttr.iAtt = Att();
aAttr.iSize = Size();
aAttr.iModified = Modified();
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::GetAttributesL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::GetAttributesL(CRsfwDirEntAttr& aAttr) const
{
aAttr.SetAtt(Att());
aAttr.SetSize(Size());
aAttr.SetModified(Modified());
if (iOpaqueFileId)
{
aAttr.SetETagL(*OpaqueFileId());
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetAttributesL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetAttributesL(CRsfwDirEntAttr& aAttr,
TBool aAllMetaData)
{
SetAtt(aAttr.Att());
if (aAllMetaData)
{
SetSize(aAttr.Size());
SetModified(aAttr.Modified());
if (aAttr.MimeType())
{
SetMimeTypeL(*aAttr.MimeType());
}
if (aAttr.ETag())
{
SetOpaqueFileIdL(*aAttr.ETag());
}
SetUid(aAttr.Uid());
SetAttribValidationTime();
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::CacheFileName
// ----------------------------------------------------------------------------
//
TDesC* CRsfwFileEntry::CacheFileName()
{
DEBUGSTRING(("CRsfwFileEntry::CacheFileName"));
if (iCacheName.Length())
{
return &iCacheName;
}
return NULL;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetCacheFileName
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetCacheFileName(TDesC* aFn)
{
DEBUGSTRING16(("SetCacheFileName for file %S", Name()));
if (aFn)
{
iCacheName = *aFn;
ReportEvent(KNotifyNodeModified);
}
else
{
if (iCacheName.Length())
{
if (IsCached())
{
// Remove the cache list entry...
iFileTable->
Volume()->
iVolumeTable->RemoveFromLRUPriorityList(this);
}
// This is a request to discard the container
RFs fs = CRsfwRfeServer::Env()->iFs;
TInt err = fs.Delete(iCacheName);
if (err != KErrNone)
{
DEBUGSTRING(("Cannot purge cache file (err=%d)", err));
}
iCacheName.Zero();
// Reset locally dirty in case this is a directory.
// "locally dirty" means that the container
// doesn't have the "cached"/"protected" indicator bits up to date
// (these indicators refer to files contained in the directory).
iFlags &= ~KNodeLocallyDirty;
ReportEvent(KNotifyNodeModified);
}
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsCached
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsCached() const
{
DEBUGSTRING(("CRsfwFileEntry::IsCached, iAtt = %d, iFlags = %d", iAtt, iFlags));
if (((iAtt & KEntryAttRemote) == 0) ||
(iFlags & KNodePartlyCached))
{
DEBUGSTRING(("returning ETrue"));
// File is either fully or partly cached
return ETrue;
}
DEBUGSTRING(("returning EFalse"));
return EFalse;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsFullyCached
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsFullyCached() const
{
DEBUGSTRING(("CRsfwFileEntry::IsFullyCached"));
DEBUGSTRING(("iCachedSize = %d, iSize = %d", iCachedSize, iSize));
if (Type() == KNodeTypeDir)
{
return IsCached();
}
else
{
if (iCachedSize == iSize)
{
return IsCached();
}
else
{
return EFalse;
}
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetCached
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetCached(TBool aCached)
{
DEBUGSTRING(("CRsfwFileEntry::SetCached"));
TUint oldAtt = iAtt;
if (aCached)
{
if (Type() == KNodeTypeDir)
{
// set to fully cached
DEBUGSTRING(("set directory to fully cached"));
iAtt &= ~KEntryAttRemote;
iFlags &= ~KNodePartlyCached;
}
else
{
if (iCachedSize == iSize)
{
// set file to fully cached
DEBUGSTRING(("set file to fully cached"));
iAtt &= ~KEntryAttRemote;
iFlags &= ~KNodePartlyCached;
}
else
{
// Set file to partly cached
DEBUGSTRING(("set file to partly cached"));
iAtt |= KEntryAttRemote;
iFlags |= KNodePartlyCached;
}
}
}
else
{
// set to "fully" remote
DEBUGSTRING(("set to fully remote"));
iFlags &= ~KNodePartlyCached;
iAtt |= KEntryAttRemote;
iUseCachedData = EFalse;
iCachedSize = 0;
}
if (iAtt != oldAtt)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetCachedSize
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetCachedSize(TInt aFetchedSize)
{
TInt oldCachedSize = iCachedSize;
iCachedSize = aFetchedSize;
if (iCachedSize != oldCachedSize)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::RemoveCacheFile
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::RemoveCacheFile()
{
DEBUGSTRING(("CRsfwFileEntry::RemoveCacheFile"));
if (IsCached() && iFileTable)
{
// Remove the cache list entry...
iFileTable->Volume()->iVolumeTable->RemoveFromLRUPriorityList(this);
}
if (iCacheName.Length())
{
RFs fs = CRsfwRfeServer::Env()->iFs;
TInt err = fs.Delete(iCacheName);
if ((err != KErrNone) && (err != KErrNotFound))
{
DEBUGSTRING(("Cannot delete cache file (err=%d)", err));
}
iCacheName.Zero();
}
SetCached(EFalse);
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ValidateCacheFile
// Function checks whether cache file has not been accidentally or intentionally
// removed from the cache (which would mean the cache has been corrupted)
// In case the corruption has happened, the function sets entry as non-cached
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ValidateCacheFile()
{
if (iCacheName.Length() > 0)
{
RFs fs = CRsfwRfeServer::Env()->iFs;
if (! BaflUtils::FileExists(fs, iCacheName))
{
SetCached(EFalse);
}
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::PrintL
// ----------------------------------------------------------------------------
//
#ifdef _DEBUG
void CRsfwFileEntry::PrintL(TInt aLevel, TBool aKids, TBool aAll) const
{
if (!IsCached() && !aAll)
{
// Print only information about cached files
return;
}
HBufC* sBuf = HBufC::NewLC(KMaxPath);
TPtr s = sBuf->Des();
s.Fill(' ', 4 * aLevel);
s.AppendNum(iFid.iNodeId);
s.Append('|');
s.Append(*iName);
switch (iType)
{
case KNodeTypeDir:
s.Append('/');
break;
case KNodeTypeFile:
break;
default:
s.Append('?');
break;
}
if (IsCached())
{
s.Append('|');
s.Append(iCacheName);
}
DEBUGBUFFER((s));
CleanupStack::PopAndDestroy(sBuf); // sBuf
if (aKids)
{
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
iKids[i]->PrintL(aLevel + 1, aKids, aAll);
}
}
}
#else
void CRsfwFileEntry::PrintL(TInt, TBool, TBool) const
{
}
#endif //DEBUG
// ----------------------------------------------------------------------------
// CRsfwFileEntry::FullNameLC
// Construct full name relative to the root.
// The caller is responsible for deallocating the return value.
// ----------------------------------------------------------------------------
//
HBufC* CRsfwFileEntry::FullNameLC() const
{
// We know that we can't have more than KMaxPath entries,
// because each entry is minimally "/"
CRsfwFileEntry* entList[KMaxPath / 2];
HBufC* fn = HBufC::NewLC(KMaxPath);
TPtr fnp = fn->Des();
CRsfwFileEntry* fep = const_cast<CRsfwFileEntry*>(this);
TInt depth = 0;
do
{
if (depth >= (KMaxPath / 2))
{
// Too deep hierarchy
DEBUGSTRING(("CRsfwFileEntry::FullNameLC - Too deep hierarchy! %d", depth));
User::Leave(KErrGeneral);
}
entList[depth++] = fep;
fep = fep->iParent;
}
while (fep);
// We want to avoid going right to the root to avoid dots
depth--;
TInt i;
for (i = depth - 1; i >= 0; i--)
{
TPtr name = entList[i]->iName->Des();
if (i != (depth - 1))
{
// Skip "this" directories (should not happen)
if ((name[0] == '.') && (name.Length() == 1))
{
continue;
}
}
if ((fnp.Length() + name.Length()) >= (KMaxPath - 1))
{
// Too long name
DEBUGSTRING(("CRsfwFileEntry::FullNameLC - Too long name!"));
User::Leave(KErrGeneral);
}
fnp.Append(name);
if (i != 0)
{
fnp.Append('/');
}
}
return fn;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::TotalCachedSize
// ----------------------------------------------------------------------------
//
TInt CRsfwFileEntry::TotalCachedSize()
{
TInt cachedSize = 0;
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
TInt newSize = iKids[i]->TotalCachedSize();
cachedSize = cachedSize + newSize;
}
cachedSize = cachedSize + iCachedSize;
return cachedSize;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::TotalEntryCount
// ----------------------------------------------------------------------------
//
TInt CRsfwFileEntry::TotalEntryCount()
{
TInt entryCount = 0;
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
TInt kidCount = iKids[i]->TotalEntryCount();
entryCount += kidCount;
}
entryCount += 1; // itself
return entryCount;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::Lookup
// ----------------------------------------------------------------------------
//
CRsfwFileEntry* CRsfwFileEntry::Lookup(const TFid& aFid)
{
// linear search - immediate kids first
TInt i;
for (i = 0; i < iKids.Count(); i++)
{
CRsfwFileEntry* fep = iKids[i];
if (fep->Fid().iNodeId == aFid.iNodeId)
{
return iKids[i];
}
}
// Not found - lookup the kids' kids
for (i = 0; i < iKids.Count(); i++)
{
CRsfwFileEntry* fep;
fep = iKids[i]->Lookup(aFid);
if (fep)
{
return fep;
}
}
return NULL;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetLockedL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetLockedL(CRsfwLockManager* lockManager, TDesC8* aLockToken)
{
DEBUGSTRING16(("Set locked: marking file '%S' locked", Name()));
if (iLockTimeout > 0)
{
if (!iLockTimer)
{
iLockTimer = CPeriodic::NewL(CActive::EPriorityHigh);
}
// attempt to refresh when one third of the timeout has expired
TCallBack callBack(CRsfwFileEntry::LockTimerExpiredL, this);
iLockTimer->Start(1000000*(iLockTimeout/KLockRefreshAdjustment),
1000000*(iLockTimeout/KLockRefreshAdjustment),
callBack);
}
iFlags |= KNodeHasValidLock;
iLockManager = lockManager;
iLockManager->AddLockedEntryL(this);
if (aLockToken)
{
// We were not just refreshing the lock
delete iLockToken;
iLockToken = aLockToken;
}
ReportEvent(KNotifyNodeModified);
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::RemoveLocked
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::RemoveLocked()
{
DEBUGSTRING16(("Remove locked: marking file '%S' unlocked", Name()));
if (iFlags & KNodeHasValidLock)
{
iLockManager->RemoveLockedEntry(this);
iLockManager = NULL; // will be set in SetLockedL, if needed once again
iFlags &= ~KNodeHasValidLock;
ReportEvent(KNotifyNodeModified);
}
if (iLockToken)
{
delete iLockToken;
iLockToken = NULL;
}
if (iLockTimer)
{
delete iLockTimer;
iLockTimer = NULL;
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::LockTimerExpiredL
// ----------------------------------------------------------------------------
//
TInt CRsfwFileEntry::LockTimerExpiredL(TAny* aParam)
{
CRsfwFileEntry* fe = static_cast<CRsfwFileEntry*>(aParam);
DEBUGSTRING16(("Lock timer expired for '%S'", fe->Name()));
fe->iLockManager->RefreshLockL(fe);
return KErrNone;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::UseCachedData
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::UseCachedData()
{
// now meta data should tell us whether to use cached data or not
return iUseCachedData && !RemotelyDirty();
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetAttribValidationTime
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetAttribValidationTime()
{
iAttribValidation.UniversalTime();
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ExternalizeL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ExternalizeL(RWriteStream& aStream) const
{
DEBUGSTRING16(("CRsfwFileEntry::ExternalizeL for node %d", iFid.iNodeId));
DEBUGSTRING16(("iFlags: %d", &iFlags));
// The node Id must be the first entry
// iNodeId, iParentNodeId, iType, iSize, iAtt, iModified, iFlags,
// iCachedSize, iCachePriority
// iCacheName, iName, iMimeType,
// iOpaqueFileId, iLockToken
aStream.WriteInt32L(iFid.iNodeId);
if (iParent)
{
aStream.WriteUint32L(iParent->Fid().iNodeId);
}
else
{
// Root
aStream.WriteUint32L(0);
}
aStream.WriteUint8L(iType);
aStream.WriteInt32L(iSize);
aStream.WriteUint32L(iAtt);
aStream.WriteUint32L(I64HIGH(iModified.Int64()));
aStream.WriteUint32L(I64LOW(iModified.Int64()));
aStream.WriteUint32L(iFlags);
aStream.WriteInt32L(iCachedSize);
aStream.WriteInt32L(iCachePriority);
aStream.WriteInt32L(iUseCachedData);
aStream << iCacheName;
HBufC* null = HBufC::NewLC(0);
if (iName)
{
aStream << *iName;
}
else
{
aStream << *null;
}
if (iMimeType)
{
aStream << *iMimeType;
}
else
{
aStream << *null;
}
if (iOpaqueFileId)
{
aStream << *iOpaqueFileId;
}
else
{
aStream << *null;
}
if (iLockToken)
{
aStream << *iLockToken;
}
else
{
aStream << *null;
}
CleanupStack::PopAndDestroy(null); // null
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::InternalizeL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::InternalizeL(RReadStream& aStream)
{
DEBUGSTRING16(("CRsfwFileEntry::InternalizeL for node %d", iFid.iNodeId));
// iNodeId, iParentNodeId, iType, iSize, iAtt, iModified, iFlags,
// iCachedSize, iCachePriority
// iCacheName, iName, iMimeType,
// iOpaqueFileId, iLockToken
// make some basic checking whether data being internalized is correct
iFid.iNodeId = aStream.ReadInt32L();
if (iFid.iNodeId < 0)
{
User::Leave(KErrCorrupt);
}
iParentNodeId = aStream.ReadInt32L();
if (iParentNodeId < 0)
{
User::Leave(KErrCorrupt);
}
iType = aStream.ReadUint8L();
iSize = aStream.ReadInt32L();
if (iSize < 0)
{
User::Leave(KErrCorrupt);
}
iAtt = aStream.ReadUint32L();
TInt highTime = aStream.ReadUint32L();
TInt lowTime = aStream.ReadUint32L();
iModified = MAKE_TINT64(highTime, lowTime);
iFlags = aStream.ReadUint32L();
DEBUGSTRING16(("iFlags: %d", &iFlags));
iCachedSize = aStream.ReadInt32L();
if (iCachedSize < 0)
{
User::Leave(KErrCorrupt);
}
iCachePriority = aStream.ReadInt32L();
iUseCachedData = aStream.ReadInt32L();
aStream >> iCacheName;
HBufC* buf = HBufC::NewL(aStream, KMaxPath);
if (buf->Length())
{
iName = buf;
}
else
{
delete buf;
buf = NULL;
}
// MimeType
HBufC8* buf8 = HBufC8::NewL(aStream, KMaxPath);
if (buf8->Length())
{
iMimeType = buf8;
}
else
{
delete buf8;
}
// OpaqueFileId
buf8 = HBufC8::NewL(aStream, KMaxPath);
if (buf8->Length())
{
iOpaqueFileId = buf8;
}
else
{
delete buf8;
}
// LockToken
buf8 = HBufC8::NewL(aStream, KMaxPath);
if (buf8->Length())
{
iLockToken = buf8;
}
else
{
delete buf8;
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetType
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetType(TUint8 aType)
{
TUint8 oldType = iType;
iType = aType;
if (aType == KNodeTypeDir)
{
iAtt |= KEntryAttDir;
}
else
{
iAtt &= ~KEntryAttDir;
}
if (iType != oldType)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetSize
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetSize(TInt aSize)
{
TInt oldSize = iSize;
iSize = aSize;
if (iSize != oldSize)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetModified
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetModified(const TTime& aModified)
{
TTime oldModified = iModified;
iModified = aModified;
if (iModified != oldModified)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetAtt
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetAtt(TUint aAtt)
{
// Don't change caching and protected state
TUint oldAtt = iAtt;
if (IsFullyCached())
{
aAtt &= ~KEntryAttRemote;
}
else
{
aAtt |= KEntryAttRemote;
}
iAtt = aAtt;
// Set node type
if (iAtt & KEntryAttDir)
{
iType = KNodeTypeDir;
}
else
{
iType = KNodeTypeFile;
}
if (iAtt != oldAtt)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetMimeTypeL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetMimeTypeL(const TDesC8& aMimeType)
{
if (iMimeType)
{
delete iMimeType;
iMimeType = NULL;
}
if (aMimeType.Length())
{
iMimeType = aMimeType.AllocL();
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetOpaqueFileIdL
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetOpaqueFileIdL(const TDesC8& aOpaqueFileId)
{
if (iOpaqueFileId)
{
delete iOpaqueFileId;
iOpaqueFileId = NULL;
}
if (aOpaqueFileId.Length())
{
iOpaqueFileId = aOpaqueFileId.AllocL();
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsLocallyDirty
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsLocallyDirty() const
{
DEBUGSTRING16(("IsLocallyDirty for file %S", Name()));
return (iFlags & KNodeLocallyDirty) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsCancelled
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsCancelled() const
{
DEBUGSTRING16(("CRsfwFileEntry::IsCancelled()"));
return (iFlags & KNodeWritingCancelled) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetLocallyDirty
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetLocallyDirty()
{
DEBUGSTRING16(("SetLocallyDirty for file %S", Name()));
TUint oldFlags = iFlags;
iFlags |= KNodeLocallyDirty;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ResetLocallyDirty
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ResetLocallyDirty()
{
DEBUGSTRING16(("ResetLocallyDirty for file %S", Name()));
TUint oldFlags = iFlags;
iFlags &= ~KNodeLocallyDirty;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::RemotelyDirty
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::RemotelyDirty() const
{
return (iFlags & KNodeRemotelyDirty) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetRemotelyDirty
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetRemotelyDirty()
{
TUint oldFlags = iFlags;
iFlags |= KNodeRemotelyDirty;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ResetRemotelyDirty
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ResetRemotelyDirty()
{
TUint oldFlags = iFlags;
iFlags &= ~KNodeRemotelyDirty;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsMarked
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsMarked() const
{
return (iFlags & KNodeMarked) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::Mark
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::Mark()
{
// This is transient state (so, it need not be saved persistently)
iFlags |= KNodeMarked;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::Unmark
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::Unmark()
{
iFlags &= ~KNodeMarked;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetFlags
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetFlags(TUint aFlags)
{
TUint oldFlags = iFlags;
iFlags |= aFlags;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ResetFlags
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ResetFlags(TUint aFlags)
{
TUint oldFlags = iFlags;
iFlags &= ~aFlags;
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetOpenedForWriting
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetOpenedForWriting(TBool aOpenedForWriting)
{
TUint oldFlags = iFlags;
if (aOpenedForWriting)
{
DEBUGSTRING(("CRsfwFileEntry::SetOpenedForWriting TRUE"));
iFlags |= KNodeOpenedForWriting;
}
else
{
DEBUGSTRING(("CRsfwFileEntry::SetOpenedForWriting FALSE"));
iFlags &= ~KNodeOpenedForWriting;
}
if (iFlags != oldFlags)
{
ReportEvent(KNotifyNodeModified);
}
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsOpenedForWriting
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsOpenedForWriting() const
{
DEBUGSTRING(("CRsfwFileEntry::IsOpenedForWriting"));
return (iFlags & KNodeOpenedForWriting) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::SetNewlyCreated
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::SetNewlyCreated()
{
iFlags |= KNodeNewlyCreated;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ResetNewlyCreated
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ResetNewlyCreated()
{
iFlags &= ~KNodeNewlyCreated;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsNewlyCreated
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsNewlyCreated() const
{
return (iFlags & KNodeNewlyCreated) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::IsLocked
// ----------------------------------------------------------------------------
//
TBool CRsfwFileEntry::IsLocked() const
{
return (iFlags & KNodeHasValidLock) != 0;
}
// ----------------------------------------------------------------------------
// CRsfwFileEntry::ReportEvent
// ----------------------------------------------------------------------------
//
void CRsfwFileEntry::ReportEvent(TInt aEvent)
{
// If there is no file table,
// this is a transient entry
if (iFileTable && iFileTable->Permanence())
{
iFileTable->HandleMetaDataEvent(aEvent, this);
}
}
void CRsfwFileEntry::ResolveDirtyFilesL()
{
DEBUGSTRING(("CRsfwFileEntry::ResolveDirtyFilesL"));
if (this->Type() == KNodeTypeDir)
{
for (int i = 0; i < iKids.Count(); i++)
{
iKids[i]->ResolveDirtyFilesL();
}
}
else if (this->Type() == KNodeTypeFile)
{
// this is a leaf
iFileTable->ResolveDirtyFileL(this);
}
}