Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

dirtree.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  DIRTREE.C                                                                           */
00003 /*                                                                                      */
00004 /*  Author: Eli Boling                                                                  */
00005 /*  Description: Directory tree implementation                                          */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 
00023 #include        <assert.h>
00024 #include        <stdio.h>
00025 #include        <stdlib.h>
00026 #include        <string.h>
00027 
00028 #include        "basetype.h"
00029 #include        "ram.h"
00030 
00031 #include        "dirtree.h"
00032 #include        "dirtree-common.h"
00033 
00034 #define DIRTREE_FILE_SIGNATURE  MAKEFOURCC('D', 'T', '0', '1')
00035 static int DirTree_SignatureBase=0x696C6345;
00036 static int DirTree_SignatureOffset=0x21657370;
00037 
00038 typedef struct  DirTree
00039 {
00040         char *                          Name;
00041         geVFile_Time            Time;
00042         geVFile_Attributes      AttributeFlags;
00043         long                            Size;
00044         geVFile_Hints           Hints;
00045         long                            Offset;
00046         struct DirTree *        Parent;
00047         struct DirTree *        Children;
00048         struct DirTree *        Siblings;
00049 }       DirTree;
00050 
00051 typedef struct  DirTree_Finder
00052 {
00053         char *          MatchName;
00054         char *          MatchExt;
00055         DirTree *       Current;
00056 }       DirTree_Finder;
00057 
00058 DirTree *DirTree_Create(void)
00059 {
00060         DirTree *       Tree;
00061 
00062         Tree = geRam_Allocate(sizeof(*Tree));
00063         if      (!Tree)
00064                 return Tree;
00065 
00066         memset(Tree, 0, sizeof(*Tree));
00067         Tree->Name = DuplicateString("");
00068         if      (!Tree->Name)
00069         {
00070                 geRam_Free(Tree);
00071                 return NULL;
00072         }
00073 
00074         Tree->AttributeFlags |= GE_VFILE_ATTRIB_DIRECTORY;
00075 
00076         return Tree;
00077 }
00078 
00079 void    DirTree_Destroy(DirTree *Tree)
00080 {
00081         assert(Tree);
00082         assert(Tree->Name);
00083 
00084         if      (Tree->Children)
00085                 DirTree_Destroy(Tree->Children);
00086 
00087         if      (Tree->Siblings)
00088                 DirTree_Destroy(Tree->Siblings);
00089 
00090         geRam_Free(Tree->Name);
00091         geRam_Free(Tree);
00092 }
00093 
00094 static  geBoolean       WriteTree(const DirTree *Tree, geVFile *File)
00095 {
00096         int             Length;
00097         int             Terminator;
00098 
00099         assert(Tree);
00100         assert(Tree->Name);
00101 
00102         Terminator = DIRTREE_LIST_NOTTERMINATED;
00103         if      (geVFile_Write(File, &Terminator, sizeof(Terminator)) == GE_FALSE)
00104                 return GE_FALSE;
00105 
00106         // Write out the name
00107         Length = strlen(Tree->Name) + 1;
00108         if      (geVFile_Write(File, &Length, sizeof(Length)) == GE_FALSE)
00109                 return GE_FALSE;
00110         if      (Length > 0)
00111         {
00112                 if      (geVFile_Write(File, Tree->Name, Length) == GE_FALSE)
00113                         return GE_FALSE;
00114         }
00115 
00116         // Write out the attribute information
00117         if      (geVFile_Write(File, &Tree->Time, sizeof(Tree->Time)) == GE_FALSE)
00118                 return GE_FALSE;
00119 
00120         if      (geVFile_Write(File, &Tree->AttributeFlags, sizeof(Tree->AttributeFlags)) == GE_FALSE)
00121                 return GE_FALSE;
00122 
00123         if      (geVFile_Write(File, &Tree->Size, sizeof(Tree->Size)) == GE_FALSE)
00124                 return GE_FALSE;
00125 
00126         if      (geVFile_Write(File, &Tree->Offset, sizeof(Tree->Offset)) == GE_FALSE)
00127                 return GE_FALSE;
00128         
00129         if      (geVFile_Write(File, &Tree->Hints.HintDataLength, sizeof(Tree->Hints.HintDataLength)) == GE_FALSE)
00130                 return GE_FALSE;
00131 
00132         if      (Tree->Hints.HintDataLength != 0)
00133                 //bug fix. someone got copy happy and forgot to remove the & from Tree->Hints.HintData
00134                 if      (geVFile_Write(File, Tree->Hints.HintData, Tree->Hints.HintDataLength) == GE_FALSE)
00135                         return GE_FALSE;
00136         
00137         // Write out the Children
00138         if      (Tree->Children)
00139         {
00140                 WriteTree(Tree->Children, File);
00141         }
00142         else
00143         {
00144                 Terminator = DIRTREE_LIST_TERMINATED;
00145                 if      (geVFile_Write(File, &Terminator, sizeof(Terminator)) == GE_FALSE)
00146                         return GE_FALSE;
00147         }
00148 
00149         // Write out the Siblings
00150         if      (Tree->Siblings)
00151         {
00152                 WriteTree(Tree->Siblings, File);
00153         }
00154         else
00155         {
00156                 Terminator = DIRTREE_LIST_TERMINATED;
00157                 if      (geVFile_Write(File, &Terminator, sizeof(Terminator)) == GE_FALSE)
00158                         return GE_FALSE;
00159         }
00160         
00161         return GE_TRUE;
00162 }
00163 
00164 static  geBoolean DirTree_WriteToFile1(const DirTree *Tree, geVFile *File, long *Size)
00165 {
00166         DirTree_Header  Header;
00167         long                    StartPosition;
00168         long                    EndPosition;
00169         
00170         if      (geVFile_Tell(File, &StartPosition) == GE_FALSE)
00171                 return GE_FALSE;
00172 
00173         Header.Signature = DIRTREE_FILE_SIGNATURE;
00174         if      (geVFile_Seek(File, sizeof(Header), GE_VFILE_SEEKCUR) == GE_FALSE)
00175                 return GE_FALSE;
00176         
00177         if      (WriteTree(Tree, File) == GE_FALSE)
00178                 return GE_FALSE;
00179 
00180         geVFile_Tell(File, &EndPosition);
00181         Header.Size = EndPosition - StartPosition;
00182         geVFile_Seek(File, StartPosition, GE_VFILE_SEEKSET);
00183         if      (geVFile_Write(File, &Header, sizeof(Header)) == GE_FALSE)
00184                 return GE_FALSE;
00185 
00186         // Make sure that we end up at the end of the directory.
00187         geVFile_Seek(File, EndPosition, GE_VFILE_SEEKSET);
00188 
00189         *Size = Header.Size;
00190 
00191         return GE_TRUE;
00192 }
00193 
00194 void DirTree_SetFileSize(DirTree *Tree, long Size)
00195 {
00196         assert(Tree);
00197         Tree->Size = Size;
00198 }
00199 
00200 void DirTree_GetFileSize(DirTree *Tree, long *Size)
00201 {
00202         assert(Tree);
00203         *Size = Tree->Size;
00204 }
00205 
00206 geBoolean DirTree_WriteToFile(const DirTree *Tree, geVFile *File)
00207 {
00208         geBoolean       Res;
00209         long            Size;
00210 
00211         Res = DirTree_WriteToFile1(Tree, File, &Size);
00212         if      (Res == GE_FALSE)
00213                 return Res;
00214 
00215         return GE_TRUE;
00216 }
00217 
00218 geBoolean DirTree_GetSize(const DirTree *Tree, long *Size)
00219 {
00220         geVFile *                               FS;
00221         geVFile_MemoryContext   Context;
00222 
00223         /*
00224                 This function is implemented via a write to a memory file for
00225                 a few reasons.  First, it makes it easier to maintain this code.  We
00226                 don't have to track format information in Write, Read and Size functions,
00227                 just in Write and Read.  Second, it gets us testing of the memory
00228                 file system for free.  Third, it was cute.  The last one doesn't count,
00229                 of course, but the other two are compelling.  This API ends up being
00230                 inefficient, but the assumption is that it will be called rarely.
00231         */
00232 
00233         Context.Data       = NULL;
00234         Context.DataLength = 0;
00235 
00236         FS = geVFile_OpenNewSystem(NULL,
00237                                                          GE_VFILE_TYPE_MEMORY,
00238                                                          NULL,
00239                                                          &Context,
00240                                                          GE_VFILE_OPEN_CREATE);
00241         if      (!FS)
00242                 return GE_FALSE;
00243 
00244         if      (DirTree_WriteToFile1(Tree, FS, Size) == GE_FALSE)
00245                 return GE_FALSE;
00246 
00247         if      (geVFile_Size(FS, Size) == GE_FALSE)
00248                 return GE_FALSE;
00249 
00250         geVFile_Close(FS);
00251 
00252         return GE_TRUE;
00253 }
00254 
00255 static  geBoolean       ReadTree(geVFile *File, DirTree **TreePtr)
00256 {
00257         int                     Terminator;
00258         int                     Length;
00259         DirTree *       Tree;
00260 
00261         if      (geVFile_Read(File, &Terminator, sizeof(Terminator)) == GE_FALSE)
00262                 return GE_FALSE;
00263 
00264         if      (Terminator == DIRTREE_LIST_TERMINATED)
00265         {
00266                 *TreePtr = NULL;
00267                 return GE_TRUE;
00268         }
00269 
00270         Tree = geRam_Allocate(sizeof(*Tree));
00271         if      (!Tree)
00272                 return GE_FALSE;
00273         memset(Tree, 0, sizeof(*Tree));
00274 
00275         // Read the name
00276         if      (geVFile_Read(File, &Length, sizeof(Length)) == GE_FALSE)
00277                 goto fail;
00278 
00279         assert(Length > 0);
00280         Tree->Name = geRam_Allocate(Length);
00281         if      (!Tree->Name)
00282         {
00283                 geRam_Free(Tree);
00284                 return GE_FALSE;
00285         }
00286         
00287         if      (geVFile_Read(File, Tree->Name, Length) == GE_FALSE)
00288                 goto fail;
00289 
00290 //printf("Reading '%s'\n", Tree->Name);
00291 
00292         // Read out the attribute information
00293         if      (geVFile_Read(File, &Tree->Time, sizeof(Tree->Time)) == GE_FALSE)
00294                 goto fail;
00295 
00296         if      (geVFile_Read(File, &Tree->AttributeFlags, sizeof(Tree->AttributeFlags)) == GE_FALSE)
00297                 goto fail;
00298 
00299         if      (geVFile_Read(File, &Tree->Size, sizeof(Tree->Size)) == GE_FALSE)
00300                 goto fail;
00301 
00302         if      (geVFile_Read(File, &Tree->Offset, sizeof(Tree->Offset)) == GE_FALSE)
00303                 goto fail;
00304 
00305         if      (geVFile_Read(File, &Tree->Hints.HintDataLength, sizeof(Tree->Hints.HintDataLength)) == GE_FALSE)
00306                 goto fail;
00307 
00308         if      (Tree->Hints.HintDataLength != 0)
00309         {
00310                 Tree->Hints.HintData = geRam_Allocate(Tree->Hints.HintDataLength);
00311                 if      (!Tree->Hints.HintData)
00312                         goto fail;
00313                 //bug fix. someone got copy happy and forgot to remove the & from Tree->Hints.HintData
00314                 if      (geVFile_Read(File, Tree->Hints.HintData, Tree->Hints.HintDataLength) == GE_FALSE)
00315                         goto fail;
00316         }
00317 
00318 //printf("Reading children of '%s'\n", Tree->Name);
00319         // Read the children
00320         if      (ReadTree(File, &Tree->Children) == GE_FALSE)
00321                 goto fail;
00322 
00323 //printf("Reading siblings of '%s'\n", Tree->Name);
00324         // Read the Siblings
00325         if      (ReadTree(File, &Tree->Siblings) == GE_FALSE)
00326                 goto fail;
00327 
00328 //DirTree_Dump(Tree);
00329 
00330         *TreePtr = Tree;
00331 
00332         return GE_TRUE;
00333 
00334 fail:
00335         DirTree_Destroy(Tree);
00336         return GE_FALSE;
00337 }
00338 
00339 DirTree *DirTree_CreateFromFile(geVFile *File)
00340 {
00341         DirTree *               Res;
00342         DirTree_Header  Header;
00343         long                    StartPosition;
00344         long                    EndPosition;
00345         
00346         if      (geVFile_Tell(File, &StartPosition) == GE_FALSE)
00347                 return GE_FALSE;
00348 
00349         if      (geVFile_Read(File, &Header, sizeof(Header)) == GE_FALSE)
00350                 return NULL;
00351 
00352         if      (Header.Signature != DIRTREE_FILE_SIGNATURE)
00353                 return GE_FALSE;
00354 
00355         if      (ReadTree(File, &Res) == GE_FALSE)
00356                 return NULL;
00357 
00358         geVFile_Tell(File, &EndPosition);
00359         if      (Header.Size != EndPosition - StartPosition)
00360         {
00361                 DirTree_Destroy(Res);
00362                 return NULL;
00363         }
00364 
00365         return Res;
00366 }
00367 
00368 DirTree *DirTree_FindExact(const DirTree *Tree, const char *Path)
00369 {
00370         static char     Buff[_MAX_PATH];
00371         DirTree *       Siblings;
00372 
00373         assert(Tree);
00374         assert(Path);
00375 
00376         if      (*Path == '\\')
00377                 return NULL;
00378 
00379         if      (*Path == '\0')
00380                 return (DirTree *)Tree;
00381 
00382         Path = GetNextDir(Path, Buff);
00383 
00384         Siblings = Tree->Children;
00385         while   (Siblings)
00386         {
00387                 if      (!stricmp(Siblings->Name, Buff))
00388                 {
00389                         if      (!*Path)
00390                                 return Siblings;
00391                         return DirTree_FindExact(Siblings, Path);
00392                 }
00393                 Siblings = Siblings->Siblings;
00394         }
00395 
00396         return NULL;
00397 }
00398 
00399 DirTree *DirTree_FindPartial(
00400         const DirTree * Tree,
00401         const char *    Path,
00402         const char **   LeftOvers)
00403 {
00404         static char     Buff[_MAX_PATH];
00405         DirTree *       Siblings;
00406 
00407         assert(Tree);
00408         assert(Path);
00409 
00410         if      (*Path == '\\')
00411                 return NULL;
00412 
00413         *LeftOvers = Path;
00414 
00415         if      (*Path == '\0')
00416                 return (DirTree *)Tree;
00417 
00418         Path = GetNextDir(Path, Buff);
00419 
00420         Siblings = Tree->Children;
00421         while   (Siblings)
00422         {
00423                 if      (!stricmp(Siblings->Name, Buff))
00424                 {
00425                         *LeftOvers = Path;
00426                         if      (!*Path)
00427                                 return Siblings;
00428                         return DirTree_FindPartial(Siblings, Path, LeftOvers);
00429                 }
00430                 Siblings = Siblings->Siblings;
00431         }
00432 
00433         return (DirTree *)Tree;
00434 }
00435 
00436 DirTree * DirTree_AddFile(DirTree *Tree, const char *Path, geBoolean IsDirectory)
00437 {
00438         DirTree *               NewEntry;
00439         const char *    LeftOvers;
00440 
00441         assert(Tree);
00442         assert(Path);
00443         assert(IsDirectory == GE_TRUE || IsDirectory == GE_FALSE);
00444 
00445         assert(strlen(Path) > 0);
00446 
00447         if      (PathHasDir(Path))
00448         {
00449                 Tree = DirTree_FindPartial(Tree, Path, &LeftOvers);
00450                 if      (!Tree)
00451                         return NULL;
00452         
00453                 if      (PathHasDir(LeftOvers))
00454                         return NULL;
00455         
00456                 Path = LeftOvers;
00457         }
00458 
00459         NewEntry = geRam_Allocate(sizeof(*NewEntry));
00460         if      (!NewEntry)
00461                 return NULL;
00462 
00463         memset(NewEntry, 0, sizeof(*NewEntry));
00464         NewEntry->Name = DuplicateString(Path);
00465         if      (!NewEntry->Name)
00466         {
00467                 geRam_Free(NewEntry->Name);
00468                 geRam_Free(NewEntry);
00469                 return NULL;
00470         }
00471 
00472         NewEntry->Siblings = Tree->Children;
00473                                                  Tree->Children = NewEntry;
00474 
00475         if      (IsDirectory == GE_TRUE)
00476                 NewEntry->AttributeFlags |= GE_VFILE_ATTRIB_DIRECTORY;
00477 
00478         return NewEntry;
00479 }
00480 
00481 geBoolean DirTree_Remove(DirTree *Tree, DirTree *SubTree)
00482 {
00483         DirTree         Siblings;
00484         DirTree *       pSiblings;
00485         DirTree *       Parent;
00486         DirTree *       ParanoiaCheck;
00487 
00488         assert(Tree);
00489         assert(SubTree);
00490 
00491         Parent = SubTree->Parent;
00492         assert(Parent);
00493 
00494         ParanoiaCheck = Parent;
00495         while   (ParanoiaCheck && ParanoiaCheck != Tree)
00496                 ParanoiaCheck = ParanoiaCheck->Parent;
00497         if      (!ParanoiaCheck)
00498                 return GE_FALSE;
00499 
00500         Siblings.Siblings = Parent->Children;
00501         assert(Siblings.Siblings);
00502         pSiblings = &Siblings;
00503         while   (pSiblings->Siblings)
00504         {
00505                 if      (pSiblings->Siblings == SubTree)
00506                 {
00507                         pSiblings->Siblings = SubTree->Siblings;
00508                         if      (SubTree == Parent->Children)
00509                                 Parent->Children = SubTree->Siblings;
00510                         SubTree->Siblings = NULL;
00511                         DirTree_Destroy(SubTree);
00512                         return GE_TRUE;
00513                 }
00514                 pSiblings = pSiblings->Siblings;
00515         }
00516 
00517         assert(!"Shouldn't be a way to get here");
00518         return GE_FALSE;
00519 }
00520 
00521 void DirTree_SetFileAttributes(DirTree *Tree, geVFile_Attributes Attributes)
00522 {
00523         assert(Tree);
00524         assert(Attributes);
00525 
00526         // Only support the read only flag
00527         assert(!(Attributes & ~GE_VFILE_ATTRIB_READONLY));
00528         assert(!(Tree->AttributeFlags & GE_VFILE_ATTRIB_DIRECTORY));
00529 
00530         Tree->AttributeFlags = (Tree->AttributeFlags & ~GE_VFILE_ATTRIB_READONLY)  | Attributes;
00531 }
00532 
00533 void DirTree_GetFileAttributes(DirTree *Tree, geVFile_Attributes *Attributes)
00534 {
00535         assert(Tree);
00536         assert(Attributes);
00537 
00538         *Attributes = Tree->AttributeFlags;
00539 }
00540 
00541 void DirTree_SetFileOffset(DirTree *Leaf, long Offset)
00542 {
00543         assert(Leaf);
00544         assert(!(Leaf->AttributeFlags & GE_VFILE_ATTRIB_DIRECTORY));
00545 
00546         Leaf->Offset = Offset;
00547 }
00548 
00549 void DirTree_GetFileOffset(DirTree *Leaf, long *Offset)
00550 {
00551         assert(Leaf);
00552         assert(!(Leaf->AttributeFlags & GE_VFILE_ATTRIB_DIRECTORY));
00553 
00554         *Offset = Leaf->Offset;
00555 }
00556 
00557 void DirTree_SetFileTime(DirTree *Tree, const geVFile_Time *Time)
00558 {
00559         assert(Tree);
00560 
00561         Tree->Time = *Time;
00562 }
00563 
00564 void DirTree_GetFileTime(DirTree *Tree, geVFile_Time *Time)
00565 {
00566         assert(Tree);
00567 
00568         *Time = Tree->Time;
00569 }
00570 
00571 geBoolean DirTree_SetFileHints(DirTree *Tree, const geVFile_Hints *Hints)
00572 {
00573         if      (Tree->Hints.HintData)
00574                 geRam_Free(Tree->Hints.HintData);
00575 
00576         if      (Hints->HintData)
00577         {
00578                 Tree->Hints.HintData = geRam_Allocate(Hints->HintDataLength);
00579                 if      (!Tree->Hints.HintData)
00580                         return GE_FALSE;
00581                 memcpy(Tree->Hints.HintData, Hints->HintData, Hints->HintDataLength);
00582         }
00583         Tree->Hints.HintDataLength = Hints->HintDataLength;
00584         return GE_TRUE;
00585 }
00586 
00587 void DirTree_GetFileHints(DirTree *Tree, geVFile_Hints *Hints)
00588 {
00589         *Hints = Tree->Hints;
00590 }
00591 
00592 geBoolean DirTree_GetName(DirTree *Tree, char *Buff, int MaxLen)
00593 {
00594         int     Length;
00595 
00596         assert(Tree);
00597         assert(Buff);
00598         assert(MaxLen > 0);
00599 
00600         Length = strlen(Tree->Name);
00601         if      (Length > MaxLen)
00602                 return GE_FALSE;
00603 
00604         memcpy(Buff, Tree->Name, Length + 1);
00605 
00606         return GE_TRUE;
00607 }
00608 
00609 geBoolean DirTree_FileExists(const DirTree *Tree, const char *Path)
00610 {
00611         if      (DirTree_FindExact(Tree, Path) == NULL)
00612                 return GE_FALSE;
00613 
00614         return GE_TRUE;
00615 }
00616 
00617 DirTree_Finder * DirTree_CreateFinder(DirTree *Tree, const char *Path)
00618 {
00619         DirTree_Finder *        Finder;
00620         DirTree *                       SubTree;
00621         char                            Directory[_MAX_PATH];
00622         char                            Name[_MAX_FNAME];
00623         char                            Ext[_MAX_EXT];
00624 
00625         assert(Tree);
00626         assert(Path);
00627 
00628         _splitpath(Path, NULL, Directory, Name, Ext);
00629 
00630         SubTree = DirTree_FindExact(Tree, Directory);
00631         if      (!SubTree)
00632                 return NULL;
00633 
00634         Finder = geRam_Allocate(sizeof(*Finder));
00635         if      (!Finder)
00636                 return Finder;
00637 
00638         Finder->MatchName = DuplicateString(Name);
00639         if      (!Finder->MatchName)
00640         {
00641                 geRam_Free(Finder);
00642                 return NULL;
00643         }
00644 
00645         // The RTL leaves the '.' on there.  That won't do.
00646         if      (*Ext == '.')
00647                 Finder->MatchExt = DuplicateString(&Ext[1]);
00648         else
00649                 Finder->MatchExt = DuplicateString(&Ext[0]);
00650 
00651         if      (!Finder->MatchExt)
00652         {
00653                 geRam_Free(Finder->MatchName);
00654                 geRam_Free(Finder);
00655                 return NULL;
00656         }
00657 
00658         Finder->Current = SubTree->Children;
00659 
00660         return Finder;
00661 }
00662 
00663 void DirTree_DestroyFinder(DirTree_Finder *Finder)
00664 {
00665         assert(Finder);
00666         assert(Finder->MatchName);
00667         assert(Finder->MatchExt);
00668 
00669         geRam_Free(Finder->MatchName);
00670         geRam_Free(Finder->MatchExt);
00671         geRam_Free(Finder);
00672 }
00673 
00674 DirTree * DirTree_FinderGetNextFile(DirTree_Finder *Finder)
00675 {
00676         DirTree *       Res;
00677         char            Name[_MAX_FNAME];
00678         char            Ext[_MAX_EXT];
00679 
00680         assert(Finder);
00681 
00682         Res = Finder->Current;
00683 
00684         if      (!Res)
00685                 return Res;
00686 
00687         do
00688         {
00689                 _splitpath(Res->Name, NULL, NULL, Name, Ext);
00690                 if      (MatchPattern(Name, Finder->MatchName) == GE_TRUE &&
00691                          MatchPattern(Ext,  Finder->MatchExt) == GE_TRUE)
00692                 {
00693                         break;
00694                 }
00695 
00696                 Res = Res->Siblings;
00697 
00698         }       while   (Res);
00699 
00700         if      (Res)
00701                 Finder->Current = Res->Siblings;
00702 
00703         return Res;
00704 }
00705 
00706 #ifdef  DEBUG
00707 
00708 static  void DirTree_Dump1(const DirTree *Tree, int i)
00709 {
00710         DirTree *       Temp;
00711 
00712         indent(i);
00713         if      (Tree->AttributeFlags & GE_VFILE_ATTRIB_DIRECTORY)
00714                 printf("\\%s\n", Tree->Name);
00715         else
00716                 printf("%-*s  %08x  %08x\n", 40 - i, Tree->Name, Tree->Offset, Tree->Size);
00717         Temp = Tree->Children;
00718         while   (Temp)
00719         {
00720                 DirTree_Dump1(Temp, i + 2);
00721                 Temp = Temp->Siblings;
00722         }
00723 }
00724 
00725 void DirTree_Dump(const DirTree *Tree)
00726 {
00727         printf("%-*s  %-8s  %-8s\n", 40, "Name", "Offset", "Size");
00728         printf("------------------------------------------------------------\n");
00729         DirTree_Dump1(Tree, 0);
00730 }
00731 
00732 #endif

Generated on Tue Sep 30 12:35:37 2003 for GTestAndEngine by doxygen 1.3.2