Improve image filename sorter.
authorCarl Hetherington <cth@carlh.net>
Thu, 16 Jul 2015 23:41:04 +0000 (00:41 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 16 Jul 2015 23:41:04 +0000 (00:41 +0100)
ChangeLog
src/lib/image_filename_sorter.cc
test/image_filename_sorter_test.cc

index 3d149a82401e938d3f9358d86e5d21c7a898c8e6..d6ae72fb83f94681b5151c6f0c83755cd0097b8b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-07-17  Carl Hetherington  <cth@carlh.net>
+
+       * Improve still-image filename sorting.
+
 2015-07-16  Carl Hetherington  <cth@carlh.net>
 
        * Updated ru_RU translation from Igor Voytovich.
index 5a3e1dcecf6ce11297ba7c94c00945393d4d7377..037446398115b66e665acd4dccf2bb299897907a 100644 (file)
@@ -27,35 +27,49 @@ class ImageFilenameSorter
 public:
        bool operator() (boost::filesystem::path a, boost::filesystem::path b)
        {
-               boost::optional<int> na = extract_number (a);
-               boost::optional<int> nb = extract_number (b);
-               if (!na || !nb) {
-                       return a.string() < b.string();
+               std::vector<int> na = extract_numbers (a);
+               std::vector<int> nb = extract_numbers (b);
+
+               std::vector<int>::const_iterator i = na.begin ();
+               std::vector<int>::const_iterator j = nb.begin ();
+
+               while (true) {
+                       if (i == na.end () || j == nb.end ()) {
+                               return false;
+                       }
+
+                       if (*i != *j) {
+                               return *i < *j;
+                       }
+
+                       ++i;
+                       ++j;
                }
 
-               return na.get() < nb.get();
+               /* NOT REACHED */
+               return false;
        }
 
 private:
-       boost::optional<int> extract_number (boost::filesystem::path p)
+       std::vector<int> extract_numbers (boost::filesystem::path p)
        {
                p = p.leaf ();
 
+               std::vector<int> numbers;
                std::string number;
                for (size_t i = 0; i < p.string().size(); ++i) {
                        if (isdigit (p.string()[i])) {
                                number += p.string()[i];
-                       } else {
-                               if (!number.empty ()) {
-                                       break;
-                               }
+                       } else if (!number.empty ()) {
+                               numbers.push_back (raw_convert<int> (number));
+                               number.clear ();
                        }
                }
 
-               if (number.empty ()) {
-                       return boost::optional<int> ();
+               if (!number.empty ()) {
+                       numbers.push_back (raw_convert<int> (number));
                }
 
-               return raw_convert<int> (number);
+               return numbers;
        }
 };
index 830065f772cd2c551231229e3b1c46490d3c8864..4bdd16f5547d663f99fcceda0465af5dff6c7acf 100644 (file)
@@ -31,6 +31,7 @@ BOOST_AUTO_TEST_CASE (image_filename_sorter_test)
        BOOST_CHECK (x ("1", "999"));
        BOOST_CHECK (x ("00057.tif", "00166.tif"));
        BOOST_CHECK (x ("/my/numeric999/path/00057.tif", "/my/numeric999/path/00166.tif"));
+       BOOST_CHECK (x ("1_01.tif", "1_02.tif"));
 
        BOOST_CHECK (!x ("abc0000000002", "abc0000000001"));
        BOOST_CHECK (!x ("2", "1"));
@@ -38,4 +39,5 @@ BOOST_AUTO_TEST_CASE (image_filename_sorter_test)
        BOOST_CHECK (!x ("2", "0001"));
        BOOST_CHECK (!x ("999", "1"));
        BOOST_CHECK (!x ("/my/numeric999/path/00166.tif", "/my/numeric999/path/00057.tif"));
+       BOOST_CHECK (!x ("1_02.tif", "1_01.tif"));
 }