pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_FilePath.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_FILEPATH_H
00040 #define PLONK_FILEPATH_H
00041 
00042 #include "plonk_FilesForwardDeclarations.h"
00043 
00044 class FilePathInternal : public SmartPointer
00045 {
00046 public:
00047     inline FilePathInternal() throw()
00048     {
00049         pl_Path_Init (&peer);
00050     }
00051     
00052     inline FilePathInternal (const char* path) throw()
00053     {
00054         if ((path[0] == '~') && (strlen (path) > 1))
00055             pl_Path_InitSystem (&peer, PLANKPATH_SYSTEMUSERHOME, (path[1] == '/') ? path + 2 : path + 1);
00056         else
00057             pl_Path_InitPath (&peer, path);
00058     }
00059 
00060     inline ~FilePathInternal()
00061     {
00062         pl_Path_DeInit (&peer);
00063     }
00064     
00065     friend class FilePath;
00066     
00067 private:
00068     PlankPath peer;
00069 };
00070 
00081 class FilePath : public SmartPointerContainer<FilePathInternal>
00082 {
00083 public:
00084     typedef SmartPointerContainer<FilePathInternal> Base;
00085     
00086     enum System
00087     {
00088         UserHome        = PLANKPATH_SYSTEMUSERHOME,
00089         UserDocuments   = PLANKPATH_SYSTEMUSERDOCUMENTS,
00090         UserDesktop     = PLANKPATH_SYSTEMUSERDESKTOP,
00091         UserAppData     = PLANKPATH_SYSTEMUSERAPPDATA,
00092         AppData         = PLANKPATH_SYSTEMAPPDATA,
00093         App             = PLANKPATH_SYSTEMAPP,
00094         Temp            = PLANKPATH_SYSTEMTEMP
00095     };
00096     
00097     inline FilePath() throw()
00098     :   Base (new FilePathInternal (""))
00099     {
00100     }
00101 
00102     inline FilePath (const char* path) throw()
00103     :   Base (new FilePathInternal (path))
00104     {
00105     }
00106     
00107     inline FilePath (Text const& path) throw()
00108     :   Base (new FilePathInternal (path.getArray()))
00109     {
00110     }
00111     
00112     inline static FilePath system (const System type) throw()
00113     {
00114         FilePath file (new FilePathInternal());
00115         pl_Path_InitSystem (&file.getInternal()->peer, type, 0);
00116         return file;
00117     }
00118         
00119     inline static FilePath temp() throw()
00120     {
00121         FilePath file (new FilePathInternal());
00122         pl_Path_InitTemp (&file.getInternal()->peer, 0, 0);
00123         return file;
00124     }
00125     
00126     inline static FilePath temp (Text const& prefix) throw()
00127     {
00128         FilePath file (new FilePathInternal());
00129         pl_Path_InitTemp (&file.getInternal()->peer, prefix.getArray(), 0);
00130         return file;
00131     }
00132     
00133     inline static FilePath temp (Text const& prefix, Text const& extension) throw()
00134     {
00135         FilePath file (new FilePathInternal());
00136         pl_Path_InitTemp (&file.getInternal()->peer, prefix.getArray(), extension.getArray());
00137         return file;
00138     }
00139     
00140     inline FilePath parent() const throw()
00141     {
00142         return parent (true);
00143     }
00144     
00145     inline FilePath child (FilePath const& relative) const throw()
00146     {
00147         return child (relative.fullpath(), true);
00148     }
00149 
00150     inline FilePath sibling (FilePath const& relative) const throw()
00151     {
00152         return sibling (relative.fullpath(), true);
00153     }
00154 
00155     inline FilePath parent (const bool shouldResolve) const throw()
00156     {
00157         FilePath file (new FilePathInternal());
00158         pl_Path_InitParent (&file.getInternal()->peer, &this->getInternal()->peer);
00159         return shouldResolve ? file.resolve() : file;
00160     }
00161     
00162     inline FilePath child (FilePath const& relative, const bool shouldResolve) const throw()
00163     {
00164         FilePath file (new FilePathInternal());
00165         pl_Path_InitChild (&file.getInternal()->peer, &this->getInternal()->peer, relative.fullpath());
00166         return shouldResolve ? file.resolve() : file;
00167     }
00168     
00169     inline FilePath sibling (FilePath const& relative, const bool shouldResolve) const throw()
00170     {
00171         FilePath file (new FilePathInternal());
00172         pl_Path_InitSibling (&file.getInternal()->peer, &this->getInternal()->peer, relative.fullpath());
00173         return shouldResolve ? file.resolve() : file;
00174     }
00175     
00176     inline Text fullpath() const throw()
00177     {
00178         return pl_Path_GetFullPath (&this->getInternal()->peer);
00179     }
00180     
00181     inline Text root() const throw()
00182     {
00183         return pl_Path_GetRoot (&this->getInternal()->peer);
00184     }
00185 
00186     inline Text filename() const throw()
00187     {
00188         return pl_Path_GetFilename (&this->getInternal()->peer);
00189     }
00190 
00191     inline Text extension() const throw()
00192     {
00193         return pl_Path_GetFileExtension (&this->getInternal()->peer);
00194     }
00195 
00196     inline Text filenameWithoutExtension() const throw()
00197     {
00198         Text filename = pl_Path_GetFilename (&this->getInternal()->peer);
00199         
00200         for (int i = filename.length(); --i >= 0;)
00201         {
00202             if (filename.atUnchecked (i) == '.')
00203             {
00204                 filename.put (i, '\0');
00205                 break;
00206             }
00207         }
00208         
00209         return filename;
00210     }
00211     
00212     inline FilePath withExtension (Text const& ext) const throw()
00213     {
00214         return (ext.first() == '.') ? FilePath (fullpath() + ext) : FilePath (fullpath() + Text (".") + ext);
00215     }
00216 
00217     inline bool isFile() const throw()
00218     {
00219         return pl_Path_IsFile (&this->getInternal()->peer);
00220     }
00221     
00222     inline bool isDirectory() const throw()
00223     {
00224         return pl_Path_IsDirectory (&this->getInternal()->peer);
00225     }
00226     
00227     inline operator Text () const throw()
00228     {
00229         return fullpath();
00230     }
00231     
00232     inline Text native() const throw()
00233     {
00234 #if PLONK_WIN
00235         return fullpath().replaceIgnoreCase ("/", "\\");
00236 #else
00237         return fullpath();
00238 #endif
00239     }
00240     
00241     inline FilePath& resolve() throw()
00242     {
00243         pl_Path_Resolve (&this->getInternal()->peer);
00244         return *this;
00245     }
00246     
00247     inline bool exists() const throw()
00248     {
00249         return pl_FileExists (fullpath(), isDirectory());
00250     }
00251 
00252     inline bool create() const throw()
00253     {
00254         if (isDirectory())
00255         {
00256             return pl_FileMakeDirectory (fullpath()) == PlankResult_OK;
00257         }
00258         else
00259         {
00260             Text parentPath = parent().fullpath();
00261             
00262             if (!pl_FileExists (parentPath.getArray(), true))
00263             {
00264                 bool success = pl_FileMakeDirectory (parentPath);
00265                 
00266                 if (!success)
00267                     return false;
00268             }
00269             
00270             PlankFile file;
00271             pl_File_Init (&file);
00272             PlankResult result = pl_File_OpenBinaryWrite (&file, fullpath(), false, false, false);
00273             
00274             if (result != PlankResult_OK)
00275                 return false;
00276             
00277             return pl_File_DeInit (&file) == PlankResult_OK;
00278         }
00279         
00280         return false;
00281     }
00282     
00283     inline bool createParent() const throw()
00284     {
00285         return parent().create();
00286     }
00287     
00288     inline bool erase() const throw()
00289     {
00290         return pl_FileErase (fullpath()) == PlankResult_OK;
00291     }
00292     
00293 private:
00294     FilePath (FilePathInternal* internal) throw()
00295     :   Base (internal)
00296     {
00297     }
00298 
00299 };
00300 
00301 #endif // PLONK_FILEPATH_H
 All Classes Functions Typedefs Enumerations Enumerator Properties