out!
[asdcplib.git] / src / KM_fileio.cpp
index d5d5a40e8c6b1b526272cb39b63012759e855401..b9257abda88d7d9c87bd929cbce7a9bd806c47c7 100644 (file)
@@ -57,6 +57,7 @@ struct iovec {
 # if defined(__linux__)
 #   include <sys/statfs.h>
 # else
+#  include <sys/param.h>
 #  include <sys/mount.h>
 # endif
 
@@ -212,7 +213,7 @@ Kumu::FileSize(const std::string& pathname)
 
 //
 static PathCompList_t&
-s_PathMakeCanonical(PathCompList_t& CList, char separator, bool is_absolute)
+s_PathMakeCanonical(PathCompList_t& CList, bool is_absolute)
 {
   PathCompList_t::iterator ci, ri; // component and removal iterators
 
@@ -246,7 +247,7 @@ Kumu::PathMakeCanonical(const std::string& Path, char separator)
 {
   PathCompList_t CList;
   bool is_absolute = PathIsAbsolute(Path, separator);
-  s_PathMakeCanonical(PathToComponents(Path, CList, separator), separator, is_absolute);
+  s_PathMakeCanonical(PathToComponents(Path, CList, separator), is_absolute);
 
   if ( is_absolute )
     return ComponentsToAbsolutePath(CList, separator);
@@ -349,10 +350,10 @@ Kumu::PathMakeAbsolute(const std::string& Path, char separator)
     }
 
   PathCompList_t CList;
-  CList.push_back(cwd_buf);
+  PathToComponents(cwd_buf, CList);
   CList.push_back(Path);
 
-  return ComponentsToAbsolutePath(s_PathMakeCanonical(CList, separator, true), separator);
+  return ComponentsToAbsolutePath(s_PathMakeCanonical(CList, true), separator);
 }
 
 //
@@ -428,6 +429,28 @@ Kumu::PathSetExtension(const std::string& Path, const std::string& Extension) //
   return Basename + "." + Extension;
 }
 
+//
+std::string
+Kumu::PathJoin(const std::string& Path1, const std::string& Path2, char separator)
+{
+  return Path1 + separator + Path2;
+}
+
+//
+std::string
+Kumu::PathJoin(const std::string& Path1, const std::string& Path2, const std::string& Path3, char separator)
+{
+  return Path1 + separator + Path2 + separator + Path3;
+}
+
+//
+std::string
+Kumu::PathJoin(const std::string& Path1, const std::string& Path2,
+              const std::string& Path3, const std::string& Path4, char separator)
+{
+  return Path1 + separator + Path2 + separator + Path3 + separator + Path4;
+}
+
 //
 Kumu::PathList_t&
 Kumu::FindInPaths(const IPathMatch& Pattern, const Kumu::PathList_t& SearchPaths,
@@ -1189,6 +1212,9 @@ Kumu::WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Fil
 //
 #ifdef KM_WIN32
 
+//
+Kumu::DirScanner::DirScanner(void) : m_Handle(-1) {}
+
 //
 //
 Result_t
@@ -1274,6 +1300,9 @@ Kumu::DirScanner::GetNext(char* filename)
 
 // POSIX directory scanner
 
+//
+Kumu::DirScanner::DirScanner(void) : m_Handle(NULL) {}
+
 //
 Result_t
 Kumu::DirScanner::Open(const char* filename)
@@ -1284,11 +1313,23 @@ Kumu::DirScanner::Open(const char* filename)
 
   if ( ( m_Handle = opendir(filename) ) == NULL )
     {
-      if ( errno == ENOENT )
-       result = RESULT_ENDOFFILE;
-
-      else
-       result = RESULT_FAIL;
+      switch ( errno )
+       {
+       case ENOENT:
+       case ENOTDIR:
+         result = RESULT_NOTAFILE;
+       case EACCES:
+         result = RESULT_NO_PERM;
+       case ELOOP:
+       case ENAMETOOLONG:
+         result = RESULT_PARAM;
+       case EMFILE:
+       case ENFILE:
+         result = RESULT_STATE;
+       default:
+         DefaultLogSink().Error("DirScanner::Open(%s): %s\n", filename, strerror(errno));
+         result = RESULT_FAIL;
+       }
     }
 
   return result;
@@ -1302,8 +1343,17 @@ Kumu::DirScanner::Close()
   if ( m_Handle == NULL )
     return RESULT_FILEOPEN;
 
-  if ( closedir(m_Handle) == -1 )
-    return RESULT_FAIL;
+  if ( closedir(m_Handle) == -1 ) {
+    switch ( errno )
+      {
+      case EBADF:
+      case EINTR:
+       return RESULT_STATE;
+      default:
+       DefaultLogSink().Error("DirScanner::Close(): %s\n", strerror(errno));
+       return RESULT_FAIL;
+      }
+  }
 
   m_Handle = NULL;
   return RESULT_OK;
@@ -1339,8 +1389,10 @@ Kumu::DirScanner::GetNext(char* filename)
 
 //------------------------------------------------------------------------------------------
 
-// note: when moving to KM_fileio, don't forget to write the Win32 versions
-// note: add error messages and remove RESULT_FAIL form DirScanner
+//
+// Attention Windows users: make sure to use the proper separator character
+// with these functions.
+//
 
 // given a path string, create any missing directories so that PathIsDirectory(Path) is true.
 //
@@ -1348,7 +1400,6 @@ Result_t
 Kumu::CreateDirectoriesInPath(const std::string& Path)
 {
   bool abs = PathIsAbsolute(Path);
-  assert(abs);
   PathCompList_t PathComps, TmpPathComps;
 
   PathToComponents(Path, PathComps);
@@ -1404,7 +1455,9 @@ Kumu::DeleteFile(const std::string& filename)
 Result_t
 h__DeletePath(const std::string& pathname)
 {
-  fprintf(stderr, "h__DeletePath %s\n", pathname.c_str());
+  if ( pathname.empty() )
+    return RESULT_NULL_STR;
+
   Result_t result = RESULT_OK;
 
   if ( ! PathIsDirectory(pathname) )
@@ -1473,13 +1526,24 @@ Kumu::DeletePath(const std::string& pathname)
 //
 
 
-#ifdef KM_WIN32
-#else // KM_WIN32
-
-//
 Result_t
 Kumu::FreeSpaceForPath(const std::string& path, Kumu::fsize_t& free_space, Kumu::fsize_t& total_space)
 {
+#ifdef KM_WIN32
+       ULARGE_INTEGER lTotalNumberOfBytes;
+       ULARGE_INTEGER lTotalNumberOfFreeBytes;
+
+       BOOL fResult = ::GetDiskFreeSpaceEx(path.c_str(), NULL, &lTotalNumberOfBytes, &lTotalNumberOfFreeBytes);
+       if (fResult) {
+      free_space = static_cast<Kumu::fsize_t>(lTotalNumberOfFreeBytes.QuadPart);
+      total_space = static_cast<Kumu::fsize_t>(lTotalNumberOfBytes.QuadPart);
+      return RESULT_OK;
+       }
+       HRESULT LastError = ::GetLastError();
+
+       DefaultLogSink().Error("FreeSpaceForPath GetDiskFreeSpaceEx %s: %lu\n", path.c_str(), ::GetLastError());
+       return RESULT_FAIL;
+#else // KM_WIN32
   struct statfs s;
 
   if ( statfs(path.c_str(), &s) == 0 )
@@ -1505,9 +1569,9 @@ Kumu::FreeSpaceForPath(const std::string& path, Kumu::fsize_t& free_space, Kumu:
 
   DefaultLogSink().Error("FreeSpaceForPath statfs %s: %s\n", path.c_str(), strerror(errno));
   return RESULT_FAIL;
+#endif // KM_WIN32
 } 
 
-#endif // KM_WIN32
 
 //
 // end KM_fileio.cpp