--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/integrityservices/integritytree.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,281 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:
+*
+*/
+
+
+/**
+ @file
+ @released
+ @internalTechnology
+*/
+
+#include "integritytree.h"
+
+#include "integrityservices.h"
+#include <f32file.h>
+
+using namespace Swi;
+
+CIntegrityTreeLeaf* CIntegrityTreeLeaf::NewLC(const TDesC& aFileName, TIntegrityServicesEvent aType,
+ const TDesC& aOwningJournal)
+ {
+ CIntegrityTreeLeaf* self = new (ELeave) CIntegrityTreeLeaf(aType, aOwningJournal);
+ CleanupStack::PushL(self);
+ self->ConstructL(aFileName);
+ return self;
+ }
+
+CIntegrityTreeLeaf::~CIntegrityTreeLeaf()
+ {
+ delete iFileName;
+ }
+
+CIntegrityTreeLeaf::CIntegrityTreeLeaf(TIntegrityServicesEvent aType, const TDesC& aOwningJournal)
+ : iType(aType), iOwningJournal(aOwningJournal)
+ {
+ }
+
+void CIntegrityTreeLeaf::ConstructL(const TDesC& aFileName)
+ {
+ iFileName = aFileName.AllocL();
+ }
+
+CIntegrityTreeLeaf* CIntegrityTreeLeaf::Peer()
+ {
+ return iPeer;
+ }
+
+TIntegrityServicesEvent CIntegrityTreeLeaf::Type()
+ {
+ return iType;
+ }
+
+const TDesC& CIntegrityTreeLeaf::Name()
+ {
+ return *iFileName;
+ }
+
+const TDesC& CIntegrityTreeLeaf::Journal()
+ {
+ return iOwningJournal;
+ }
+
+void CIntegrityTreeLeaf::SetPeer(CIntegrityTreeLeaf* aPeer)
+ {
+ iPeer = aPeer;
+ }
+
+CIntegrityTreeNode* CIntegrityTreeNode::NewL(const TDesC& aDirectoryName)
+ {
+ CIntegrityTreeNode* self = CIntegrityTreeNode::NewLC(aDirectoryName);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CIntegrityTreeNode* CIntegrityTreeNode::NewLC(const TDesC& aDirectoryName)
+ {
+ CIntegrityTreeNode* self = new (ELeave) CIntegrityTreeNode;
+ CleanupStack::PushL(self);
+ self->ConstructL(aDirectoryName);
+ return self;
+ }
+
+
+const TDesC& CIntegrityTreeNode::Name()
+ {
+ return *iDirName;
+ }
+
+CIntegrityTreeLeaf* CIntegrityTreeNode::AddNodeL(const TDesC& aFileName, TIntegrityServicesEvent aType, const TDesC& aOwningJournal)
+ {
+ RBuf filename;
+ filename.CreateL(aFileName, aFileName.Length());
+ CleanupClosePushL(filename);
+ CIntegrityTreeLeaf* leaf = DoAddNodeL(filename, aType, aOwningJournal);
+ CleanupStack::PopAndDestroy(&filename);
+ return leaf;
+ }
+
+TInt CIntegrityTreeNode::FindNode(const TDesC& aFileName, TIntegrityServicesEvent aType)
+ {
+ RBuf filename;
+ TInt found = 0;
+ TRAPD(err,
+ filename.CreateL(aFileName, aFileName.Length());
+ CleanupClosePushL(filename);
+ found = DoFindNode(filename, aType);
+ CleanupStack::PopAndDestroy(&filename);
+ );
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ return found;
+ }
+
+void CIntegrityTreeNode::WalkTreeL(TTreeWalkFunctionL aFunc, TIntegrityServicesEvent aTypeFilter,
+ RFs& aFs, RLoader& aLoader, CFileMan& aFileMan,
+ CIntegrityServices& aIntegrityServices, CIntegrityServices::TFailType aFailType)
+ {
+ RBuf filename;
+ filename.CreateL(*iDirName, KMaxFileName);
+ CleanupClosePushL(filename);
+ DoWalkTreeL(filename, aFunc, aTypeFilter, aFs, aLoader, aFileMan, aIntegrityServices, aFailType);
+ CleanupStack::PopAndDestroy(&filename);
+ }
+
+CIntegrityTreeLeaf* CIntegrityTreeNode::DoAddNodeL(TDes& aFileName, TIntegrityServicesEvent aType, const TDesC& aOwningJournal)
+ {
+ TInt pathDividerPos = aFileName.Locate(KPathDelimiter);
+ User::LeaveIfError(pathDividerPos); // The must be at least /this/ directory name
+
+ TPtrC dirPtr(aFileName.Left(pathDividerPos));
+ if (dirPtr.CompareF(*iDirName) != 0)
+ {
+ User::Leave(KErrBadName); // this doesn't belong to us.
+ }
+
+ // remove the directory section of the path.
+ aFileName.Delete(0, pathDividerPos+1);
+
+ // Now, see if we need to pass it on up the chain.
+ pathDividerPos = aFileName.Locate(KPathDelimiter);
+ if (pathDividerPos == KErrNotFound)
+ {
+ // This is now just a file name, add a new file name leaf here.
+ CIntegrityTreeLeaf* leaf = CIntegrityTreeLeaf::NewLC(aFileName, aType, aOwningJournal);
+ iFiles.AppendL(leaf);
+ CleanupStack::Pop(leaf);
+ return leaf;
+ }
+ else
+ {
+ // There are more directories in the chain... See if we have an entry...
+ dirPtr.Set(aFileName.Left(pathDividerPos));
+
+ TInt dirCount(iDirectories.Count());
+ for (TInt i = 0; i < dirCount; ++i)
+ {
+ if (dirPtr.CompareF(iDirectories[i]->Name()) == 0)
+ {
+ return iDirectories[i]->DoAddNodeL(aFileName, aType, aOwningJournal);
+ }
+ }
+ // doesn't yet exist. Add it to the tree.
+ CIntegrityTreeNode* node = CIntegrityTreeNode::NewLC(dirPtr);
+ iDirectories.AppendL(node);
+ CleanupStack::Pop(node);
+
+ // pass the remaining path down the tree
+ return node->DoAddNodeL(aFileName, aType, aOwningJournal);
+ }
+ }
+
+TInt CIntegrityTreeNode::DoFindNode(TDes& aFileName, TIntegrityServicesEvent aType)
+ {
+ TInt pathDividerPos = aFileName.Locate(KPathDelimiter);
+ if (pathDividerPos < 0)
+ return pathDividerPos; // The must be at least one path delimiter in the file name
+
+ TPtrC dirPtr(aFileName.Left(pathDividerPos));
+ if (dirPtr.CompareF(*iDirName) != 0)
+ {
+ return KErrBadName; // this doesn't belong to us.
+ }
+
+ // remove the directory section of the path.
+ aFileName.Delete(0, pathDividerPos+1);
+
+ // Now, see if we need to pass it on up the chain.
+ pathDividerPos = aFileName.Locate(KPathDelimiter);
+ if (pathDividerPos == KErrNotFound)
+ {
+ TInt nameCount(iFiles.Count());
+ for (TInt i = 0; i < nameCount; ++i)
+ {
+ if (iFiles[i]->Type() == aType &&
+ iFiles[i]->Name().CompareF(aFileName) == 0)
+ {
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+ else
+ {
+ // There are more directories in the chain... See if we have an entry...
+ dirPtr.Set(aFileName.Left(pathDividerPos));
+
+ TInt dirCount(iDirectories.Count());
+ for (TInt i = 0; i < dirCount; ++i)
+ {
+ if (dirPtr.CompareF(iDirectories[i]->Name()) == 0)
+ {
+ return iDirectories[i]->DoFindNode(aFileName, aType);
+ }
+ }
+ return KErrNotFound;
+ }
+ }
+
+void CIntegrityTreeNode::DoWalkTreeL(TDes& aPath, TTreeWalkFunctionL aFunc,
+ TIntegrityServicesEvent aTypeFilter, RFs& aFs, RLoader& aLoader, CFileMan& aFileMan,
+ CIntegrityServices& aIntegrityServices, CIntegrityServices::TFailType aFailType)
+ {
+ aPath.Append(KPathDelimiter);
+
+ // Feed all the files for this node to the walk function
+
+ TInt fileCount(iFiles.Count());
+ TInt i;
+ for (i = 0; i < fileCount; ++i)
+ {
+ CIntegrityTreeLeaf* leaf = iFiles[i];
+ if (leaf->Type() == aTypeFilter)
+ {
+ aIntegrityServices.SimulatePowerFailureL(aFailType, CIntegrityServices::EBeforeAction, leaf->Name());
+ aFunc(aPath, leaf, aFs, aLoader, aFileMan);
+ aIntegrityServices.SimulatePowerFailureL(aFailType, CIntegrityServices::EAfterAction, leaf->Name());
+ }
+ }
+
+ // Walk the child nodes for this tree
+ TInt len = aPath.Length();
+ TInt dirCount(iDirectories.Count());
+ for (i = 0; i < dirCount; ++i)
+ {
+ CIntegrityTreeNode* node = iDirectories[i];
+ aPath.SetLength(len);
+ aPath.Append(node->Name());
+ node->DoWalkTreeL(aPath, aFunc, aTypeFilter, aFs, aLoader, aFileMan, aIntegrityServices, aFailType);
+ }
+ }
+
+CIntegrityTreeNode::CIntegrityTreeNode()
+ {
+ }
+
+void CIntegrityTreeNode::ConstructL(const TDesC& aDirectoryName)
+ {
+ iDirName = aDirectoryName.AllocL();
+ }
+
+CIntegrityTreeNode::~CIntegrityTreeNode()
+ {
+ delete iDirName;
+ iDirectories.ResetAndDestroy();
+ iFiles.ResetAndDestroy();
+ }