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

fsvfs.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  FSVFS.C                                                                             */
00003 /*                                                                                      */
00004 /*  Author: Eli Boling                                                                  */
00005 /*  Description: Collection file system 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 #include        <stdio.h>
00023 #include        <stdlib.h>
00024 #include        <string.h>
00025 #include        <assert.h>
00026 
00027 #include        "ram.h"
00028 
00029 #include        "fsvfs.h"
00030 #include        "dirtree.h"
00031 
00032 //      "VF00"
00033 #define VFSFILEHEADER_SIGNATURE 0x30304656
00034 //      "CF00"
00035 #define VCFSFILEHEADER_SIGNATURE        0x30304643
00036 
00037 //      "VF01"
00038 #define VFSFILE_SIGNATURE               0x31304656
00039 
00040 //      "VF02"
00041 #define VFSFINDER_SIGNATURE             0x32304656
00042 
00043 #define HEADER_VERSION  0
00044 
00045 typedef struct  VFSFileHeader
00046 {
00047         unsigned int    Signature;
00048         unsigned short  Version;                        // Version number
00049         geBoolean               Dispersed;                      // Is this VFS dispersed?
00050         long                    DirectoryOffset;        // File offset to directory
00051         long                    DataLength;                     // Length of all file data, including VFS header
00052         long                    EndPosition;            // End Position in the RWOps file we were written to
00053 }       VFSFileHeader;
00054 
00055 // In the above structure, EndPosition should be the same as DataLength.  We use this for
00056 // asserts.
00057 
00058 typedef struct  VFSFile
00059 {
00060         unsigned int    Signature;
00061 
00062         geVFile *               RWOps;                          // Parent file for read/write ops
00063         struct VFSFile *System;                         // If we're a child, we need a back pointer
00064 
00065         DirTree *               DirEntry;                       // Directory entry for this file
00066         DirTree *               Directory;                      // Directory information for the VFS
00067 
00068         long                    RWOpsStartPos;          // Starting position in the RWOps file
00069         long                    CurrentRelPos;          // Current file pointer (relative to our start)
00070         long                    Length;                         // Current file size
00071         char                    Mask;
00072 
00073         unsigned int    OpenModeFlags;
00074 
00075         // Things that are specific to the Root node
00076         long                    EndPosition;            // End position in the RWOps file if we're a system
00077         geBoolean               IsSystem;                       // Am I the owner of the Directory?
00078         long                    DataLength;                     // Current size of the aggregate including VFS header
00079         geBoolean               Dispersed;                      // Is this VFS dispersed?
00080 
00081 }       VFSFile;
00082 
00083 typedef struct  VFSFinder
00084 {
00085         unsigned int            Signature;
00086         VFSFile *                       File;
00087         DirTree_Finder *        Finder;
00088         DirTree *                       LastFind;
00089 }       VFSFinder;
00090 
00091 #define CHECK_HANDLE(H) assert(H);assert(H->Signature == VFSFILE_SIGNATURE);
00092 #define CHECK_FINDER(F) assert(F);assert(F->Signature == VFSFINDER_SIGNATURE);
00093 
00094 static  void *  GENESISCC FSVFS_FinderCreate(
00095         geVFile *               FS,
00096         void *                  Handle,
00097         const char *    FileSpec)
00098 {
00099         VFSFinder *             Finder;
00100         VFSFile *               File;
00101 
00102         assert(FileSpec != NULL);
00103 
00104         File = Handle;
00105 
00106         CHECK_HANDLE(File);
00107 
00108         if      (!File->Directory)
00109                 return NULL;
00110 
00111         Finder = geRam_Allocate(sizeof(*Finder));
00112         if      (!Finder)
00113                 return NULL;
00114 
00115         memset(Finder, 0, sizeof(*Finder));
00116 
00117         Finder->Signature = VFSFINDER_SIGNATURE;
00118         Finder->File      = File;
00119         Finder->Finder    = DirTree_CreateFinder(File->Directory, FileSpec);
00120         if      (!Finder->Finder)
00121         {
00122                 geRam_Free(Finder);
00123                 return NULL;
00124         }
00125 
00126         return (void *)Finder;
00127 }
00128 
00129 static  geBoolean       GENESISCC FSVFS_FinderGetNextFile(void *Handle)
00130 {
00131         VFSFinder *     Finder;
00132 
00133         Finder = Handle;
00134 
00135         CHECK_FINDER(Finder);
00136 
00137         Finder->LastFind = DirTree_FinderGetNextFile(Finder->Finder);
00138         if      (Finder->LastFind)
00139                 return GE_TRUE;
00140 
00141         return GE_FALSE;
00142 }
00143 
00144 static  geBoolean       GENESISCC FSVFS_FinderGetProperties(void *Handle, geVFile_Properties *Properties)
00145 {
00146         VFSFinder *             Finder;
00147 
00148         assert(Properties);
00149 
00150         Finder = Handle;
00151 
00152         CHECK_FINDER(Finder);
00153 
00154         if      (!Finder->LastFind)
00155                 return GE_FALSE;
00156 
00157         DirTree_GetFileTime(Finder->LastFind, &Properties->Time);
00158         DirTree_GetFileAttributes(Finder->LastFind, &Properties->AttributeFlags);
00159         DirTree_GetFileSize(Finder->LastFind, &Properties->Size);
00160         DirTree_GetFileHints(Finder->LastFind, &Properties->Hints);
00161         return DirTree_GetName(Finder->LastFind, &Properties->Name[0], sizeof(Properties->Name));
00162 }
00163 
00164 static  void GENESISCC FSVFS_FinderDestroy(void *Handle)
00165 {
00166         VFSFinder *     Finder;
00167 
00168         Finder = Handle;
00169 
00170         CHECK_FINDER(Finder);
00171 
00172         assert(Finder->Finder);
00173 
00174         Finder->Signature = 0;
00175         DirTree_DestroyFinder(Finder->Finder);
00176         geRam_Free(Finder);
00177 }
00178 
00179 static  void *  GENESISCC FSVFS_Open(
00180         geVFile *               FS,
00181         void *                  Handle,
00182         const char *    Name,
00183         void *                  Dummy,
00184         unsigned int    OpenModeFlags)
00185 {
00186         VFSFile *       Context;
00187         VFSFile *       NewFile;
00188         DirTree *       FileEntry;
00189 
00190         Context = Handle;
00191 
00192         CHECK_HANDLE(Context);
00193 
00194         assert(Name);
00195 
00196         if      (!Context->Directory)
00197                 return NULL;
00198 
00199         /*
00200                 Right now, we only support update operations to a VFS which is being
00201                 created.  We can do create operations to a VFS which is being created,
00202                 or which already exists.  We can also support directory open operations
00203                 at anytime.
00204         */
00205         if      ((OpenModeFlags & GE_VFILE_OPEN_UPDATE)   &&
00206                  !(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY) &&
00207                  !(OpenModeFlags & GE_VFILE_OPEN_CREATE) &&
00208                  !(Context->System->OpenModeFlags & GE_VFILE_OPEN_CREATE))
00209                 return NULL;
00210 
00211         FileEntry = DirTree_FindExact(Context->Directory, Name);
00212         if      (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00213         {
00214                 if      (FileEntry)
00215                         return NULL;
00216 
00217                 FileEntry = DirTree_AddFile(Context->Directory,
00218                                                                         Name,
00219                                                                         (OpenModeFlags & GE_VFILE_OPEN_DIRECTORY) ? GE_TRUE : GE_FALSE);
00220                 if      (!FileEntry)
00221                         return NULL;
00222         }
00223         else
00224         {
00225                 if      (!FileEntry)
00226                         return NULL;
00227         }
00228 
00229         NewFile = geRam_Allocate(sizeof(*NewFile));
00230         if      (!NewFile)
00231                 return NewFile;
00232 
00233         memset(NewFile, 0, sizeof(*NewFile));
00234 
00235         NewFile->Signature        = VFSFILE_SIGNATURE;
00236         NewFile->DirEntry         = FileEntry;
00237         NewFile->RWOps            = Context->RWOps;
00238         NewFile->Dispersed        = GE_FALSE;
00239         NewFile->System           = Context->System;
00240         NewFile->Mask             = Context->Mask;
00241 
00242         // If we're a directory, make us a first class operator with the child
00243         if      (OpenModeFlags & GE_VFILE_OPEN_DIRECTORY)
00244         {
00245                 NewFile->Directory = FileEntry;
00246         }
00247         else
00248         {
00249                 if      (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00250                 {
00251                         NewFile->RWOpsStartPos = Context->System->DataLength +
00252                                                                          Context->System->RWOpsStartPos;
00253                 }
00254                 else
00255                 {
00256                         DirTree_GetFileOffset(FileEntry, &NewFile->RWOpsStartPos);
00257                 }
00258         }
00259 
00260         NewFile->OpenModeFlags = OpenModeFlags;
00261 
00262         if      (!(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY))
00263         {
00264                 if      (OpenModeFlags & GE_VFILE_OPEN_CREATE)
00265                 {
00266                         DirTree_SetFileOffset(FileEntry, NewFile->RWOpsStartPos);
00267                 }
00268                 else
00269                 {
00270                         assert(!(OpenModeFlags & GE_VFILE_OPEN_UPDATE));
00271                         DirTree_GetFileSize(FileEntry, &NewFile->Length);
00272                 }
00273         }
00274 
00275         // Only a VFS opened with OpenNewSystem gets to be the owner
00276         NewFile->IsSystem = GE_FALSE;
00277 
00278         return (void *)NewFile;
00279 }
00280 
00281 static  void *  GENESISCC FSVFS_OpenNewSystem(
00282         geVFile *               RWOps,
00283         const char *    Name,
00284         void *                  Context,
00285         unsigned int    OpenModeFlags)
00286 {
00287         VFSFile *       NewFS;
00288         long            RWOpsStartPos;
00289         char *TStr;
00290         char EString[256];
00291         char Mask;
00292 
00293         assert(RWOps != NULL);
00294         assert(Name == NULL);
00295         if(Context == NULL)
00296                 Mask = 0;
00297         else
00298         {
00299                 TStr = (char *)Context;
00300                 strncpy(EString, TStr, 8);
00301                 Mask = EString[0] & 0x01;
00302                 Mask |= EString[7] & 0x02;
00303                 Mask |= EString[1] & 0x04;
00304                 Mask |= EString[6] & 0x08;
00305                 Mask |= EString[2] & 0x10;
00306                 Mask |= EString[5] & 0x20;
00307                 Mask |= EString[3] & 0x40;
00308                 Mask |= EString[4] & 0x80;
00309 
00310                 //Mask = (EString[0]<<2) & 0xc0;
00311                 //Mask |= EString[1] & 0x30;
00312                 //Mask |= EString[2] & 0x0c;
00313                 //Mask |= EString[3] & 0x03;
00314         }
00315 
00316         // All VFS are directories
00317         if      (!(OpenModeFlags & GE_VFILE_OPEN_DIRECTORY))
00318                 return NULL;
00319 
00320         if      (geVFile_Tell(RWOps, &RWOpsStartPos) == GE_FALSE)
00321                 return NULL;
00322 
00323         if      (!(OpenModeFlags & GE_VFILE_OPEN_CREATE))
00324         {
00325                 VFSFileHeader   Header;
00326                 long                    DirectoryStartPos;
00327                 long                    DirectoryEndPos;
00328 
00329 //#pragma message  ("FSVFS_OpenNewSystem: READ/WRITE opens not supported")
00330 
00331                 if      (geVFile_Read(RWOps, &Header, sizeof(Header)) == GE_FALSE)
00332                         return NULL;
00333 
00334                 if      (!((Header.Signature == VFSFILEHEADER_SIGNATURE) || (Header.Signature == VCFSFILEHEADER_SIGNATURE)))
00335                         return NULL;
00336 
00337                 if      (Header.Version != HEADER_VERSION)
00338                         return NULL;
00339 
00340                 if      (Header.Dispersed == GE_TRUE)
00341                 {
00342                         assert(!"Not implemented");
00343                         return NULL;
00344                 }
00345 
00346                 // Go to the directory
00347                 if      (geVFile_Seek(RWOps, Header.DirectoryOffset, GE_VFILE_SEEKSET) == GE_FALSE)
00348                         return NULL;
00349 
00350                 // Remember where we started reading the directory
00351                 if      (geVFile_Tell(RWOps, &DirectoryStartPos) == GE_FALSE)
00352                         return NULL;
00353 
00354                 NewFS = geRam_Allocate(sizeof(*NewFS));
00355                 if      (!NewFS)
00356                         return NewFS;
00357                 memset(NewFS, 0, sizeof(*NewFS));
00358 
00359                 NewFS->RWOps = RWOps;
00360                 NewFS->RWOpsStartPos = RWOpsStartPos;
00361                 NewFS->DataLength = Header.DataLength;
00362                 NewFS->EndPosition = Header.EndPosition;
00363                 NewFS->Mask     = Mask;
00364 
00365                 // Read the directory
00366                 NewFS->Directory = DirTree_CreateFromFile(RWOps);
00367                 if      (!NewFS->Directory)
00368                 {
00369                         geRam_Free(NewFS);
00370                         return NULL;
00371                 }
00372 
00373                 // Get the end position for paranoia checking
00374                 if      (geVFile_Tell(RWOps, &DirectoryEndPos) == GE_FALSE)
00375                 {
00376                         DirTree_Destroy(NewFS->Directory);
00377                         geRam_Free(NewFS);
00378                         return NULL;
00379                 }
00380         }
00381         else
00382         {
00383                 NewFS = geRam_Allocate(sizeof(*NewFS));
00384                 if      (!NewFS)
00385                         return NewFS;
00386                 memset(NewFS, 0, sizeof(*NewFS));
00387 
00388                 NewFS->RWOps = RWOps;
00389                 NewFS->RWOpsStartPos = RWOpsStartPos;
00390                 NewFS->Directory = DirTree_Create();
00391                 NewFS->DataLength = sizeof(VFSFileHeader);
00392                 NewFS->Mask     = Mask;
00393         }
00394 
00395         NewFS->Signature         = VFSFILE_SIGNATURE;
00396         NewFS->IsSystem          = GE_TRUE;
00397         NewFS->System            = NewFS;
00398         NewFS->OpenModeFlags = OpenModeFlags;
00399 
00400         return NewFS;
00401 }
00402 
00403 static  geBoolean       GENESISCC FSVFS_UpdateContext(
00404         geVFile *               FS,
00405         void *                  Handle,
00406         void *                  Context,
00407         int                     ContextSize)
00408 {
00409         return GE_FALSE;
00410 }
00411 
00412 static  void    GENESISCC FSVFS_Close(void *Handle)
00413 {
00414         VFSFile *       File;
00415 
00416         File = Handle;
00417         
00418         CHECK_HANDLE(File);
00419 
00420         if      (File->Directory)
00421         {
00422                 if      (File->IsSystem == GE_TRUE)
00423                 {
00424                         // Hmmm.  We're the top level
00425                         assert(File == File->System);
00426 
00427                         if      (File->OpenModeFlags & (GE_VFILE_OPEN_CREATE | GE_VFILE_OPEN_UPDATE))
00428                         {
00429                                 VFSFileHeader   Header;
00430                                 long                    EndPosition;
00431 
00432                                 // Have to update the directory
00433                                 if      (geVFile_Seek(File->RWOps, File->RWOpsStartPos + File->DataLength, GE_VFILE_SEEKSET) == GE_FALSE)
00434                                 {
00435                                         // What to do on failure?
00436                                         assert(!"Can't fail");
00437                                 }
00438                                 if      (DirTree_WriteToFile(File->Directory, File->RWOps) == GE_FALSE)
00439                                 {
00440                                         // What to do on failure?
00441                                         assert(!"Can't fail");
00442                                 }
00443                                 geVFile_Tell(File->RWOps, &EndPosition);
00444                                 if      (geVFile_Seek(File->RWOps, File->RWOpsStartPos, GE_VFILE_SEEKSET) == GE_FALSE)
00445                                 {
00446                                         // What to do on failure?
00447                                         assert(!"Can't fail");
00448                                 }
00449                                 if(File->Mask==0)
00450                                         Header.Signature = VFSFILEHEADER_SIGNATURE;
00451                                 else
00452                                         Header.Signature = VCFSFILEHEADER_SIGNATURE;
00453                                 Header.Version = HEADER_VERSION;
00454                                 Header.Dispersed = GE_FALSE;
00455                                 Header.EndPosition = EndPosition;
00456 
00457                                 Header.DirectoryOffset = File->RWOpsStartPos + File->DataLength;
00458                                 Header.DataLength = File->DataLength;
00459                                 if      (geVFile_Write(File->RWOps, &Header, sizeof(Header)) == GE_FALSE)
00460                                 {
00461                                         // What to do on failure?
00462                                         assert(!"Can't fail");
00463                                 }
00464 
00465                                 // Make sure that we end up at the end of the RWOps file
00466                                 geVFile_Seek(File->RWOps, EndPosition, GE_VFILE_SEEKSET);
00467                         }
00468                         else
00469                         {
00470                                 // Have to make sure that we leave the file pointer at the end
00471                                 // of our data in the RWOps file that we come from.
00472 
00473                                 geVFile_Seek(File->RWOps, File->EndPosition, GE_VFILE_SEEKSET);
00474                         }
00475 
00476                         DirTree_Destroy(File->Directory);
00477                 }
00478         }
00479         else
00480         {
00481                 // Update the system with the length of this file.  Subsequent
00482                 // file operations will follow this file.
00483                 assert(File->System);
00484                 File->System->DataLength += File->Length;
00485                 DirTree_SetFileSize(File->DirEntry, File->Length);
00486         }
00487 
00488         geRam_Free(File);
00489 }
00490 
00491 static  geBoolean       GENESISCC ForceFilePos(VFSFile *File)
00492 {
00493         assert(File);
00494         assert(File->RWOps);
00495         assert(!File->Directory);
00496         
00497         assert(File->CurrentRelPos >= 0);
00498         assert(File->CurrentRelPos <= File->Length);
00499 
00500         return geVFile_Seek(File->RWOps,
00501                                           File->RWOpsStartPos + File->CurrentRelPos,
00502                                           GE_VFILE_SEEKSET);
00503 }
00504 
00505 static  int                     ClampOperationSize(const VFSFile *File, int Size)
00506 {
00507         assert(!File->Directory);
00508         assert(File->CurrentRelPos >= 0);
00509         return min(File->Length - File->CurrentRelPos, Size);
00510 }
00511 
00512 static  void            GENESISCC UpdateFilePos(VFSFile *File)
00513 {
00514         long    RWOpsPos;
00515 
00516         assert(!File->Directory);
00517         assert(File->CurrentRelPos >= 0);
00518 
00519         geVFile_Tell(File->RWOps, &RWOpsPos);
00520 
00521         File->CurrentRelPos = RWOpsPos - File->RWOpsStartPos;
00522         if      (File->CurrentRelPos > File->Length)
00523                 File->Length = File->CurrentRelPos;
00524 
00525         assert(File->CurrentRelPos >= 0);
00526 }
00527 
00528 static  geBoolean       GENESISCC FSVFS_GetS(void *Handle, void *Buff, int MaxLen)
00529 {
00530         VFSFile *       File;
00531         geBoolean       Res;
00532 
00533         assert(Buff);
00534         assert(MaxLen != 0);
00535 
00536         File = Handle;
00537 
00538         CHECK_HANDLE(File);
00539 
00540         if      (File->Directory)
00541                 return GE_FALSE;
00542 
00543         assert(File->CurrentRelPos >= 0);
00544         assert(File->CurrentRelPos <= File->Length);
00545 
00546         if      (!ForceFilePos(File))
00547                 return GE_FALSE;
00548 
00549         MaxLen = ClampOperationSize(File, MaxLen);
00550 
00551         Res = geVFile_GetS(File->RWOps, Buff, MaxLen);
00552 
00553         UpdateFilePos(File);
00554 
00555         return Res;
00556 }
00557 
00558 static  geBoolean       GENESISCC FSVFS_Read(void *Handle, void *Buff, int Count)
00559 {
00560         VFSFile *       File;
00561         geBoolean       Res;
00562         int i;
00563         char Bbyte;
00564         char *TBuffer;
00565 
00566 #ifndef NDEBUG
00567         int                     CurRelPos;
00568 #endif
00569 
00570         assert(Buff);
00571         assert(Count != 0);
00572 
00573         File = Handle;
00574 
00575         CHECK_HANDLE(File);
00576 
00577         if      (File->Directory)
00578                 return GE_FALSE;
00579 
00580         assert(File->CurrentRelPos >= 0);
00581         assert(File->CurrentRelPos <= File->Length);
00582 
00583         if      (!ForceFilePos(File))
00584                 return GE_FALSE;
00585 
00586         if      (ClampOperationSize(File, Count) != Count)
00587                 return GE_FALSE;
00588 
00589 #ifndef NDEBUG
00590         CurRelPos = File->CurrentRelPos;
00591 #endif
00592         Res = geVFile_Read(File->RWOps, Buff, Count);
00593         TBuffer = Buff;
00594         for(i=0;i<Count;i++)
00595         {
00596                 memcpy(&Bbyte, (TBuffer+i),1);
00597                 Bbyte ^=File->Mask;
00598                 memcpy((TBuffer+i),&Bbyte,1);
00599         }
00600 
00601         UpdateFilePos(File);
00602         assert(File->CurrentRelPos - CurRelPos == Count);
00603 
00604         return Res;
00605 }
00606 
00607 static  geBoolean       GENESISCC FSVFS_Write(void *Handle, const void *Buff, int Count)
00608 {
00609         VFSFile *       File;
00610         geBoolean       Res;
00611         int i;
00612         char Bbyte;
00613         char *TBuffer;
00614 
00615 #ifndef NDEBUG
00616         int                     CurRelPos;
00617 #endif
00618 
00619         assert(Buff);
00620         assert(Count != 0);
00621 
00622         File = Handle;
00623 
00624         CHECK_HANDLE(File);
00625 
00626         if      (File->Directory)
00627                 return GE_FALSE;
00628 
00629         if      (File->OpenModeFlags & GE_VFILE_OPEN_READONLY)
00630                 return GE_FALSE;
00631 
00632         assert(File->CurrentRelPos >= 0);
00633         assert(File->CurrentRelPos <= File->Length);
00634 
00635         if      (!ForceFilePos(File))
00636                 return GE_FALSE;
00637 
00638 #ifndef NDEBUG
00639         CurRelPos = File->CurrentRelPos;
00640 #endif
00641         TBuffer = (char *)Buff;
00642         for(i=0;i<Count;i++)
00643         {
00644                 memcpy(&Bbyte, (TBuffer+i),1);
00645                 Bbyte ^=File->Mask;
00646                 memcpy((TBuffer+i),&Bbyte,1);
00647         }
00648         Res = geVFile_Write(File->RWOps, Buff, Count);
00649 
00650         UpdateFilePos(File);
00651         assert(File->CurrentRelPos - CurRelPos == Count);
00652 
00653         return Res;
00654 }
00655 
00656 static  geBoolean       GENESISCC FSVFS_Seek(void *Handle, int Where, geVFile_Whence Whence)
00657 {
00658         VFSFile *       File;
00659         geBoolean       Res;
00660         long            AbsolutePos=0;
00661 
00662         File = Handle;
00663 
00664         CHECK_HANDLE(File);
00665 
00666         if      (File->Directory)
00667                 return GE_FALSE;
00668 
00669         assert(File->CurrentRelPos >= 0);
00670         assert(File->CurrentRelPos <= File->Length);
00671 
00672         switch  (Whence)
00673         {
00674         case    GE_VFILE_SEEKSET:
00675                 AbsolutePos = File->RWOpsStartPos + Where;
00676                 break;
00677 
00678         case    GE_VFILE_SEEKEND:
00679                 AbsolutePos = File->RWOpsStartPos + File->Length - Where;
00680                 break;
00681 
00682         case    GE_VFILE_SEEKCUR:
00683                 AbsolutePos = File->RWOpsStartPos + File->CurrentRelPos + Where;
00684                 break;
00685 
00686         default:
00687                 assert(!"Illegal seek case");
00688         }
00689 
00690         if      (AbsolutePos < File->RWOpsStartPos)
00691                 return GE_FALSE;
00692 
00693         Res = geVFile_Seek(File->RWOps, AbsolutePos, GE_VFILE_SEEKSET);
00694 
00695         UpdateFilePos(File);
00696 
00697         return Res;
00698 }
00699 
00700 static  geBoolean       GENESISCC FSVFS_EOF(const void *Handle)
00701 {
00702         const VFSFile * File;
00703 
00704         File = Handle;
00705 
00706         CHECK_HANDLE(File);
00707 
00708         if      (File->Directory)
00709                 return GE_FALSE;
00710 
00711         assert(File->CurrentRelPos >= 0);
00712         assert(File->CurrentRelPos <= File->Length);
00713 
00714         if      (File->CurrentRelPos == File->Length)
00715                 return GE_TRUE;
00716 
00717         return GE_FALSE;
00718 }
00719 
00720 static  geBoolean       GENESISCC FSVFS_Tell(const void *Handle, long *Position)
00721 {
00722         const VFSFile * File;
00723 
00724         File = Handle;
00725 
00726         CHECK_HANDLE(File);
00727 
00728         if      (File->Directory)
00729                 return GE_FALSE;
00730 
00731         assert(File->CurrentRelPos >= 0);
00732         assert(File->CurrentRelPos <= File->Length);
00733 
00734         *Position = File->CurrentRelPos;
00735 
00736         return GE_TRUE;
00737 }
00738 
00739 static  geBoolean       GENESISCC FSVFS_Size(const void *Handle, long *Size)
00740 {
00741         const VFSFile * File;
00742 
00743         File = Handle;
00744 
00745         CHECK_HANDLE(File);
00746 
00747         if      (File->Directory != NULL)
00748                 return GE_FALSE;
00749 
00750         assert(File->CurrentRelPos >= 0);
00751         assert(File->CurrentRelPos <= File->Length);
00752 
00753         *Size = File->Length;
00754 
00755         return GE_TRUE;
00756 }
00757 
00758 static  geBoolean       GENESISCC FSVFS_GetProperties(const void *Handle, geVFile_Properties *Properties)
00759 {
00760         const VFSFile * File;
00761 
00762         File = Handle;
00763 
00764         CHECK_HANDLE(File);
00765 
00766         assert(File->DirEntry);
00767 
00768         DirTree_GetFileTime(File->DirEntry, &Properties->Time);
00769         DirTree_GetFileAttributes(File->DirEntry, &Properties->AttributeFlags);
00770         DirTree_GetFileSize(File->DirEntry, &Properties->Size);
00771         DirTree_GetFileHints(File->DirEntry, &Properties->Hints);
00772         return DirTree_GetName(File->DirEntry, &Properties->Name[0], sizeof(Properties->Name));
00773 }
00774 
00775 static  geBoolean       GENESISCC FSVFS_SetSize(void *Handle, long Size)
00776 {
00777         assert(!"Not implemented");
00778         return GE_FALSE;
00779 }
00780 
00781 static  geBoolean       GENESISCC FSVFS_SetAttributes(void *Handle, geVFile_Attributes Attributes)
00782 {
00783         const VFSFile * File;
00784 
00785         File = Handle;
00786 
00787         CHECK_HANDLE(File);
00788 
00789         assert(File->DirEntry);
00790 
00791         if      (Attributes & ~GE_VFILE_ATTRIB_READONLY)
00792                 return GE_FALSE;
00793 
00794         DirTree_SetFileAttributes(File->DirEntry, Attributes);
00795 
00796         return GE_TRUE;
00797 }
00798 
00799 static  geBoolean       GENESISCC FSVFS_SetTime(void *Handle, const geVFile_Time *Time)
00800 {
00801         const VFSFile * File;
00802 
00803         File = Handle;
00804 
00805         CHECK_HANDLE(File);
00806 
00807         assert(File->DirEntry);
00808 
00809         DirTree_SetFileTime(File->DirEntry, Time);
00810 
00811         return GE_FALSE;
00812 }
00813 
00814 static  geBoolean       GENESISCC FSVFS_SetHints(void *Handle, const geVFile_Hints *Hints)
00815 {
00816         const VFSFile * File;
00817 
00818         File = Handle;
00819 
00820         CHECK_HANDLE(File);
00821 
00822         assert(File->DirEntry);
00823 
00824         return DirTree_SetFileHints(File->DirEntry, Hints);
00825 }
00826 
00827 static  geBoolean       GENESISCC FSVFS_FileExists(geVFile *FS, void *Handle, const char *Name)
00828 {
00829         VFSFile *       File;
00830 
00831         File = Handle;
00832 
00833         CHECK_HANDLE(File);
00834 
00835         if      (!File->Directory)
00836                 return GE_FALSE;
00837 
00838         return DirTree_FileExists(File->Directory, Name);
00839 }
00840 
00841 static  geBoolean       GENESISCC FSVFS_Disperse(
00842         geVFile *       FS,
00843         void *          Handle,
00844         const char *Directory,
00845         geBoolean       Recursive)
00846 {
00847 assert(!"Not implemented");
00848         return GE_FALSE;
00849 }
00850 
00851 static  geBoolean       GENESISCC FSVFS_DeleteFile(geVFile *FS, void *Handle, const char *Name)
00852 {
00853 assert(!"Not implemented");
00854         return GE_FALSE;
00855 }
00856 
00857 static  geBoolean       GENESISCC FSVFS_RenameFile(geVFile *FS, void *Handle, const char *Name, const char *NewName)
00858 {
00859 assert(!"Not implemented");
00860         return GE_FALSE;
00861 }
00862 
00863 static  geVFile_SystemAPIs      FSVFS_APIs =
00864 {
00865         FSVFS_FinderCreate,
00866         FSVFS_FinderGetNextFile,
00867         FSVFS_FinderGetProperties,
00868         FSVFS_FinderDestroy,
00869 
00870         FSVFS_OpenNewSystem,
00871         FSVFS_UpdateContext,
00872         FSVFS_Open,
00873         FSVFS_DeleteFile,
00874         FSVFS_RenameFile,
00875         FSVFS_FileExists,
00876         FSVFS_Disperse,
00877         FSVFS_Close,
00878 
00879         FSVFS_GetS,
00880         FSVFS_Read,
00881         FSVFS_Write,
00882         FSVFS_Seek,
00883         FSVFS_EOF,
00884         FSVFS_Tell,
00885         FSVFS_Size,
00886 
00887         FSVFS_GetProperties,
00888 
00889         FSVFS_SetSize,
00890         FSVFS_SetAttributes,
00891         FSVFS_SetTime,
00892         FSVFS_SetHints,
00893 };
00894 
00895 const geVFile_SystemAPIs * GENESISCC FSVFS_GetAPIs(void)
00896 {
00897         return &FSVFS_APIs;
00898 }
00899 

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