PLplot
5.10.0
|
00001 // 00002 // dirent.h - dirent API for Microsoft Visual Studio 00003 // 00004 // Copyright (C) 2006 Toni Ronkko 00005 // 00006 // Permission is hereby granted, free of charge, to any person obtaining 00007 // a copy of this software and associated documentation files (the 00008 // ``Software''), to deal in the Software without restriction, including 00009 // without limitation the rights to use, copy, modify, merge, publish, 00010 // distribute, sublicense, and/or sell copies of the Software, and to 00011 // permit persons to whom the Software is furnished to do so, subject to 00012 // the following conditions: 00013 // 00014 // The above copyright notice and this permission notice shall be included 00015 // in all copies or substantial portions of the Software. 00016 // 00017 // THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00019 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00020 // IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR 00021 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00022 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00023 // OTHER DEALINGS IN THE SOFTWARE. 00024 // 00025 // 00026 // Jan 18, 2008, Toni Ronkko 00027 // Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string 00028 // between multi-byte and unicode representations. This makes the 00029 // code simpler and also allows the code to be compiled under MingW. Thanks 00030 // to Azriel Fasten for the suggestion. 00031 // 00032 // Mar 4, 2007, Toni Ronkko 00033 // Bug fix: due to the strncpy_s() function this file only compiled in 00034 // Visual Studio 2005. Using the new string functions only when the 00035 // compiler version allows. 00036 // 00037 // Nov 2, 2006, Toni Ronkko 00038 // Major update: removed support for Watcom C, MS-DOS and Turbo C to 00039 // simplify the file, updated the code to compile cleanly on Visual 00040 // Studio 2005 with both unicode and multi-byte character strings, 00041 // removed rewinddir() as it had a bug. 00042 // 00043 // Aug 20, 2006, Toni Ronkko 00044 // Removed all remarks about MSVC 1.0, which is antiqued now. Simplified 00045 // comments by removing SGML tags. 00046 // 00047 // May 14 2002, Toni Ronkko 00048 // Embedded the function definitions directly to the header so that no 00049 // source modules need to be included in the Visual Studio project. Removed 00050 // all the dependencies to other projects so that this very header can be 00051 // used independently. 00052 // 00053 // May 28 1998, Toni Ronkko 00054 // First version. 00055 // 00056 #ifndef DIRENT_H 00057 #define DIRENT_H 00058 00059 #include <windows.h> 00060 #include <string.h> 00061 #include <assert.h> 00062 00063 00064 typedef struct dirent 00065 { 00066 // name of current directory entry (a multi-byte character string) 00067 char d_name[MAX_PATH + 1]; 00068 00069 // file attributes 00070 WIN32_FIND_DATAA data; 00071 } dirent; 00072 00073 00074 typedef struct DIR 00075 { 00076 // current directory entry 00077 dirent current; 00078 00079 // is there an un-processed entry in current? 00080 int cached; 00081 00082 // file search handle 00083 HANDLE search_handle; 00084 00085 // search pattern (3 = zero terminator + pattern "\\*") 00086 char patt[MAX_PATH + 3]; 00087 } DIR; 00088 00089 00090 static DIR *opendir( const char *dirname ); 00091 static struct dirent *readdir( DIR *dirp ); 00092 static int closedir( DIR *dirp ); 00093 00094 00095 // use the new safe string functions introduced in Visual Studio 2005 00096 #if defined ( _MSC_VER ) && _MSC_VER >= 1400 00097 # define STRNCPY( dest, src, size ) strncpy_s( ( dest ), ( size ), ( src ), _TRUNCATE ) 00098 #else 00099 # define STRNCPY( dest, src, size ) strncpy( ( dest ), ( src ), ( size ) ) 00100 #endif 00101 00102 00103 // 00104 // Open directory stream DIRNAME for read and return a pointer to the 00105 // internal working area that is used to retrieve individual directory 00106 // entries. 00107 // 00108 static DIR* 00109 opendir( 00110 const char *dirname ) 00111 { 00112 DIR *dirp; 00113 assert( dirname != NULL ); 00114 assert( strlen( dirname ) < MAX_PATH ); 00115 00116 // construct new DIR structure 00117 dirp = (DIR *) malloc( sizeof ( struct DIR ) ); 00118 if ( dirp != NULL ) 00119 { 00120 char *p; 00121 00122 // take directory name... 00123 STRNCPY( dirp->patt, dirname, sizeof ( dirp->patt ) ); 00124 dirp->patt[MAX_PATH] = '\0'; 00125 00126 // ... and append search pattern to it 00127 p = strchr( dirp->patt, '\0' ); 00128 if ( dirp->patt < p && *( p - 1 ) != '\\' && *( p - 1 ) != ':' ) 00129 { 00130 *p++ = '\\'; 00131 } 00132 *p++ = '*'; 00133 *p = '\0'; 00134 00135 // open stream and retrieve first file 00136 dirp->search_handle = FindFirstFileA( dirp->patt, &dirp->current.data ); 00137 if ( dirp->search_handle == INVALID_HANDLE_VALUE ) 00138 { 00139 // invalid search pattern? 00140 free( dirp ); 00141 return NULL; 00142 } 00143 00144 // there is an un-processed directory entry in memory now 00145 dirp->cached = 1; 00146 } 00147 return dirp; 00148 } 00149 00150 00151 // 00152 // Read a directory entry, and return a pointer to a dirent structure 00153 // containing the name of the entry in d_name field. Individual directory 00154 // entries returned by this very function include regular files, 00155 // sub-directories, pseudo-directories "." and "..", but also volume labels, 00156 // hidden files and system files may be returned. 00157 // 00158 static struct dirent * 00159 readdir( 00160 DIR *dirp ) 00161 { 00162 assert( dirp != NULL ); 00163 00164 if ( dirp->search_handle == INVALID_HANDLE_VALUE ) 00165 { 00166 // directory stream was opened/rewound incorrectly or it ended normally 00167 return NULL; 00168 } 00169 00170 // get next directory entry 00171 if ( dirp->cached != 0 ) 00172 { 00173 // a valid directory entry already in memory 00174 dirp->cached = 0; 00175 } 00176 else 00177 { 00178 // read next directory entry from disk 00179 if ( FindNextFileA( dirp->search_handle, &dirp->current.data ) == FALSE ) 00180 { 00181 // the very last file has been processed or an error occured 00182 FindClose( dirp->search_handle ); 00183 dirp->search_handle = INVALID_HANDLE_VALUE; 00184 return NULL; 00185 } 00186 } 00187 00188 // copy as a multibyte character string 00189 STRNCPY( dirp->current.d_name, dirp->current.data.cFileName, sizeof ( dirp->current.d_name ) ); 00190 dirp->current.d_name[MAX_PATH] = '\0'; 00191 00192 return &dirp->current; 00193 } 00194 00195 00196 // 00197 // Close directory stream opened by opendir() function. Close of the 00198 // directory stream invalidates the DIR structure as well as any previously 00199 // read directory entry. 00200 // 00201 static int 00202 closedir( 00203 DIR *dirp ) 00204 { 00205 assert( dirp != NULL ); 00206 00207 // release search handle 00208 if ( dirp->search_handle != INVALID_HANDLE_VALUE ) 00209 { 00210 FindClose( dirp->search_handle ); 00211 dirp->search_handle = INVALID_HANDLE_VALUE; 00212 } 00213 00214 // release directory handle 00215 free( dirp ); 00216 return 0; 00217 } 00218 00219 00220 #endif //DIRENT_H