Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CAT/CATFileSystem_Win32.cpp Source File

CATFileSystem_Win32.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------
00002 /// \file CATFileSystem_Win32.cpp
00003 /// \brief File system functions for Win32 platform
00004 /// \ingroup CAT
00005 /// 
00006 /// Copyright (c) 2003-2008 by Michael Ellison.
00007 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00008 ///
00009 // $Author: mikeellison $
00010 // $Date: 2008-01-21 08:33:12 -0600 (Mon, 21 Jan 2008) $
00011 // $Revision:   $
00012 // $NoKeywords: $
00013 //---------------------------------------------------------------------------
00014 #include <memory.h>
00015 
00016 #include "CATFileSystem_Win32.h"
00017 #include "CATStreamFile.h"
00018 #include "CATStreamRAM.h"
00019 #include "CATPlatform.h"
00020 //---------------------------------------------------------------------------
00021 CATFileSystem_Win32::CATFileSystem_Win32(const CATString& basePath)
00022 :CATFileSystem(basePath)
00023 {
00024 
00025 }
00026 
00027 //---------------------------------------------------------------------------
00028 CATFileSystem_Win32::~CATFileSystem_Win32()
00029 {
00030 
00031 }
00032 
00033 //---------------------------------------------------------------------------
00034 // Initialize() must be called prior to using CATFileSystem!
00035 // \return CATResult - CAT_SUCCESS
00036 //
00037 // For CATFileSystem_Win32, we don't really use this right now.
00038 //---------------------------------------------------------------------------
00039 CATResult CATFileSystem_Win32::Initialize()
00040 {
00041    CATResult result = CAT_SUCCESS;
00042    fFSLock.Wait();
00043    
00044 
00045    fFSLock.Release();
00046    return result;
00047 }
00048 
00049 //---------------------------------------------------------------------------
00050 // FileExists should return a successful result if the file exists,
00051 // or an error otherwise.
00052 //
00053 // Note: FileExists() fails if a directory of that name is present.
00054 //
00055 // \param pathname - path to file to check for existance.
00056 // \return CATResult - successful result if the file is found.
00057 CATResult CATFileSystem_Win32::FileExists(  const CATString& pathname   )
00058 {
00059    CATString fullPath = BuildPath(fBasePath,pathname);
00060 
00061    DWORD attribs = ::GetFileAttributes(fullPath);
00062    if (INVALID_FILE_ATTRIBUTES == attribs)
00063    {
00064       return CATRESULTFILE(CAT_ERR_FILE_DOES_NOT_EXIST,pathname);
00065       
00066    }
00067 
00068    if (attribs & FILE_ATTRIBUTE_DIRECTORY)
00069    {
00070       return CATRESULTFILE(CAT_ERR_FILE_IS_DIRECTORY,pathname);
00071    }
00072 
00073    return CAT_SUCCESS;
00074 }
00075 
00076 //---------------------------------------------------------------------------
00077 // DirExists should return a successful result if the dir exists,
00078 // or an error otherwise.
00079 //
00080 // Note: DirExists() fails if a file of the specified name exists.
00081 //
00082 // \param pathname - path to dir to check for existance.
00083 // \return CATResult - successful result if the file is found.
00084 CATResult CATFileSystem_Win32::DirExists (  const CATString& pathname   )
00085 {
00086    CATString fullPath = BuildPath(fBasePath,pathname);
00087 
00088    DWORD attribs = ::GetFileAttributes(fullPath);
00089    if (INVALID_FILE_ATTRIBUTES == attribs)
00090    {
00091       return CATRESULTFILE(CAT_ERR_DIR_DOES_NOT_EXIST,fBasePath);
00092    }
00093 
00094    if (!(attribs & FILE_ATTRIBUTE_DIRECTORY))
00095    {
00096       return CATRESULTFILE(CAT_ERR_DIR_IS_FILE,fBasePath);
00097    }
00098 
00099    return CAT_SUCCESS;
00100 }
00101 
00102 
00103 /// CreateDir creates the directory if necessary.
00104 ///
00105 /// \param pathname - path to dir to check for existance and create if not
00106 ///                   present.
00107 /// \return CATResult - CAT_SUCCESS if successful.
00108 CATResult CATFileSystem_Win32::CreateDir(  const CATString& pathname   )
00109 {
00110    CATUInt32 offset = 0;
00111 
00112    if (pathname.IsEmpty())
00113    {
00114       return CATRESULT(CAT_ERR_NULL_PARAM);
00115    }
00116    
00117    while (offset < pathname.LengthCalc())
00118    {
00119       // Check for full path - return if it exists.
00120       if (CATSUCCEEDED(DirExists(pathname)))
00121          return CAT_SUCCESS;
00122 
00123       CATString curPath = pathname;
00124       
00125       if (pathname.Find(CAT_PATHSEPERATOR,offset))
00126       {
00127          CATString curPath = pathname.Left(offset);
00128          offset++;
00129       }
00130       else
00131       {
00132          offset = pathname.LengthCalc();
00133       }
00134 
00135         if (curPath.IsEmpty())
00136         {
00137            return CATRESULT(CAT_ERR_FILESYSTEM_CREATE_DIR);
00138         }
00139 #ifdef kDRIVESEPERATOR
00140       if ((curPath.GetWChar(curPath.LengthCalc() - 1) != kDRIVESEPERATOR) && 
00141           (CATFAILED(DirExists(curPath))))
00142 #else
00143       if (CATFAILED(DirExists(curPath)) )
00144 #endif
00145       {
00146          CATString fullPath = BuildPath(fBasePath,curPath);
00147          if (!::CreateDirectory(fullPath,0))
00148          {
00149             return CATRESULT(CAT_ERR_FILESYSTEM_CREATE_DIR);
00150          }
00151       }
00152    } 
00153 
00154    return DirExists(pathname);
00155 }
00156 
00157 //---------------------------------------------------------------------------
00158 // PathExists should return a successful result if a dir or a file
00159 // of that name exists.
00160 //
00161 // If it is a file, returns CAT_STAT_PATH_IS_FILE.
00162 // IF it is a dir, returns CAT_STAT_PATH_IS_DIRECTORY
00163 //
00164 // Note: DirExists() fails if a file of the specified name exists.
00165 //
00166 // \param pathname - path to dir to check for existance.
00167 // \return CATResult - successful result if the file is found.
00168 CATResult CATFileSystem_Win32::PathExists(  const CATString& pathname   )
00169 {
00170    CATString fullPath = BuildPath(fBasePath,pathname);
00171 
00172    DWORD attribs = ::GetFileAttributes(fullPath);
00173    if (INVALID_FILE_ATTRIBUTES == attribs)
00174    {
00175       return CATRESULTFILE(CAT_ERR_PATH_DOES_NOT_EXIST,fBasePath);
00176    }
00177    
00178    if (attribs & FILE_ATTRIBUTE_DIRECTORY)
00179       return CAT_STAT_PATH_IS_DIRECTORY;
00180    
00181    return CAT_STAT_PATH_IS_FILE;   
00182 }
00183 
00184 //---------------------------------------------------------------------------
00185 // FindFirst() finds the first matching file or directory and
00186 // returns it in firstFile.  
00187 //
00188 // FindFirst *must* be called prior to FindNext().  Only one
00189 // search at a time is allowed.
00190 // \param searchMAsk - mask for performing searches with
00191 // \param firstFile - ref to a string that receives the filename
00192 //                    on success.
00193 // \param findHandle - ref to handle returned on success. 
00194 // \result CATResult - if the file is a directory, returns
00195 // CAT_STAT_PATH_IS_DIRECTORY.  If the file is a normal
00196 // file, then CAT_STAT_PATH-IS-FILE is returned instead.
00197 CATResult CATFileSystem_Win32::FindFirst (  const CATString& searchPath, 
00198                                           CATString&       firstFile,
00199                                           CATFINDHANDLE&   findHandle)
00200                                          
00201 {
00202    fFSLock.Wait();
00203    CATString fullPath = BuildPath(fBasePath,searchPath);
00204 
00205    firstFile = "";
00206    findHandle = 0;
00207 
00208    WIN32_FIND_DATA findData;
00209    memset(&findData,0,sizeof(findData));
00210    findHandle = ::FindFirstFile(fullPath,&findData);
00211    
00212    if (INVALID_HANDLE_VALUE == findHandle)
00213    {
00214       findHandle = 0;
00215       fFSLock.Release();
00216       return CATRESULTDESC(CAT_ERR_FIND_NO_MATCHES, fullPath);
00217    }
00218 
00219    bool gotFile = true;
00220 
00221    CATString testFile = findData.cFileName;
00222    
00223    while ((gotFile) && ((testFile.Compare(".") == 0) || (testFile.Compare("..") == 0)))
00224    {      
00225       gotFile = ::FindNextFile(findHandle,&findData)?true:false;
00226       if (gotFile)
00227       {
00228          testFile = findData.cFileName;
00229       }
00230    }
00231 
00232    if (!gotFile)
00233    {
00234       ::FindClose(findHandle);
00235       findHandle = 0;
00236       fFSLock.Release();
00237       return CATRESULTDESC(CAT_ERR_FIND_NO_MATCHES,fullPath);
00238    }
00239 
00240    CATString searchDir;   
00241    CATString searchMask;
00242    
00243    fullPath = RemoveBasePath(fullPath);
00244    
00245    SplitPath( fullPath,searchDir,searchMask,true);
00246 
00247    CATResult result = CAT_SUCCESS;   
00248 
00249    CATString tmpDir = searchDir;
00250    fFindPaths.insert(std::make_pair<CATFINDHANDLE,CATString>(findHandle,tmpDir));
00251 
00252    firstFile = BuildPath(searchDir, findData.cFileName);
00253    
00254    fFSLock.Release();
00255 
00256    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00257       return CAT_STAT_PATH_IS_DIRECTORY;
00258 
00259    return CAT_STAT_PATH_IS_FILE;
00260 }      
00261 
00262 //---------------------------------------------------------------------------
00263 // FindNext() finds the next matching file or directory and
00264 // returns it in firstFile.  
00265 CATResult CATFileSystem_Win32::FindNext  (  CATString&       nextFile,
00266                                           CATFINDHANDLE   findHandle)
00267 {
00268    WIN32_FIND_DATA findData;
00269    memset(&findData,0,sizeof(findData));
00270 
00271    nextFile = "";
00272 
00273    if (findHandle == 0)
00274    {
00275       CATASSERT(false,"You must call find first before find next...");
00276       return CATRESULT(CAT_ERR_FIND_CALL_FINDFIRST);
00277    }
00278 
00279    // Bail if no more matches.
00280    if (! ::FindNextFile(findHandle, &findData))
00281    {
00282       return CATRESULT(CAT_ERR_FIND_END);
00283    }
00284 
00285    bool gotFile = true;
00286 
00287    CATString testFile = findData.cFileName;
00288    
00289    while ((gotFile) && ((testFile.Compare(".") == 0) || (testFile.Compare("..") == 0)))
00290    {      
00291       gotFile = ::FindNextFile(findHandle,&findData)?true:false;
00292       if (gotFile)
00293       {
00294          testFile = findData.cFileName;
00295       }
00296    }
00297 
00298    if (!gotFile)
00299    {
00300       return CATRESULT(CAT_ERR_FIND_END);
00301    }
00302 
00303    fFSLock.Wait();
00304 
00305    CATString searchDir;
00306    std::map<CATFINDHANDLE,CATString>::iterator iter =  fFindPaths.find(findHandle);
00307    if (iter == fFindPaths.end())
00308    {
00309       fFSLock.Release();
00310       return CATRESULT(CAT_ERR_FIND_CALL_FINDFIRST);
00311    }
00312    searchDir = iter->second;
00313 
00314    fFSLock.Release();
00315 
00316    nextFile = BuildPath(searchDir, findData.cFileName);
00317    
00318    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00319       return CAT_STAT_PATH_IS_DIRECTORY;
00320 
00321    return CAT_STAT_PATH_IS_FILE;
00322 }
00323 
00324 // FindEnd() ends a find operation and performs any necessary cleanup.
00325 //
00326 // The handle will be set to 0.
00327 //
00328 // \param findHandle - handle of find from FindFirst()
00329 // \return CATResult - CAT_SUCCESS on success.
00330 // \sa FindFirst(), FindNext()
00331 CATResult CATFileSystem_Win32::FindEnd (CATFINDHANDLE& findHandle)
00332 {
00333    fFSLock.Wait();
00334 
00335    if (findHandle != 0)
00336    {
00337       CATString path;
00338       std::map<CATFINDHANDLE,CATString>::iterator iter = fFindPaths.find(findHandle);
00339       if (iter == fFindPaths.end())
00340       {
00341           CATASSERT(false,"Find handle not found in path tree.");
00342       }
00343       else
00344       {
00345           fFindPaths.erase(iter);
00346       }
00347       ::FindClose(findHandle);
00348    }
00349    findHandle = 0;
00350 
00351    fFSLock.Release();
00352 
00353    return CAT_SUCCESS;
00354 }
00355 
00356 
00357 //---------------------------------------------------------------------------
00358 // OpenFile() opens or creates a file.
00359 //
00360 // \param filepath - path to file. 
00361 // \param mode - open mode for the file      
00362 // \param CATStream*& - ref to receive opened file stream
00363 // \return CATResult - CAT_SUCCESS on success.
00364 // \sa ReleaseStream()
00365 CATResult CATFileSystem_Win32::OpenFile( const CATString&      filename, 
00366                                        CATStream::OPEN_MODE  mode,
00367                                        CATStream*&           stream)
00368 {
00369    stream = 0;
00370    CATString fullPath = BuildPath(this->fBasePath,filename);
00371    
00372    try
00373    {
00374       stream = new CATStreamFile();
00375    }
00376    catch (...)
00377    {
00378       stream = 0;
00379    }
00380 
00381    if (stream == 0)
00382    {
00383       return CATRESULTFILE(CAT_ERR_OUT_OF_MEMORY,filename);
00384    }
00385 
00386    CATResult result = CAT_SUCCESS;
00387    if (CATFAILED(result = stream->Open(fullPath,mode)))
00388    {
00389       delete stream;
00390       stream = 0;
00391       return result;
00392    }
00393 
00394    return result;
00395 }
00396 
00397 //---------------------------------------------------------------------------
00398 // OpenCachedFile() opens a RAM stream filled with the contents
00399 // of the specified file. 
00400 //
00401 // \param filepath - path to file. 
00402 // \param CATStream*& - ref to receive opened file stream
00403 // \return CATResult - CAT_SUCCESS on success.
00404 // \sa ReleaseStream()
00405 CATResult CATFileSystem_Win32::OpenCachedFile( const CATString&      filename,                                        
00406                                        CATStream*&           stream)
00407 {
00408    stream = 0;
00409    try
00410    {
00411       stream = new CATStreamRAM();
00412    }
00413    catch (...)
00414    {
00415       stream = 0;
00416    }
00417 
00418    if (stream == 0)
00419    {
00420       return CATRESULT(CAT_ERR_OUT_OF_MEMORY);
00421    }
00422 
00423    return ((CATStreamRAM*)stream)->FromFile(filename);
00424 }
00425 
00426 //---------------------------------------------------------------------------
00427 // ReleaseFile() releases a stream opened with OpenFile().
00428 // 
00429 // \param CATStream*& - reference to stream pointer. Set to 0 when closed.
00430 // \return CATResult - CAT_SUCCESS on success.
00431 // \sa OpenFile()
00432 CATResult CATFileSystem_Win32::ReleaseFile(CATStream*& stream)
00433 {
00434    CATResult result = CAT_SUCCESS;
00435    if (stream == 0)
00436       return result;
00437 
00438    if (stream->IsOpen())
00439    {
00440       (void)stream->Close();
00441    }
00442 
00443    delete stream;
00444    stream = 0;
00445    
00446    return result;
00447 }
00448 
00449 
00450 /// IsFileReadOnly() returns true if the file is read-only, and false
00451 /// if not or if it doesn't exist.
00452 bool CATFileSystem_Win32::IsFileReadOnly(const CATString& path)
00453 {
00454     if (CATSUCCEEDED(this->FileExists(path)))
00455     {
00456         DWORD attribs = ::GetFileAttributes(path);
00457         return attribs & FILE_ATTRIBUTE_READONLY;
00458 
00459     }
00460     else
00461     {
00462         return false;
00463     }
00464 }

Generated on Mon Feb 11 04:09:43 2008 for Game Accessibility Suite by doxygen 1.5.4