[cpp-sp] branch main updated: WIP on ISO parsing support.

Scott Cantor cantor.2 at osu.edu
Mon Oct 20 23:42:33 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=963bd34086c6369d53a085eca7aae9741e26de35

The following commit(s) were added to refs/heads/main by this push:
     new 963bd340 WIP on ISO parsing support.
963bd340 is described below

commit 963bd34086c6369d53a085eca7aae9741e26de35
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Oct 20 19:42:29 2025 -0400

    WIP on ISO parsing support.
---
 shibsp/util/Misc.cpp          | 64 +++++++++++++++++++++++++++++++++++++++++++
 shibsp/util/Misc.h            |  7 +++++
 tests/util/ISOParserTests.cpp | 40 +++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)

diff --git a/shibsp/util/Misc.cpp b/shibsp/util/Misc.cpp
index 48df59e1..f49b2a04 100644
--- a/shibsp/util/Misc.cpp
+++ b/shibsp/util/Misc.cpp
@@ -24,9 +24,18 @@
 #include <set>
 #include <vector>
 #include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include <sys/stat.h>
 
+#ifdef SHIBSP_USE_BOOST_REGEX
+# include <boost/regex.hpp>
+namespace regexp = boost;
+#else
+# include <regex>
+namespace regexp = std;
+#endif
+
 using namespace shibsp;
 using namespace std;
 
@@ -50,6 +59,61 @@ set<string>::size_type shibsp::split_to_container(set<string>& container, const
     return container.size();
 }
 
+time_t shibsp::parseISODuration(const string& s)
+{
+    // If solving a problem with a regex gives you two problems, any estimates on these?
+    static regexp::regex notime_parser("P([[:d:]]+Y)?([[:d:]]+M)?([[:d:]]+D)?");
+    static regexp::regex full_parser("P([[:d:]]+Y)?([[:d:]]+M)?([[:d:]]+D)?T([[:d:]]+H)?([[:d:]]+M)?([[:d:]]+S|[[:d:]]+\\.[[:d:]]+S)?");
+    
+    regexp::smatch match;
+
+    try {
+        if (strchr(s.c_str(), 'T')) {
+            regexp::regex_search(s, match, full_parser);
+        }
+        else {
+            regexp::regex_search(s, match, notime_parser);
+        }
+    }
+    catch (const regexp::regex_error& e) {
+        return 0;
+    }
+
+    if (match.empty()) {
+        return 0;
+    }
+
+    vector<double> vec = {0,0,0,0,0,0}; // years, months, days, hours, minutes, seconds
+
+    for (size_t i = 1; i < match.size(); ++i) {
+
+        if (match[i].matched) {
+            string str = match[i];
+            str.pop_back(); // remove last character.
+            try {
+                vec[i-1] = boost::lexical_cast<long>(str);
+            }
+            catch (const boost::bad_lexical_cast& e) {
+                return 0;
+            }
+        }
+    }
+
+    time_t duration =   31556926   * vec[0] +  // years  
+                        2629743.83 * vec[1] +  // months
+                        86400      * vec[2] +  // days
+                        3600       * vec[3] +  // hours
+                        60         * vec[4] +  // minutes
+                        1          * vec[5];   // seconds    
+
+    return duration;
+}
+
+time_t shibsp::parseISODateTime(const string& s)
+{
+    return 0;
+}
+
 bool FileSupport::exists(const char* path)
 {
 #ifdef WIN32
diff --git a/shibsp/util/Misc.h b/shibsp/util/Misc.h
index c0803692..f6942699 100644
--- a/shibsp/util/Misc.h
+++ b/shibsp/util/Misc.h
@@ -23,6 +23,7 @@
 #include <set>
 #include <string>
 #include <vector>
+#include <ctime>
 #include <boost/optional.hpp>
 
 namespace shibsp {
@@ -83,6 +84,12 @@ namespace shibsp {
         }
     };
 
+    /**
+     * ISO format parsers.
+     */
+    SHIBSP_API time_t parseISODuration(const std::string& s);
+    SHIBSP_API time_t parseISODateTime(const std::string& s);
+
     struct FileSupport {
         /**
          * Checks whether a file exists.
diff --git a/tests/util/ISOParserTests.cpp b/tests/util/ISOParserTests.cpp
new file mode 100644
index 00000000..a436d0d6
--- /dev/null
+++ b/tests/util/ISOParserTests.cpp
@@ -0,0 +1,40 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * util/ISOParserTests.cpp
+ *
+ * Unit tests for ISO Date/Time/Duration parsing.
+ */
+
+#include "util/Misc.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace shibsp;
+using namespace std;
+
+BOOST_AUTO_TEST_CASE(DurationTests)
+{
+    BOOST_CHECK_EQUAL(parseISODuration("Foo"), 0);
+    BOOST_CHECK_EQUAL(parseISODuration("PT10S"), 10);
+    BOOST_CHECK_EQUAL(parseISODuration("PT10M"), 10 * 60);
+    BOOST_CHECK_EQUAL(parseISODuration("PT10H"), 10 * 60 * 60);
+    BOOST_CHECK_EQUAL(parseISODuration("P1D"), 24 * 60 * 60);
+    BOOST_CHECK_EQUAL(parseISODuration("P1Y"), 31556926);
+
+    BOOST_CHECK_EQUAL(parseISODuration("P1DT1H1M1S"), 24 * 60 * 60 + 60 * 60 + 60 + 1);
+
+    BOOST_CHECK_EQUAL(parseISODuration("PT10H5M30S"), 10 * 60 * 60 + 5 * 60 + 30);
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list