lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 325e88a 12/33: Increase filename portability


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 325e88a 12/33: Increase filename portability
Date: Mon, 3 May 2021 08:15:52 -0400 (EDT)

branch: master
commit 325e88a0e15cd33648c446ea9b842e82462bf6e9
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Increase filename portability
    
    It is no longer possible to "fail a std::filesystem name check".
    Unlike the boost original, std::filesystem doesn't check filename
    validity, so where portable filenames are preferred, lmi must enforce
    its own rules. Improved the original serial_file_path() implementation
    by making both user-specified components portable--simplified example:
    
      "My Employer.cns" // input
      "My Name.text"    // input
      "My Employer.My_Name.text" // old output (contains space)
      "My_Employer.My_Name.text" // new output (portable)
    
    IOW, if replacing one space is good, then replacing both is better.
    
    Added unit tests that would have failed without this change.
    
    Added a comment explaining why rules originally imposed for 'fop'
    compatibility are still enforced even though 'fop' is no longer used.
---
 path_utility.cpp      | 13 +++++++++----
 path_utility_test.cpp | 10 ++++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/path_utility.cpp b/path_utility.cpp
index a0c273b..d68b0b2 100644
--- a/path_utility.cpp
+++ b/path_utility.cpp
@@ -101,6 +101,10 @@ fs::path modify_directory
 /// in case an end user types something like
 ///   Crime and/or Punishment
 /// with no intention of denoting a path.
+///
+/// Even though lmi no longer uses fop, it is still good to impose
+/// some rationality on output filenames that reflect end-user input,
+/// and the rules above are reasonable.
 
 std::string portable_filename(std::string const& original_filename)
 {
@@ -203,9 +207,9 @@ std::string serial_extension
 /// Any extension or path is discarded from the input census filepath;
 /// only the filename is used.
 ///
-/// It is necessary to call portable_filename() on the insured's name
-/// in case it contains a character (probably whitespace) that might
-/// fail a std::filesystem name check.
+/// Apply portable_filename() to the census filename and the insured's
+/// name: because they're under end-user control, they may contain
+/// characters that would render the resulting filename nonportable.
 
 fs::path serial_file_path
     (fs::path    const& exemplar
@@ -216,6 +220,7 @@ fs::path serial_file_path
 {
     LMI_ASSERT(!exemplar.empty());
     LMI_ASSERT(exemplar.has_filename());
+    fs::path f(portable_filename(exemplar.filename().string()));
     std::string s(serial_extension(serial_number, extension));
     if
         (  !personal_name.empty()
@@ -224,7 +229,7 @@ fs::path serial_file_path
         {
         s = '.' + portable_filename(personal_name) + s;
         }
-    return fs::path{exemplar}.filename().replace_extension(s);
+    return f.replace_extension(s);
 }
 
 /// Create a unique file path, following input as closely as possible.
diff --git a/path_utility_test.cpp b/path_utility_test.cpp
index d05fbd0..b9aa114 100644
--- a/path_utility_test.cpp
+++ b/path_utility_test.cpp
@@ -166,6 +166,16 @@ void test_serial_file_path()
         (                                 "x.000012346.y"
         ,serial_file_path("/path/to/x", "",      12345, "y").string()
         );
+
+    // Make both census and personal names portable.
+    LMI_TEST_EQUAL
+        (                         "My_Employer.My_Name.text.1000000000.tsv"
+        ,serial_file_path("My Employer.cns", "My Name.text", 999999999, 
"tsv").string()
+        );
+    LMI_TEST_EQUAL
+        (                 
"Fyodor_Dostoyevskiy.Crime_and_Punishment.text.000001867.xyz"
+        ,serial_file_path("Fyodor Dostoyevskiy", "Crime and Punishment.text", 
1866, "xyz").string()
+        );
 }
 
 void test_unique_filepath_with_normal_filenames()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]