Add QUtil::path_basename

This commit is contained in:
Jay Berkenbilt 2021-02-18 07:55:39 -05:00
parent f21e4f264a
commit 0b1623d07d
6 changed files with 83 additions and 4 deletions

View File

@ -1,5 +1,7 @@
2021-02-18 Jay Berkenbilt <ejb@ql.org>
* Add QUtil::path_basename to get last element of a path.
* Add examples/pdf-attach-file.cc to illustrate new file
attachment method and also new parse that takes indirect objects.

View File

@ -130,14 +130,22 @@ namespace QUtil
// Write the contents of filename as a binary file to the
// pipeline.
QPDF_DLL
void
pipe_file(char const* filename, Pipeline* p);
void pipe_file(char const* filename, Pipeline* p);
// Return a function that will send the contents of the given file
// through the given pipeline as binary data.
QPDF_DLL
std::function<void(Pipeline*)>
file_provider(std::string const& filename);
std::function<void(Pipeline*)> file_provider(std::string const& filename);
// Return the last path element. On Windows, either / or \ are
// path separators. Otherwise, only / is a path separator. Strip
// any trailing path separators. Then, if any path separators
// remain, return everything after the last path separator.
// Otherwise, return the whole string. As a special case, if a
// string consists entirely of path separators, the first
// character is returned.
QPDF_DLL
std::string path_basename(std::string const& filename);
QPDF_DLL
char* copy_string(std::string const&);

View File

@ -663,6 +663,37 @@ QUtil::file_provider(std::string const& filename)
};
}
std::string
QUtil::path_basename(std::string const& filename)
{
#ifdef _WIN32
char const* pathsep = "/\\";
#else
char const* pathsep = "/";
#endif
std::string last = filename;
auto len = last.length();
while (len > 1)
{
auto pos = last.find_last_of(pathsep);
if (pos == len - 1)
{
last.pop_back();
--len;
}
else if (pos == std::string::npos)
{
break;
}
else
{
last = last.substr(pos + 1);
break;
}
}
return last;
}
char*
QUtil::copy_string(std::string const& str)
{

View File

@ -97,6 +97,13 @@ file1: -qutil.out-, file2: -other-file-; same: 0: PASS
file1: -qutil.out-, file2: --; same: 0: PASS
file1: -qutil.out-, file2: -(null)-; same: 0: PASS
file1: --, file2: -qutil.out-; same: 0: PASS
---- path
//// -> /
a/b/cdef -> cdef
a/b/cdef/ -> cdef
/ -> /
->
quack -> quack
---- read from file
This file is used for qutil testing.
It has mixed newlines.

View File

@ -439,6 +439,29 @@ void same_file_test()
assert_same_file("", "qutil.out", false);
}
void path_test()
{
auto check = [](bool print, std::string const& a, std::string const& b) {
auto result = QUtil::path_basename(a);
if (print)
{
std::cout << a << " -> " << result << std::endl;
}
assert(result == b);
};
#ifdef _WIN32
check(false, "asdf\\qwer", "qwer");
check(false, "asdf\\qwer/\\", "qwer");
#endif
check(true, "////", "/");
check(true, "a/b/cdef", "cdef");
check(true, "a/b/cdef/", "cdef");
check(true, "/", "/");
check(true, "", "");
check(true, "quack", "quack");
}
void read_from_file_test()
{
std::list<std::string> lines = QUtil::read_lines_from_file("other-file");
@ -636,6 +659,8 @@ int main(int argc, char* argv[])
get_whoami_test();
std::cout << "---- file" << std::endl;
same_file_test();
std::cout << "---- path" << std::endl;
path_test();
std::cout << "---- read from file" << std::endl;
read_from_file_test();
std::cout << "---- hex encode/decode" << std::endl;

View File

@ -5283,6 +5283,12 @@ print "\n";
matrices.
</para>
</listitem>
<listitem>
<para>
Add <function>QUtil::path_basename</function> to return the
last element of a path.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>