userlibandfileserver/fileserver/sfsrv/cl_find.cpp
branchRCL_3
changeset 80 597aaf25e343
parent 0 a41df078684a
--- a/userlibandfileserver/fileserver/sfsrv/cl_find.cpp	Sat Feb 20 00:10:51 2010 +0200
+++ b/userlibandfileserver/fileserver/sfsrv/cl_find.cpp	Fri Mar 12 15:50:11 2010 +0200
@@ -20,93 +20,104 @@
 #define gPathDelimiter TChar(';')
 enum TMode {EFindByDrives,EFindByDrivesInPath,EFindByPath};
 
-TInt TFindFile::DoFindInDir()
+
 //
 // Look for aFileName in aDir
 //
+TInt TFindFile::DoFindInDir()
 	{
 
-	if (iDir==NULL)
+	if (!iDir)
 		{
 		TEntry entry;
 		TInt r=iFs->Entry(iFile.FullName(),entry);
-		if (r==KErrNone /*|| r==KErrAccessDenied*/)
-			return(KErrNone);
-		else if (r==KErrNoMemory)
+
+		if (r != KErrNone && r != KErrNoMemory && r != KErrPermissionDenied)
+			r = KErrNotFound;
+
 			return r;
-		else if (r==KErrPermissionDenied)
-			return (KErrPermissionDenied);
-		else
-			return(KErrNotFound);
 		}
+	
 	TInt r=iFs->GetDir(iFile.FullName(),KEntryAttMaskSupported|KEntryAttAllowUid,ESortByName,*iDir);
-	if (r==KErrNoMemory)
-		return r;
-	else if (r==KErrPermissionDenied)
-		return r;
-	else if (r!=KErrNone)
-		return(KErrNotFound);
-	if ((*iDir)->Count()==0)
+
+    if(r == KErrNone)
+        {
+        if(!(*iDir)->Count())
+            r = KErrNotFound; //-- empty directory
+        }
+    else if(r != KErrNoMemory && r != KErrPermissionDenied)
+        {
+            r = KErrNotFound;        
+        }
+
+	if (r != KErrNone && iDir)
 		{
 		delete (*iDir);
 		*iDir=NULL;
-		return(KErrNotFound);
 		}
-	else
-		return(KErrNone);
+
+	return r; 
 	}
 
-TInt TFindFile::DoFindNextInPath()
+
 //
 // Look for aFileName along the path and increment aPathPos
 //
+TInt TFindFile::DoFindNextInPath()
 	{
 
 	if (iMode==EFindByDrivesInPath)
 		{
 		TInt r=DoFindNextInDriveList();
-		if (r==KErrNone)
-			return(KErrNone);
 		if (r!=KErrNotFound)
 			return(r);
+
 		iMode=EFindByPath;
 		}
+
 	FOREVER
 		{
 		if (iPath->Length()<iPathPos)
 			return(KErrNotFound);
+
 		TPtrC path(iPath->Ptr()+iPathPos,iPath->Length()-iPathPos);
+
 		TInt r=path.Locate(gPathDelimiter);
+
 		if (r==KErrNotFound)
 			r=path.Length();
+
 		path.Set(path.Ptr(),r);
 		iPathPos+=r+1;
 		TFileName fileName=iFile.NameAndExt();
 		iFile.Set(fileName,&path,NULL);
+
 		if (iFile.FullName().Length()>=2 && iFile.FullName()[1]==KDriveDelimiter)
 			{
 			TInt r=DoFindInDir();
-			if (r==KErrNone)
-				return(KErrNone);
-			if (r!=KErrNotFound)
-				return(r);
+			if (r == KErrNotFound)
 			continue;
+			
+            return(r);
 			}
+		
 		iMode=EFindByDrivesInPath;
 		
 		r=FindByDir(fileName,path);
-		if (r==KErrNone)
-			return(KErrNone);
-		if (r!=KErrNotFound)
+		
+        if (r == KErrNotFound)
+			continue;
+		
 			return(r);
 		}
 
 	}
 
-TInt TFindFile::DoFindNextInDriveList()
+
 //
 // Look for aFileName in all available drives in order
 //
+TInt TFindFile::DoFindNextInDriveList()
 	{
 	
 	TInt found;	
@@ -235,9 +246,12 @@
 		TPtrC path(iFile.Path());
 		fileName.Set(nameAndExt,&path,&drive);
 		iFile=fileName;
+		
 		TInt r=DoFindInDir();
+		
 		if (r==KErrNone)
 			return(KErrNone);
+		
 		if (r!=KErrNotFound)
 			return(r);
 		}	
@@ -246,15 +260,14 @@
 
 
 
-EXPORT_C TFindFile::TFindFile(RFs& aFs)
-	: iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iMatchMask(0)
 /**
 Constructor taking a file server session.
 
 @param aFs File server session.
 */
+EXPORT_C TFindFile::TFindFile(RFs& aFs)
+	               :iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iDir(NULL), iMatchMask(0)
 	{
-	
 	iFile.Set(_L(""),NULL,NULL);
 	}
 
@@ -274,29 +287,25 @@
 	TInt r=iFile.Set(aFileName,NULL,NULL);
 	if (r!=KErrNone)
 		return(r);
+
 	iPath=aPath;
 	iPathPos=0;
 	iMode=EFindByPath;
 	r=DoFindInDir();	
 	
-	
-	if (r==KErrNone)
-		return(KErrNone);
-	if (r!=KErrNotFound)
-		return(r);
-	if ((iPath==NULL) || (iPath->Length()==0))
-		return(KErrNotFound);
-	
-	
+	// if it's not in the current dir and a search path was specified, look there.
+	if (r == KErrNotFound && iPath && iPath->Length())
 	r=DoFindNextInPath();
+
 	return(r);
 	}
 
-TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir)
+
 //
 // Look for aFileName in aDir on each connected drive
 // Make initial check for aFileName in aDir on current drive
 //
+TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir)
 	{
 		
 	if (aFileName.Length() <= 0) 
@@ -305,23 +314,24 @@
 	TInt r=iFs->Parse(aFileName,aDir,iFile);
 	if (r!=KErrNone)
 		return(r);
+	
 	TInt searchResult=DoFindInDir();
-	if(searchResult==KErrNoMemory)                       
+	if(searchResult == KErrNoMemory || searchResult == KErrPermissionDenied)
 		return(searchResult);
 	
-	if(searchResult==KErrPermissionDenied)
-		return (KErrPermissionDenied);
-	
 	r=iFs->DriveList(iDrvList,KDriveAttAll);
 	if (r!=KErrNone)
 		return(r);
+	
 	TInt drive;
 	r=RFs::CharToDrive(iFile.Drive()[0],drive);
 	if (r!=KErrNone)
 		return(r);
+
 	iDrvList[drive]=0; // Drive 'drive' has already been searched
 	iCurrentDrive=EDriveY;
 	iMode=EFindByDrives;
+	
 	if (searchResult==KErrNone)
 		return(KErrNone);
 	
@@ -329,10 +339,21 @@
 	return(DoFindNextInDriveList());
 	}
 
+/**
+    internal helper method that deletes the (*iDir) object in the case of errors and assigns NULL to the client's pointer top it.
+*/
+TInt TFindFile::CallSafe(TInt aResult)
+	{
+	if (aResult != KErrNone && iDir)
+		{
+		delete *iDir;
+		*iDir = NULL;
+		iDir = NULL;
+		}
+	return aResult;
+	}
 
 
-
-EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath)
 /**
 Searches for a file/directory in one or more directories in the path.
 
@@ -367,16 +388,16 @@
 @see TFindFile::File
 @see TFindFile::Find
 */
+EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath)
 	{
 
 	iDir=NULL;
-	return(DoFindByPath(aFileName,aPath));
+	return CallSafe(DoFindByPath(aFileName,aPath));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir)
 /**
 Searches for a file/directory in a directory on all available drives.
 
@@ -416,51 +437,50 @@
 @see TFindFile::Find()
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir)
 	{
 
 	iDir=NULL;
-	return(DoFindByDir(aFileName,aDir));
+	return CallSafe(DoFindByDir(aFileName,aDir));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir)
+
 /**
-Searches for one or more files/directories in the directories contained in a
-path list.
+Searches for one or more files/directories in the directories contained in a path list.
 
-Wildcard characters can be specified. The search ends when one or more
-filenames matching aFileName is found, or when every
-directory in the path list has been unsuccessfully searched.
-To begin searching again after a successful match has been made,
-use FindWild().
+Wildcard characters can be specified. The search ends when one or more filenames matching aFileName is found, or when every
+directory in the path list has been unsuccessfully searched. To begin searching again after a successful match has been made, use FindWild().
 
-Using function SetFindMask it is possible to specify a combination of 
-attributes that the drives to be searched must match.
+Using function SetFindMask it is possible to specify a combination of  attributes that the drives to be searched must match.
 
 Notes:
 
-1. The caller of the function is responsible for deleting
-   aDir after the function has returned.
+1. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
 
-2. Calling TFindFile::File() after a successful search gets the drive letter
-   and directory containing the file(s). The filenames can be retrieved via
-   the array of TEntry::iName objects contained in aDir. If you want to
-   retrieve the fully qualified path of a file, you need to parse the path and
-   the filename.
+2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
+
+3. Calling TFindFile::File() after a successful search gets the drive letter and directory containing the file(s). 
+   The filenames can be retrieved via the array of TEntry::iName objects contained in aDir. If you want to  retrieve the fully 
+   qualified path of a file, you need to parse the path and the filename.
    
-@param aFileName The filename to search for. May contain wildcards. If
-                 it specifies a directory as well as a filename, then that
+@param aFileName The filename to search for. May contain wildcards. If it specifies a directory as well as a filename, then that
                  directory is searched first.
-@param aPath     List of directories to search. Paths in this list must be
-                 separated by a semicolon character, but a semicolon is not
-                 required after the final path. The directories are searched
-                 in the order in which they occur in the list.
-                 Directories must be fully qualified, including
-                 a drive letter, and the name must end with a backslash.
-@param aDir      On return, contains the entries for all files matching
-				 aFileName in the first directory in which a match occurred.
+
+@param aPath     List of directories to search. Paths in this list must be separated by a semicolon character, but a semicolon is not
+                 required after the final path. The directories are searched in the order in which they occur in the list.
+                 Directories must be fully qualified, including a drive letter, and the name must end with a backslash.
+
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
 
 @return KErrNone, if one or more matching files was	found;
         KErrNotFound, if no matching file was found in any of the directories.
@@ -471,79 +491,80 @@
 @see TEntry::iName
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir)
 	{
 
 	iDir=&aDir;
-	return(DoFindByPath(aFileName,aPath));
+	*iDir=NULL;
+
+	return CallSafe(DoFindByPath(aFileName,aPath));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir)
+
 /**
-Searches, using wildcards, for one or more files/directories in a specified
-directory.
+Searches, using wildcards, for one or more files/directories in a specified directory.
 
-If no matching file is found in that directory, all available drives are
-searched in descending alphabetical order, from Y: to A:, and ending
-with the Z: drive.Using function SetFindMask it is possible to specify a 
-combination of attributes that the drives to be searched must match.
+If no matching file is found in that directory, all available drives are searched in descending alphabetical order, from Y: to A:, and ending
+with the Z: drive.Using function SetFindMask it is possible to specify a combination of attributes that the drives to be searched must match.
 
-The search ends when one or more matching filenames are found, or when every 
-available drive has been unsuccessfully searched. To begin searching again 
-after a successful match has been made, use FindWild(). Wildcards may be
-specified in the filename.
+The search ends when one or more matching filenames are found, or when every  available drive has been unsuccessfully searched. 
+To begin searching again after a successful match has been made, use FindWild(). Wildcards may be specified in the filename.
 
 Notes:
 
-1. A drive letter may be specified in aDirPath (or in aFileName). If a drive 
-   is specified, that drive is searched first, followed by the other available 
-   drives, in descending alphabetical order. If no drive is specified, the drive 
-   contained in the session path is searched first.
+1. A drive letter may be specified in aDirPath (or in aFileName). If a drive  is specified, that drive is searched first, 
+   followed by the other available drives, in descending alphabetical order. If no drive is specified, the drive contained in the session 
+   path is searched first.
+
+2. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
 
-2. The function sets aDir to NULL, then allocates memory for it before appending 
-   entries to the list. Therefore, aDir should have no memory allocated to it 
-   before this function is called, otherwise this memory will become orphaned.
+3. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
 
-3. The caller of this function is responsible for deleting aDir after the function 
-   has returned.
 
-4. Calling TFindFile::File() after a successful search returns the drive letter 
-   and directory containing the file(s). Filenames may be retrieved via the array 
-   of TEntry::iNames contained in aDir. If you want to retrieve the fully 
+4. Calling TFindFile::File() after a successful search returns the drive letter and directory containing the file(s). 
+   Filenames may be retrieved via the array of TEntry::iNames contained in aDir. If you want to retrieve the fully 
    qualified path of a file, you will need to parse the path and the filename.
 
-@param aFileName The filename to search for. May contain wildcards. If a path 
-                 is specified, it overrides the path specified in aDirPath.
-                 If no path is specified, the path contained in aDirPath is
-                 used in the search.
+@param aFileName The filename to search for. May contain wildcards. If a path is specified, it overrides the path specified in aDirPath.
+                 If no path is specified, the path contained in aDirPath is used in the search.
+
 @param aDirPath  Path indicating a directory to search on each drive.
-@param aDir      On return, contains the entries for all files
-                 matching aFileName.
+
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
                  
 @return KErrNone if one or more matching files was found;
-        KErrNotFound if no matching file was found in the directory on any 
-        of the drives.
+        KErrNotFound if no matching file was found in the directory on any of the drives.
         KErrArgument, if the filename is empty. 
                 
 @see TFindFile::FindWild
 @see TFindFile::File
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir)
 	{
-
 	iDir=&aDir;
-	return(DoFindByDir(aFileName,aDirPath));
+    *iDir=NULL;
+	
+	return CallSafe(DoFindByDir(aFileName,aDirPath));
 	}
 
 
 
 
-TInt TFindFile::DoFind()
 //
 // Find the next match
 //
+TInt TFindFile::DoFind()
 	{
 
 	TInt ret=KErrNone;
@@ -565,7 +586,7 @@
 
 
 
-EXPORT_C TInt TFindFile::Find()
+
 /**
 Searches for the next file/directory.
 
@@ -589,6 +610,7 @@
 @see TFindFile::SetFindMask()
 
 */
+EXPORT_C TInt TFindFile::Find()
 	{
 
 //	iDir=NULL;
@@ -598,7 +620,7 @@
 
 
 
-EXPORT_C TInt TFindFile::FindWild(CDir*& aDir)
+
 /**
 Searches for the next file/directory.
 
@@ -609,21 +631,25 @@
 
 Notes:
 
-1. The caller of this function is responsible for deleting aDir after
-   the function has returned 
+1. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
+
+2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
+
+3. Calling TFindFile::File() after a successful search, will return the drive letter and the directory containing the file(s).
+   The filenames may be retrieved via the array of TEntry::iName objects contained in aDir. If you want to retrieve the fully qualified
+   path of a file, you will need to parse the path and the filename using the TParse class or derived classes.
 
-2. Calling TFindFile::File() after a successful search, will return
-   the drive letter and the directory containing the file(s).
-   The filenames may be retrieved via the array of TEntry::iName objects
-   contained in aDir. If you want to retrieve the fully qualified
-   path of a file, you will need to parse the path and the filename using
-   the TParse class or derived classes.
-
-@param aDir On return, contains the entries for all matching files found in
-            the next directory.
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
             
-@return KErrNone, if further occurrences were found;
-        KErrNotFound, if no more matching files were found.
+@return KErrNone      if further occurrences were found;
+        KErrNotFound  if no more matching files were found.
 
 
 @see TParse
@@ -633,15 +659,18 @@
 @see TFindFile::FindWildByDir
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWild(CDir*& aDir)
 	{
 
 	iDir=&aDir;
-	return(DoFind());
+    *iDir=NULL;
+
+	return CallSafe(DoFind());
 	}
 
 
 
-EXPORT_C TInt TFindFile::SetFindMask(TUint aMask)
+
 /**
 Can be used in order to specify a combination of drive attributes that the drives 
 to be searched must match. When searching without specifying a mask, all drives, except the 
@@ -653,6 +682,7 @@
         KErrArgument, if the mask supplied is invalid.
 */
 
+EXPORT_C TInt TFindFile::SetFindMask(TUint aMask)
 	 {	
 	 TInt r =ValidateMatchMask(aMask);
 	 if(r!=KErrNone) 
@@ -667,8 +697,5 @@
 	 	return KErrNone;
 	 	
 	 	}
-	 
-	
-											
 	 }