diff options
| author | jhurst <jhurst@cinecert.com> | 2013-02-08 19:11:58 +0000 |
|---|---|---|
| committer | jhurst <> | 2013-02-08 19:11:58 +0000 |
| commit | 9998b893b47f111f41c4f0fcf1067efe5b7a62f3 (patch) | |
| tree | ef455067287c17ebb9f82ecf3d27d134823c1edb /src/KM_fileio.cpp | |
| parent | b3fa00a9f37ecc7c2bef6276aae0ea67d1ddbeb3 (diff) | |
big change rollup
Diffstat (limited to 'src/KM_fileio.cpp')
| -rw-r--r-- | src/KM_fileio.cpp | 179 |
1 files changed, 109 insertions, 70 deletions
diff --git a/src/KM_fileio.cpp b/src/KM_fileio.cpp index 5d728cc..fdd4719 100644 --- a/src/KM_fileio.cpp +++ b/src/KM_fileio.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2011, John Hurst +Copyright (c) 2004-2012, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -70,31 +70,6 @@ struct iovec { typedef struct stat fstat_t; #endif -// -static void -split(const std::string& str, char separator, std::list<std::string>& components) -{ - const char* pstr = str.c_str(); - const char* r = strchr(pstr, separator); - - while ( r != 0 ) - { - assert(r >= pstr); - if ( r > pstr ) - { - std::string tmp_str; - tmp_str.assign(pstr, (r - pstr)); - components.push_back(tmp_str); - } - - pstr = r + 1; - r = strchr(pstr, separator); - } - - if( strlen(pstr) > 0 ) - components.push_back(std::string(pstr)); -} - // static Kumu::Result_t @@ -216,61 +191,55 @@ Kumu::FileSize(const std::string& pathname) } // -static PathCompList_t& -s_PathMakeCanonical(PathCompList_t& CList, bool is_absolute) +static void +make_canonical_list(const PathCompList_t& in_list, PathCompList_t& out_list) { - PathCompList_t::iterator ci, ri; // component and removal iterators - - for ( ci = CList.begin(); ci != CList.end(); ci++ ) + PathCompList_t::const_iterator i; + for ( i = in_list.begin(); i != in_list.end(); ++i ) { - if ( *ci == "." && ( CList.size() > 1 || is_absolute ) ) - { - ri = ci++; - CList.erase(ri); - } - else if ( *ci == ".." && ci != CList.begin() ) + if ( *i == ".." ) { - ri = ci; - ri--; - - if ( *ri != ".." ) + if ( ! out_list.empty() ) { - CList.erase(ri); - ri = ci++; - CList.erase(ri); - } - } + out_list.pop_back(); + } + } + else if ( *i != "." ) + { + out_list.push_back(*i); + } } - - return CList; } // std::string Kumu::PathMakeCanonical(const std::string& Path, char separator) { - PathCompList_t CList; + PathCompList_t in_list, out_list; bool is_absolute = PathIsAbsolute(Path, separator); - s_PathMakeCanonical(PathToComponents(Path, CList, separator), is_absolute); + PathToComponents(Path, in_list, separator); + make_canonical_list(in_list, out_list); if ( is_absolute ) - return ComponentsToAbsolutePath(CList, separator); + return ComponentsToAbsolutePath(out_list, separator); - return ComponentsToPath(CList, separator); + return ComponentsToPath(out_list, separator); } // bool Kumu::PathsAreEquivalent(const std::string& lhs, const std::string& rhs) { - return PathMakeCanonical(lhs) == PathMakeCanonical(rhs); + return PathMakeAbsolute(lhs) == PathMakeAbsolute(rhs); } // Kumu::PathCompList_t& Kumu::PathToComponents(const std::string& Path, PathCompList_t& CList, char separator) { - split(Path, separator, CList); + std::string s; + s = separator; + CList = km_token_split(Path, s); return CList; } @@ -334,18 +303,8 @@ Kumu::PathIsAbsolute(const std::string& Path, char separator) // std::string -Kumu::PathMakeAbsolute(const std::string& Path, char separator) +Kumu::PathCwd() { - if ( Path.empty() ) - { - std::string out_path; - out_path = separator; - return out_path; - } - - if ( PathIsAbsolute(Path, separator) ) - return Path; - char cwd_buf [MaxFilePath]; if ( _getcwd(cwd_buf, MaxFilePath) == 0 ) { @@ -353,11 +312,28 @@ Kumu::PathMakeAbsolute(const std::string& Path, char separator) return ""; } - PathCompList_t CList; - PathToComponents(cwd_buf, CList); - CList.push_back(Path); + return cwd_buf; +} - return ComponentsToAbsolutePath(s_PathMakeCanonical(CList, true), separator); +// +std::string +Kumu::PathMakeAbsolute(const std::string& Path, char separator) +{ + if ( Path.empty() ) + { + std::string tmpstr; + tmpstr = separator; + return tmpstr; + } + + if ( PathIsAbsolute(Path, separator) ) + return PathMakeCanonical(Path); + + PathCompList_t in_list, out_list; + PathToComponents(PathJoin(PathCwd(), Path), in_list); + make_canonical_list(in_list, out_list); + + return ComponentsToAbsolutePath(out_list); } // @@ -455,6 +431,69 @@ Kumu::PathJoin(const std::string& Path1, const std::string& Path2, return Path1 + separator + Path2 + separator + Path3 + separator + Path4; } +#ifndef KM_WIN32 +// returns false if link cannot be read +// +bool +Kumu::PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator) +{ + PathCompList_t in_list, out_list; + PathToComponents(PathMakeCanonical(link_path), in_list, separator); + PathCompList_t::iterator i; + char link_buf[MaxFilePath]; + + for ( i = in_list.begin(); i != in_list.end(); ++i ) + { + assert ( *i != ".." && *i != "." ); + out_list.push_back(*i); + + for (;;) + { + std::string next_link = ComponentsToAbsolutePath(out_list, separator); + ssize_t link_size = readlink(next_link.c_str(), link_buf, MaxFilePath); + + if ( link_size == -1 ) + { + if ( errno == EINVAL ) + break; + + DefaultLogSink().Error("%s: readlink: %s\n", next_link.c_str(), strerror(errno)); + return false; + } + + assert(link_size < MaxFilePath); + link_buf[link_size] = 0; + std::string tmp_path; + out_list.clear(); + + if ( PathIsAbsolute(link_buf) ) + { + tmp_path = link_buf; + } + else + { + tmp_path = PathJoin(PathDirname(next_link), link_buf); + } + + PathToComponents(PathMakeCanonical(tmp_path), out_list, separator); + } + } + + resolved_path = ComponentsToAbsolutePath(out_list, separator); + return true; +} + +#else // KM_WIN32 +// TODO: is there a reasonable equivalent to be written for win32? +// +bool +Kumu::PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator) +{ + resolved_path = link_path; + return true; +} +#endif + // Kumu::PathList_t& Kumu::FindInPaths(const IPathMatch& Pattern, const Kumu::PathList_t& SearchPaths, @@ -1520,7 +1559,7 @@ h__DeletePath(const std::string& pathname) Result_t Kumu::DeletePath(const std::string& pathname) { - std::string c_pathname = PathMakeAbsolute(PathMakeCanonical(pathname)); + std::string c_pathname = PathMakeCanonical(PathMakeAbsolute(pathname)); DefaultLogSink().Debug("DeletePath (%s) c(%s)\n", pathname.c_str(), c_pathname.c_str()); return h__DeletePath(c_pathname); } |
