00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #if defined(_WIN32) || defined(_WIN64)
00018 #include <spl/configwin32.h>
00019 #include <spl/cleanwindows.h>
00020 #else
00021 #include <spl/autoconf/config.h>
00022 #endif
00023
00024 #ifdef HAVE_SYS_TYPES_H
00025 #include <sys/types.h>
00026 #endif
00027
00028 #include <spl/Environment.h>
00029 #include <spl/io/Directory.h>
00030 #include <spl/io/File.h>
00031 #include <spl/io/WinPerm.h>
00032
00033 #include <stdio.h>
00034
00035 #ifdef HAVE_FCNTL_H
00036 #include <fcntl.h>
00037 #endif
00038 #ifdef HAVE_SYS_TYPES_H
00039 #include <sys/types.h>
00040 #endif
00041 #ifdef HAVE_IO_H
00042 #include <io.h>
00043 #endif
00044 #ifdef HAVE_DIRECT_H
00045 #include <direct.h>
00046 #endif
00047 #ifdef HAVE_DIRENT_H
00048 #include <dirent.h>
00049 #endif
00050 #ifdef HAVE_SYS_STAT_H
00051 #include <sys/stat.h>
00052 #endif
00053 #ifdef HAVE_UNISTD_H
00054 #include <unistd.h>
00055 #endif
00056 #ifdef HAVE_SYS_STAT_H
00057 #include <sys/stat.h>
00058 #endif
00059
00060 #ifdef WIN32
00061 char Directory::m_seperator = '\\';
00062 #include <spl/cleanwindows.h>
00063 #else
00064 char Directory::m_seperator = '/';
00065 #endif
00066
00067 #ifdef WIN32
00068 extern bool EncodePermissions(const Permissions& perm, _WinPerms &wperm);
00069 #else
00070 extern void EncodePermissions(const Permissions& perm, mode_t& mode);
00071 #endif
00072
00073 Vector<StringPtr> Directory::ListFiles(const String& directory, const String& filter)
00074 {
00075 Vector<StringPtr> list;
00076
00077 #ifdef WIN32
00078 struct _finddata_t c_file;
00079
00080 #if _MSC_VER >= 1400
00081 intptr_t hFile;
00082 #else
00083 long hFile;
00084 #endif
00085
00086 char odir[512];
00087
00088 _getcwd(odir, 512);
00089
00090 if ( 0 != _chdir(directory.GetChars()) )
00091 {
00092 return list;
00093 }
00094
00095
00096 if( (hFile = _findfirst( filter.GetChars(), &c_file )) == -1L )
00097 {
00098 return list;
00099 }
00100
00101 list.Add( StringPtr(new String(c_file.name)) );
00102 while( _findnext( hFile, &c_file ) == 0 )
00103 {
00104 list.Add( StringPtr(new String(c_file.name)) );
00105 }
00106 _findclose( hFile );
00107
00108 if (0 != _chdir(odir))
00109 {
00110 throw new IOException("Cannot change directory to " + String(odir));
00111 }
00112
00113 #else
00114
00115 DIR *dp;
00116 struct dirent *ep;
00117
00118 dp = opendir (directory.GetChars());
00119 if (dp != NULL)
00120 {
00121 while (ep = readdir (dp))
00122 {
00123 list.Add( StringPtr(new String(ep->d_name)) );
00124 }
00125 closedir (dp);
00126 }
00127
00128 #endif
00129 return list;
00130 }
00131
00132 void Directory::ChangeWorkingDirectory(const String& directory)
00133 {
00134 #ifdef WIN32
00135 if ( 0 != _chdir(directory.GetChars()) )
00136 {
00137 throw new InvalidArgumentException(Environment::LastErrorMessage());
00138 }
00139 #else
00140 if ( 0 != chdir(directory.GetChars()) )
00141 {
00142 throw new InvalidArgumentException(Environment::LastErrorMessage());
00143 }
00144 #endif
00145 }
00146
00147 StringPtr Directory::GetWorkingDirectory()
00148 {
00149 char workingDir[512];
00150
00151 #ifdef _WINDOWS
00152 return StringPtr(new String(_getcwd(workingDir, 512)));
00153 #else
00154 return StringPtr(new String(getcwd(workingDir, 512)));
00155 #endif
00156 }
00157
00158 Directory::Directory(const String& directory)
00159 : m_raw(directory), m_parts()
00160 {
00161 char sep[2];
00162 sep[0] = m_seperator;
00163 sep[1] = '\0';
00164 m_parts = m_raw.Split(sep);
00165 if (m_parts->Count() > 0)
00166 {
00167 StringPtr fileName = m_parts->ElementAt(m_parts->Count() - 1);
00168 if (fileName->Length() == 0 || File::Exists(fileName))
00169 {
00170 m_parts->RemoveAt(m_parts->Count() - 1);
00171 }
00172 }
00173 }
00174
00175 Directory::~Directory()
00176 {
00177 }
00178
00179 Directory::Directory( const Directory& dir )
00180 : m_raw(), m_parts()
00181 {
00182 *this = dir;
00183 }
00184
00185 Directory& Directory::operator =(const Directory& dir)
00186 {
00187 m_parts->Clear();
00188
00189 char sep[2];
00190 sep[0] = m_seperator;
00191 sep[1] = '\0';
00192 m_raw = dir.m_raw;
00193 m_parts = dir.m_parts;
00194
00195 return *this;
00196 }
00197
00198 Directory Directory::Parent() const
00199 {
00200 StringBuffer buf(m_raw.Length());
00201 for (int x = 0; x < m_parts->Count() - 1; x++)
00202 {
00203 buf.Append(m_parts->ElementAt(x));
00204 buf.Append(Directory::SeperatorChar());
00205 }
00206
00207 return Directory(buf.ToString());
00208 }
00209
00210 int32 Directory::HashCode() const
00211 {
00212 return m_raw.HashCode();
00213 }
00214
00215 bool Directory::Equals( const IComparable& a ) const
00216 {
00217 if (a.MajicNumber() != MajicNumber())
00218 {
00219 return false;
00220 }
00221 const Directory& dir = static_cast<const Directory &>(a);
00222 return m_raw.Equals( dir.m_raw );
00223 }
00224
00225 int Directory::Compare( const IComparable& a ) const
00226 {
00227 if (a.MajicNumber() != MajicNumber())
00228 {
00229 return 1;
00230 }
00231 const Directory& dir = static_cast<const Directory &>(a);
00232 return m_raw.Compare( dir.m_raw );
00233 }
00234
00235 int32 Directory::MajicNumber() const
00236 {
00237 return 0x00F1;
00238 }
00239
00240 StringPtr Directory::RemoveTrailingSeperator(const String& path)
00241 {
00242 if (path.CharAt(path.Length() - 1) == m_seperator)
00243 {
00244 return path.Substring(0, path.Length() - 1);
00245 }
00246 return StringPtr(new String(path));
00247 }
00248
00249 StringPtr Directory::ToString() const
00250 {
00251 StringBuffer buf(m_raw.Length());
00252
00253 for (int x = 0; x < m_parts->Count(); x++)
00254 {
00255 buf.Append(m_parts->ElementAt(x));
00256 buf.Append(Directory::SeperatorChar());
00257 }
00258
00259 return buf.ToString();
00260 }
00261
00262 bool Directory::IsDirectory(const String &path)
00263 {
00264 #ifdef _WINDOWS
00265
00266 struct _stat stbuf;
00267
00268 if (_stat(RemoveTrailingSeperator(path)->GetChars(), &stbuf) != 0)
00269 {
00270 return false;
00271 }
00272
00273 return (stbuf.st_mode & _S_IFDIR) != 0;
00274
00275 #else
00276
00277 struct stat stbuf;
00278
00279 if(stat(path.GetChars(), &stbuf) != 0)
00280 {
00281 return false;
00282 }
00283 return S_ISDIR(stbuf.st_mode);
00284
00285 #endif
00286 }
00287
00288 void Directory::Delete(const String& path)
00289 {
00290 #ifdef WIN32
00291
00292 if(::RemoveDirectory(RemoveTrailingSeperator(path)->GetChars()) != TRUE)
00293 {
00294 throw new IOException(Environment::LastErrorMessage());
00295 }
00296
00297 #else
00298
00299 if(::rmdir(path.GetChars()) != 0)
00300 {
00301 throw new IOException(Environment::LastErrorMessage());
00302 }
00303
00304 #endif
00305 }
00306
00307 void Directory::Rename(const String& oldname, const String& newname)
00308 {
00309 if (rename(oldname.GetChars(), newname.GetChars()) != 0)
00310 {
00311 throw new IOException(Environment::LastErrorMessage());
00312 }
00313 }
00314
00315 void Directory::Create(const String& path, const Permissions& perm)
00316 {
00317 if(path.Length() < 1)
00318 {
00319 throw new InvalidArgumentException("Path is required");
00320 }
00321
00322 #ifdef _WINDOWS
00323
00324 SECURITY_ATTRIBUTES sa;
00325 _WinPerms wperm;
00326
00327 EncodePermissions(perm, wperm);
00328
00329 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
00330 sa.lpSecurityDescriptor = wperm.pdesc;
00331 sa.bInheritHandle = FALSE;
00332
00333 if (::CreateDirectory(RemoveTrailingSeperator(path)->GetChars(), &sa) != TRUE)
00334 {
00335 throw new IOException(Environment::LastErrorMessage());
00336 }
00337
00338 #else
00339
00340 mode_t mode;
00341 EncodePermissions(perm, mode);
00342
00343 if(::mkdir(path.GetChars(), mode) != 0)
00344 {
00345 throw new IOException(Environment::LastErrorMessage());
00346 }
00347
00348 #endif
00349 }
00350
00351 #ifdef DEBUG
00352 void Directory::ValidateMem() const
00353 {
00354 m_raw.ValidateMem();
00355 m_parts.ValidateMem();
00356 }
00357
00358 void Directory::CheckMem() const
00359 {
00360 m_raw.ValidateMem();
00361 m_parts.CheckMem();
00362 }
00363 #endif