Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

FileProxy.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file FileProxy.d
00004         
00005         Copyright (C) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029 
00030         @version        Initial version, March 2004      
00031         @author         Kris, Brad Anderson, teqdruid
00032 
00033 
00034 *******************************************************************************/
00035 
00036 module mango.io.FileProxy;
00037 
00038 private import  mango.base.System;
00039 
00040 private import  mango.io.FilePath,
00041                 mango.io.FileStyle,
00042                 mango.io.Exception;
00043 
00044 private extern (C) int strlen (char *);
00045 
00046 /*******************************************************************************
00047 
00048         Models a generic file. Use this to manipulate files and directories
00049         in conjunction with FilePath, FileSystem and FileConduit. Doxygen
00050         has a hard time with D version() statements, so part of this class
00051         is documented in FileProxy::VersionWin32 instead.
00052         
00053 *******************************************************************************/
00054 
00055 class FileProxy
00056 {
00057         private FilePath path;
00058 
00059         /***********************************************************************
00060         
00061                 Construct a FileProxy from the provided FilePath
00062 
00063         ***********************************************************************/
00064                                   
00065         this (FilePath path)
00066         {
00067                 this.path = path;
00068         }
00069 
00070         /***********************************************************************
00071         
00072                 Construct a FileProxy from a text string
00073 
00074         ***********************************************************************/
00075 
00076         this (char[] path)
00077         {
00078                 this (new FilePath (path));
00079         }
00080 
00081         /***********************************************************************
00082         
00083                 Return the FilePath associated with this FileProxy
00084 
00085         ***********************************************************************/
00086 
00087         FilePath getPath ()
00088         {
00089                 return path;
00090         }               
00091 
00092         /***********************************************************************
00093         
00094                 Return the name of the associated path
00095 
00096         ***********************************************************************/
00097 
00098         char[] toString ()
00099         {
00100                 return path.toString();
00101         }               
00102 
00103         /***********************************************************************
00104         
00105                 Does this path currently exist?
00106 
00107         ***********************************************************************/
00108 
00109         bool isExisting ()               
00110         {
00111                 try {
00112                     getSize();
00113                     return true;
00114                     } catch (IOException){}
00115                 return false;
00116         }            
00117 
00118         /***********************************************************************
00119         
00120                 List the files contained within the associated path:
00121 
00122                 @code
00123                 FileProxy proxy = new FileProxy (".");
00124 
00125                 foreach (FilePath path; proxy.toList())
00126                          Stdout.put(path).cr();
00127                 @endcode
00128 
00129         ***********************************************************************/
00130 
00131         FilePath[] toList ()
00132         {
00133                 bool accept (FilePath fp) {return true;}
00134 
00135                 return toList (&accept);
00136         }              
00137 
00138         /***********************************************************************
00139 
00140         ***********************************************************************/
00141 
00142         version (Win32)
00143         {
00144                 private import std.c.windows.windows;
00145 
00146                 /***************************************************************
00147 
00148                         Throw an exception using the last known error
00149 
00150                 ***************************************************************/
00151 
00152                 private void exception ()
00153                 {
00154                         throw new IOException (path.toString ~ ": " ~ System.error);
00155                 }
00156 
00157                 /***************************************************************
00158 
00159                         Get info about this path
00160 
00161                 ***************************************************************/
00162 
00163                 private uint getInfo (void delegate (WIN32_FIND_DATA info) dg)
00164                 {
00165                         WIN32_FIND_DATA info;
00166 
00167                         HANDLE h = FindFirstFileA (path.toStringZ(), &info);
00168                         if (h == INVALID_HANDLE_VALUE)
00169                             exception ();
00170 
00171                         if (dg)
00172                             dg (info);
00173                         FindClose (h);
00174 
00175                         return info.dwFileAttributes;
00176                 }
00177 
00178                 /***************************************************************
00179                         
00180                         Return the file length (in bytes)
00181 
00182                 ***************************************************************/
00183 
00184                 long getSize ()
00185                 {
00186                         long _size;
00187 
00188                         void size (WIN32_FIND_DATA info)
00189                         {
00190                                 _size = (cast(ulong) info.nFileSizeHigh << 32) + 
00191                                                      info.nFileSizeLow;
00192                         }
00193 
00194                         getInfo (&size);
00195                         return _size;
00196                 }
00197 
00198                 /***************************************************************
00199 
00200                         Is this file writable?
00201 
00202                 ***************************************************************/
00203 
00204                 bool isWritable ()               
00205                 {
00206                         return (getInfo(null) & FILE_ATTRIBUTE_READONLY) == 0;
00207                 }            
00208 
00209                 /***************************************************************
00210 
00211                         Is this file really a directory?
00212 
00213                 ***************************************************************/
00214 
00215                 bool isDirectory ()               
00216                 {
00217                         return (getInfo(null) & FILE_ATTRIBUTE_DIRECTORY) != 0;
00218                 }            
00219 
00220                 /***************************************************************
00221 
00222                         Return the time when the file was last modified
00223 
00224                 ***************************************************************/
00225 
00226                 long getModifiedTime ()
00227                 {
00228                         long _time;
00229 
00230                         void time (WIN32_FIND_DATA info)
00231                         {
00232                                 _time = (cast(ulong) info.ftLastWriteTime.dwHighDateTime << 32) + 
00233                                                      info.ftLastWriteTime.dwLowDateTime;
00234                         }
00235 
00236                         getInfo (&time);
00237                         return _time;
00238                 }               
00239 
00240                 /***************************************************************
00241 
00242                         Remove the file/directory from the file-system
00243 
00244                 ***************************************************************/
00245 
00246                 void remove ()
00247                 {
00248                         if (isDirectory ())
00249                            {
00250                            if (! RemoveDirectoryA (path.toStringZ()))
00251                                  exception();
00252                            }
00253                         else
00254                            {
00255                            if (! DeleteFileA (path.toStringZ()))
00256                                  exception();
00257                            }
00258                 }           
00259 
00260                 /***************************************************************
00261 
00262                         Create a new file 
00263 
00264                 ***************************************************************/
00265 
00266                 FileProxy createFile ()
00267                 {
00268                         HANDLE h;
00269 
00270                         h = CreateFileA (path.toStringZ(), GENERIC_WRITE, 0, null, 
00271                                          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
00272 
00273                         if (h == INVALID_HANDLE_VALUE)
00274                             exception();
00275 
00276                         if (! CloseHandle (h))
00277                               exception();
00278 
00279                         return this;
00280                 }
00281 
00282                 /***************************************************************
00283 
00284                         Create a new directory
00285 
00286                 ***************************************************************/
00287 
00288                 FileProxy createDirectory ()
00289                 {
00290                         if (! CreateDirectoryA (path.toStringZ(), null))
00291                               exception();
00292 
00293                         return this;
00294                 }
00295 
00296                 /***************************************************************
00297                         
00298                         List the set of children within this directory. See
00299                         toList() above.
00300 
00301                 ***************************************************************/
00302 
00303                 FilePath[] toList (bool delegate(FilePath fp) filter)
00304                 {
00305                         int             i;
00306                         char[]          c;
00307                         HANDLE          h;
00308                         FilePath[]      list;
00309                         WIN32_FIND_DATA fileinfo;
00310 
00311                         list = new FilePath[50];
00312 
00313                         c = path.toString() ~ "\\*\0";
00314                         h = FindFirstFileA (c, &fileinfo);
00315 
00316                         if (h != INVALID_HANDLE_VALUE)
00317                             try {
00318                                 do {
00319                                    int len = strlen (fileinfo.cFileName);
00320 
00321                                    // make a copy of the file name for listing
00322                                    FilePath fp = new FilePath (fileinfo.cFileName [0 .. len].dup);
00323 
00324                                    if (i >= list.length)
00325                                       list.length = list.length * 2;
00326 
00327                                    if (filter (fp))
00328                                       {
00329                                       list[i] = fp;
00330                                       ++i;
00331                                       }
00332                                    } while (FindNextFileA (h, &fileinfo));
00333                                 } finally {
00334                                           FindClose (h);
00335                                           }
00336                         list.length = i;
00337                         return list;
00338                 }
00339         }
00340 
00341         /***********************************************************************
00342 
00343         ***********************************************************************/
00344 
00345         version (linux)
00346         {
00347                 private import std.c.linux.linux;
00348 
00349                 /***************************************************************
00350 
00351                         Throw an exception using the last known error
00352 
00353                 ***************************************************************/
00354 
00355                 private void exception ()
00356                 {
00357                         throw new IOException (path.toString ~ ": " ~ System.error);
00358                 }
00359 
00360                 /***************************************************************
00361 
00362                         Get info about this path
00363 
00364                 ***************************************************************/
00365 
00366                 private uint getInfo (void delegate (struct_stat info) dg)
00367                 {
00368                         struct_stat stats;
00369 
00370                         if (std.c.linux.linux.stat (path.toStringZ(), &stats))
00371                             exception();
00372 
00373                         if (dg)
00374                             dg (stats);
00375 
00376                         return stats.st_mode;
00377                 }               
00378 
00379                 /***************************************************************
00380 
00381                         Return the file length (in bytes)
00382 
00383                 ***************************************************************/
00384 
00385                 long getSize ()
00386                 {
00387                         long _size;
00388 
00389                         void size (struct_stat info)
00390                         {
00391                                 _size = cast(ulong) info.st_size;    // 32 bits only
00392                         }
00393 
00394                         getInfo (&size);
00395                         return _size;
00396                 }
00397 
00398                 /***************************************************************
00399 
00400                         Is this file writable?
00401 
00402                 ***************************************************************/
00403 
00404                 bool isWritable ()               
00405                 {
00406                         return (getInfo(null) & O_RDONLY) == 0;
00407                 }            
00408 
00409                 /***************************************************************
00410 
00411                         Is this file really a directory?
00412 
00413                 ***************************************************************/
00414 
00415                 bool isDirectory ()               
00416                 {
00417                         return (getInfo(null) & S_IFDIR) != 0;
00418                 }            
00419 
00420                 /***************************************************************
00421 
00422                         Return the time when the file was last modified
00423 
00424                 ***************************************************************/
00425 
00426                 long getModifiedTime ()
00427                 {
00428                         long _time;
00429 
00430                         void time (struct_stat info)
00431                         {
00432                                _time = cast(ulong) info.st_mtime; // seconds since 1/1/1970
00433                         }
00434 
00435                         getInfo (&time);
00436                         return _time;
00437                 }               
00438 
00439                 /***************************************************************
00440 
00441                         Remove the file/directory from the file-system
00442 
00443                 ***************************************************************/
00444 
00445                 void remove ()
00446                 {
00447                         if (isDirectory())
00448                            {
00449                            if (std.c.linux.linux.rmdir (path.toStringZ()))
00450                                exception ();
00451                            }
00452                         else           
00453                            if (std.c.stdio.remove (path.toStringZ()) == -1)
00454                                exception ();
00455                 }              
00456 
00457                 /***************************************************************
00458 
00459                         Create a new file 
00460 
00461                 ***************************************************************/
00462 
00463                 FileProxy createFile ()
00464                 {
00465                         int fd;
00466 
00467                         fd = std.c.linux.linux.open (path.toStringZ(), O_CREAT | O_WRONLY | O_TRUNC, 0660);
00468                         if (fd == -1)
00469                             exception();
00470 
00471                         if (std.c.linux.linux.close(fd) == -1)
00472                             exception();
00473 
00474                         return this;
00475                 }              
00476 
00477                 /***************************************************************
00478 
00479                         Create a new directory
00480 
00481                 ***************************************************************/
00482 
00483                 FileProxy createDirectory ()
00484                 {
00485                         if (std.c.linux.linux.mkdir (path.toStringZ(), 0777))
00486                             exception();
00487 
00488                         return this;
00489                 }
00490 
00491                 /***************************************************************
00492                 
00493                         List the set of children within this directory. See
00494                         toList() above.
00495 
00496                 ***************************************************************/
00497 
00498                 FilePath[] toList (bool delegate(FilePath fp) filter)
00499                 {
00500                         int             i;
00501                         DIR*            dir;
00502                         dirent*         entry;
00503                         FilePath[]      list;
00504 
00505                         dir = opendir (path.toStringZ());
00506                         if (! dir) 
00507                               exception();
00508 
00509                         list = new FilePath [50];
00510                         while (entry = readdir(dir)) 
00511                               {
00512                               int len = strlen (entry.d_name);
00513 
00514                               // make a copy of the file name for listing
00515                               fp = new FilePath (entry.d_name[0 ..len].dup);
00516 
00517                               if (i >= list.length)
00518                                   list.length = list.length * 2;
00519 
00520                               if (filter (fp))
00521                                  {
00522                                  list[i] = fp;
00523                                  ++i;
00524                                  }
00525                               }  
00526 
00527                         list.length = i;
00528                         closedir (dir);
00529                         return list;
00530                 }
00531 
00532         }
00533 }

Generated on Sun Oct 24 22:31:14 2004 for Mango by doxygen 1.3.6