• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/amule/wxWidgets-2.8.12/src/mac/classic/morefile/
1/*
2	File:		IterateDirectory.c
3
4	Contains:	File Manager directory iterator routines.
5
6	Version:	MoreFiles
7
8	Copyright:	� 1995-2001 by Jim Luther and Apple Computer, Inc., all rights reserved.
9
10	You may incorporate this sample code into your applications without
11	restriction, though the sample code has been provided "AS IS" and the
12	responsibility for its operation is 100% yours.  However, what you are
13	not permitted to do is to redistribute the source as "DSC Sample Code"
14	after having made changes. If you're going to re-distribute the source,
15	we require that you make it clear in the source that the code was
16	descended from Apple Sample Code, but that you've made changes.
17
18	File Ownership:
19
20		DRI:				Apple Macintosh Developer Technical Support
21
22		Other Contact:		Apple Macintosh Developer Technical Support
23							<http://developer.apple.com/bugreporter/>
24
25		Technology:			DTS Sample Code
26
27	Writers:
28
29		(JL)	Jim Luther
30
31	Change History (most recent first):
32
33		 <2>	  2/7/01	JL		Added standard header. Updated names of includes.
34		<1>		12/06/99	JL		MoreFiles 1.5.
35*/
36
37#include <MacTypes.h>
38#include <MacErrors.h>
39#include <Files.h>
40
41#define	__COMPILINGMOREFILES
42
43#include "MoreFilesExtras.h"
44#include "IterateDirectory.h"
45
46/*
47**	Type definitions
48*/
49
50/* The IterateGlobals structure is used to minimize the amount of
51** stack space used when recursively calling IterateDirectoryLevel
52** and to hold global information that might be needed at any time.
53*/
54#if PRAGMA_STRUCT_ALIGN
55#pragma options align=mac68k
56#endif
57struct IterateGlobals
58{
59	IterateFilterProcPtr	iterateFilter;	/* pointer to IterateFilterProc */
60	CInfoPBRec				cPB;			/* the parameter block used for PBGetCatInfo calls */
61	Str63					itemName;		/* the name of the current item */
62	OSErr					result;			/* temporary holder of results - saves 2 bytes of stack each level */
63	Boolean					quitFlag;		/* set to true if filter wants to kill interation */
64	unsigned short			maxLevels;		/* Maximum levels to iterate through */
65	unsigned short			currentLevel;	/* The current level IterateLevel is on */
66	void					*yourDataPtr;	/* A pointer to caller data the filter may need to access */
67};
68#if PRAGMA_STRUCT_ALIGN
69#pragma options align=reset
70#endif
71
72typedef struct IterateGlobals IterateGlobals;
73typedef IterateGlobals *IterateGlobalsPtr;
74
75/*****************************************************************************/
76
77/*	Static Prototype */
78
79static	void	IterateDirectoryLevel(long dirID,
80									  IterateGlobals *theGlobals);
81
82/*****************************************************************************/
83
84/*
85**	Functions
86*/
87
88static	void	IterateDirectoryLevel(long dirID,
89									  IterateGlobals *theGlobals)
90{
91	if ( (theGlobals->maxLevels == 0) ||						/* if maxLevels is zero, we aren't checking levels */
92		 (theGlobals->currentLevel < theGlobals->maxLevels) )	/* if currentLevel < maxLevels, look at this level */
93	{
94		short index = 1;
95
96		++theGlobals->currentLevel;	/* go to next level */
97
98		do
99		{	/* Isn't C great... What I'd give for a "WITH theGlobals DO" about now... */
100
101			/* Get next source item at the current directory level */
102
103			theGlobals->cPB.dirInfo.ioFDirIndex = index;
104			theGlobals->cPB.dirInfo.ioDrDirID = dirID;
105			theGlobals->result = PBGetCatInfoSync((CInfoPBPtr)&theGlobals->cPB);
106
107			if ( theGlobals->result == noErr )
108			{
109				/* Call the IterateFilterProc */
110				CallIterateFilterProc(theGlobals->iterateFilter, &theGlobals->cPB, &theGlobals->quitFlag, theGlobals->yourDataPtr);
111
112				/* Is it a directory? */
113				if ( (theGlobals->cPB.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 )
114				{
115					/* We have a directory */
116					if ( !theGlobals->quitFlag )
117					{
118						/* Dive again if the IterateFilterProc didn't say "quit" */
119						IterateDirectoryLevel(theGlobals->cPB.dirInfo.ioDrDirID, theGlobals);
120					}
121				}
122			}
123
124			++index; /* prepare to get next item */
125		} while ( (theGlobals->result == noErr) && (!theGlobals->quitFlag) ); /* time to fall back a level? */
126
127		if ( (theGlobals->result == fnfErr) ||	/* fnfErr is OK - it only means we hit the end of this level */
128			 (theGlobals->result == afpAccessDenied) ) /* afpAccessDenied is OK, too - it only means we cannot see inside a directory */
129		{
130			theGlobals->result = noErr;
131		}
132
133		--theGlobals->currentLevel;	/* return to previous level as we leave */
134	}
135}
136
137/*****************************************************************************/
138
139pascal	OSErr	IterateDirectory(short vRefNum,
140								 long dirID,
141								 ConstStr255Param name,
142								 unsigned short maxLevels,
143								 IterateFilterProcPtr iterateFilter,
144								 void *yourDataPtr)
145{
146	IterateGlobals	theGlobals;
147	OSErr			result;
148	long			theDirID;
149	short			theVRefNum;
150	Boolean			isDirectory;
151
152	/* Make sure there is a IterateFilter */
153	if ( iterateFilter != NULL )
154	{
155		/* Get the real directory ID and make sure it is a directory */
156		result = GetDirectoryID(vRefNum, dirID, name, &theDirID, &isDirectory);
157		if ( result == noErr )
158		{
159			if ( isDirectory == true )
160			{
161				/* Get the real vRefNum */
162				result = DetermineVRefNum(name, vRefNum, &theVRefNum);
163				if ( result == noErr )
164				{
165					/* Set up the globals we need to access from the recursive routine. */
166					theGlobals.iterateFilter = iterateFilter;
167					theGlobals.cPB.hFileInfo.ioNamePtr = (StringPtr)&theGlobals.itemName;
168					theGlobals.cPB.hFileInfo.ioVRefNum = theVRefNum;
169					theGlobals.itemName[0] = 0;
170					theGlobals.result = noErr;
171					theGlobals.quitFlag = false;
172					theGlobals.maxLevels = maxLevels;
173					theGlobals.currentLevel = 0;	/* start at level 0 */
174					theGlobals.yourDataPtr = yourDataPtr;
175
176					/* Here we go into recursion land... */
177					IterateDirectoryLevel(theDirID, &theGlobals);
178
179					result = theGlobals.result;	/* set the result */
180				}
181			}
182			else
183			{
184				result = dirNFErr;	/* a file was passed instead of a directory */
185			}
186		}
187	}
188	else
189	{
190		result = paramErr;	/* iterateFilter was NULL */
191	}
192
193	return ( result );
194}
195
196/*****************************************************************************/
197
198pascal	OSErr	FSpIterateDirectory(const FSSpec *spec,
199									unsigned short maxLevels,
200									IterateFilterProcPtr iterateFilter,
201									void *yourDataPtr)
202{
203	return ( IterateDirectory(spec->vRefNum, spec->parID, spec->name,
204						maxLevels, iterateFilter, yourDataPtr) );
205}
206
207/*****************************************************************************/
208