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 std::string::size_type delimiterIndex = path.rfind(pathDelimiter());
00102 if(delimiterIndex == std::string::npos) {
00103 return std::make_pair(std::string(""), path);
00104 }
00105 if(delimiterIndex == path.size() - 1) {
00106 return std::make_pair(path, std::string(""));
00107 }
00108 return std::make_pair(
00109 path.substr(0, delimiterIndex + 1),
00110 path.substr(delimiterIndex + 1, std::string::npos));
00111 }
00112
00113 }
00114
00115 }
00116
00117
00118
00119
00120 #ifdef _WIN32
00121
00122
00123
00124
00125 namespace dlr {
00126
00127 namespace portability {
00128
00129
00130 const std::string& pathDelimiter() {
00131 static std::string delimiter = "\\";
00132 return delimiter;
00133 }
00134
00135
00136
00137 const std::string& extensionDelimiter() {
00138 static std::string delimiter = ".";
00139 return delimiter;
00140 }
00141
00142
00143
00144
00145 std::vector<std::string>
00146 listDirectory(const std::string& directoryName, bool fullPath)
00147 {
00148 std::vector<std::string> listing;
00149 std::string fileNameGlob = joinPath(directoryName, "*");
00150 WIN32_FIND_DATA findData;
00151 HANDLE handle = FindFirstFile(fileNameGlob.c_str(), &findData);
00152 if (handle == INVALID_HANDLE_VALUE) {
00153 return listing;
00154 }
00155 while(1) {
00156 listing.push_back(std::string(findData.cFileName));
00157 if (!FindNextFile(handle, &findData)) {
00158 if (GetLastError() == ERROR_NO_MORE_FILES) {
00159 break;
00160 }
00161 std::ostringstream message;
00162 message << "Problem reading file names from " << directoryName;
00163 DLR_THROW(dlr::IOException, "listDirectory()",
00164 message.str().c_str());
00165 }
00166 }
00167 if (!FindClose(handle)) {
00168 std::ostringstream message;
00169 message << "Problem closing search handle for " << directoryName;
00170 DLR_THROW(dlr::IOException, "listDirectory()",
00171 message.str().c_str());
00172 }
00173
00174 if(fullPath) {
00175
00176
00177 typedef PointerToBinaryFunctionRA<std::string, std::string, std::string>
00178 functorType;
00179 std::transform(listing.begin(), listing.end(), listing.begin(),
00180 std::bind1st(functorType(joinPath), directoryName));
00181 }
00182 return listing;
00183 }
00184
00185 }
00186
00187 }
00188
00189
00190
00191 #else
00192
00193
00194
00195 namespace dlr {
00196
00197 namespace portability {
00198
00199
00200 const std::string& pathDelimiter() {
00201 static std::string delimiter = "/";
00202 return delimiter;
00203 }
00204
00205
00206
00207 const std::string& extensionDelimiter() {
00208 static std::string delimiter = ".";
00209 return delimiter;
00210 }
00211
00212
00213
00214
00215 std::vector<std::string>
00216 listDirectory(const std::string& directoryName, bool fullPath)
00217 {
00218 std::vector<std::string> listing;
00219
00220 DIR* directoryPtr = opendir(directoryName.c_str());
00221 if(directoryPtr == 0) {
00222 std::ostringstream message;
00223 char charBuffer[1024];
00224 if(strerror_r(errno, charBuffer, 1024) == 0) {
00225 charBuffer[1023] = '\0';
00226 message << charBuffer;
00227 } else {
00228 message << "Unknown error opening directory";
00229 }
00230 message << ": " << directoryName << std::endl;
00231 DLR_THROW(IOException, "listDirectory()", message.str().c_str());
00232 }
00233 while(1) {
00234 struct dirent* directoryEntryPtr = readdir(directoryPtr);
00235 if(directoryEntryPtr == 0) {
00236
00237
00238
00239 break;
00240 }
00241 listing.push_back(std::string(directoryEntryPtr->d_name));
00242 }
00243
00244 if(fullPath) {
00245
00246
00247 typedef PointerToBinaryFunctionRA<std::string, std::string, std::string>
00248 functorType;
00249 std::transform(listing.begin(), listing.end(), listing.begin(),
00250 std::bind1st(functorType(joinPath), directoryName));
00251 }
00252 return listing;
00253 }
00254
00255 }
00256
00257 }
00258
00259
00260
00261 #endif
00262