filesystem.cpp
Go to the documentation of this file.00001
00014 #include <dlrPortability/filesystem.h>
00015
00016
00017
00018 #include <algorithm>
00019 #include <sstream>
00020 #include <sys/stat.h>
00021 #include <sys/types.h>
00022 #include <dlrCommon/exception.h>
00023 #include <dlrCommon/functional.h>
00024
00025
00026
00027 #ifdef _WIN32
00028
00029
00030
00031 #include <io.h>
00032 #include <windows.h>
00033
00034
00035
00036 #else
00037
00038
00039
00040 #include <dirent.h>
00041 #include <errno.h>
00042 #include <unistd.h>
00043
00044
00045
00046 #endif
00047
00048
00049
00050
00051 namespace dlr {
00052
00053 namespace portability {
00054
00055
00056
00057
00058 bool
00059 isDirectory(const std::string& path)
00060 {
00061 struct stat statBuf;
00062 memset(&statBuf, 0, sizeof(statBuf));
00063 int returnValue = stat(path.c_str(), &statBuf);
00064 if(returnValue == 0) {
00065
00066 if((statBuf.st_mode & S_IFMT) == S_IFDIR) {
00067 return true;
00068 }
00069 }
00070 return false;
00071 }
00072
00073
00074
00075 std::string
00076 joinPath(const std::string& part0, const std::string& part1)
00077 {
00078 if(part0.empty()) {
00079 return part1;
00080 }
00081 if(part1.empty()) {
00082 return part0;
00083 }
00084 if(part0.size() >= pathDelimiter().size()) {
00085 if(part0.compare(
00086 part0.size() - pathDelimiter().size(), std::string::npos,
00087 pathDelimiter()) == 0) {
00088 return part0 + part1;
00089 }
00090 }
00091 return part0 + pathDelimiter() + part1;
00092 }
00093
00094
00095
00096
00097
00098 std::pair<std::string, std::string>
00099 splitPath(const std::string& path)
00100 {
00101 typedef std::vector<std::string>::const_iterator DelimIter;
00102
00103 const std::vector<std::string>& delimiterVector = pathDelimiters();
00104 std::string::size_type delimiterIndex = std::string::npos;
00105
00106 DelimIter delimIter = delimiterVector.begin();
00107 while(delimIter != delimiterVector.end()) {
00108 delimiterIndex = std::min(delimiterIndex, path.rfind(*delimIter));
00109 ++delimIter;
00110 }
00111 if(delimiterIndex == std::string::npos) {
00112 return std::make_pair(std::string(""), path);
00113 }
00114 if(delimiterIndex == path.size() - 1) {
00115 return std::make_pair(path, std::string(""));
00116 }
00117 return std::make_pair(
00118 path.substr(0, delimiterIndex + 1),
00119 path.substr(delimiterIndex + 1, std::string::npos));
00120 }
00121
00122 }
00123
00124 }
00125
00126
00127
00128
00129 #ifdef _WIN32
00130
00131
00132
00133
00134 namespace dlr {
00135
00136 namespace portability {
00137
00138
00139 const std::string& pathDelimiter() {
00140 static std::string delimiter = "\\";
00141 return delimiter;
00142 }
00143
00144
00145
00146 const std::vector<std::string>& pathDelimiters() {
00147 static bool needsInit = true;
00148 static std::vector<std::string> delimiterVector;
00149 if(needsInit) {
00150 delimiterVector.push_back("\\");
00151 delimiterVector.push_back("/");
00152 needsInit = false;
00153 }
00154 return delimiterVector;
00155 }
00156
00157
00158
00159 const std::string& extensionDelimiter() {
00160 static std::string delimiter = ".";
00161 return delimiter;
00162 }
00163
00164
00165
00166
00167 std::vector<std::string>
00168 listDirectory(const std::string& directoryName, bool fullPath)
00169 {
00170 std::vector<std::string> listing;
00171 std::string fileNameGlob = joinPath(directoryName, "*");
00172 WIN32_FIND_DATA findData;
00173 HANDLE handle = FindFirstFile(fileNameGlob.c_str(), &findData);
00174 if (handle == INVALID_HANDLE_VALUE) {
00175 return listing;
00176 }
00177 while(1) {
00178 listing.push_back(std::string(findData.cFileName));
00179 if (!FindNextFile(handle, &findData)) {
00180 if (GetLastError() == ERROR_NO_MORE_FILES) {
00181 break;
00182 }
00183 std::ostringstream message;
00184 message << "Problem reading file names from " << directoryName;
00185 DLR_THROW(dlr::IOException, "listDirectory()",
00186 message.str().c_str());
00187 }
00188 }
00189 if (!FindClose(handle)) {
00190 std::ostringstream message;
00191 message << "Problem closing search handle for " << directoryName;
00192 DLR_THROW(dlr::IOException, "listDirectory()",
00193 message.str().c_str());
00194 }
00195
00196 if(fullPath) {
00197
00198
00199 typedef PointerToBinaryFunctionRA<std::string, std::string, std::string>
00200 functorType;
00201 std::transform(listing.begin(), listing.end(), listing.begin(),
00202 std::bind1st(functorType(joinPath), directoryName));
00203 }
00204 return listing;
00205 }
00206
00207 }
00208
00209 }
00210
00211
00212
00213 #else
00214
00215
00216
00217 namespace dlr {
00218
00219 namespace portability {
00220
00221
00222 const std::string& pathDelimiter() {
00223 static std::string delimiter = "/";
00224 return delimiter;
00225 }
00226
00227
00228
00229 const std::vector<std::string>& pathDelimiters() {
00230 bool needsInit = true;
00231 static std::vector<std::string> delimiterVector;
00232 if(needsInit) {
00233 delimiterVector.push_back("/");
00234 needsInit = false;
00235 }
00236 return delimiterVector;
00237 }
00238
00239
00240
00241 const std::string& extensionDelimiter() {
00242 static std::string delimiter = ".";
00243 return delimiter;
00244 }
00245
00246
00247
00248
00249 std::vector<std::string>
00250 listDirectory(const std::string& directoryName, bool fullPath)
00251 {
00252 std::vector<std::string> listing;
00253
00254 DIR* directoryPtr = opendir(directoryName.c_str());
00255 if(directoryPtr == 0) {
00256 std::ostringstream message;
00257 char charBuffer[1024];
00258 if(strerror_r(errno, charBuffer, 1024) == 0) {
00259 charBuffer[1023] = '\0';
00260 message << charBuffer;
00261 } else {
00262 message << "Unknown error opening directory";
00263 }
00264 message << ": " << directoryName << std::endl;
00265 DLR_THROW(IOException, "listDirectory()", message.str().c_str());
00266 }
00267 try {
00268 while(1) {
00269 struct dirent* directoryEntryPtr = readdir(directoryPtr);
00270 if(directoryEntryPtr == 0) {
00271
00272
00273
00274 break;
00275 }
00276 listing.push_back(std::string(directoryEntryPtr->d_name));
00277 }
00278 } catch(...) {
00279 closedir(directoryPtr);
00280 throw;
00281 }
00282 closedir(directoryPtr);
00283
00284 if(fullPath) {
00285
00286
00287 typedef PointerToBinaryFunctionRA<std::string, std::string, std::string>
00288 functorType;
00289 std::transform(listing.begin(), listing.end(), listing.begin(),
00290 std::bind1st(functorType(joinPath), directoryName));
00291 }
00292 return listing;
00293 }
00294
00295 }
00296
00297 }
00298
00299
00300
00301 #endif
00302