This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 0f52de3a68 Allow query parameters to erase() 'all but' (#11352)
0f52de3a68 is described below

commit 0f52de3a68919db7e5cdce7d6b63aff483ad1a77
Author: Leif Hedstrom <zw...@apache.org>
AuthorDate: Wed May 22 09:25:03 2024 -0600

    Allow query parameters to erase() 'all but' (#11352)
---
 include/cripts/Urls.hpp        | 13 +++++------
 src/cripts/Urls.cc             | 31 +++++++++++++++++++++++++
 src/cripts/tests/query_test.cc | 52 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 7 deletions(-)

diff --git a/include/cripts/Urls.hpp b/include/cripts/Urls.hpp
index 5e78a70825..1a16d624c3 100644
--- a/include/cripts/Urls.hpp
+++ b/include/cripts/Urls.hpp
@@ -426,20 +426,19 @@ public:
     Cript::string      operator+=(Cript::string_view add);
     Parameter          operator[](Cript::string_view param);
     void               erase(Cript::string_view param);
+    void               erase(std::initializer_list<Cript::string_view> list, 
bool keep = false);
 
     void
-    erase(std::initializer_list<Cript::string_view> list)
+    erase()
     {
-      for (auto &it : list) {
-        erase(it);
-      }
+      operator=("");
+      _size = 0;
     }
 
     void
-    erase()
+    keep(std::initializer_list<Cript::string_view> list)
     {
-      operator=("");
-      _size = 0;
+      erase(list, true);
     }
 
     void
diff --git a/src/cripts/Urls.cc b/src/cripts/Urls.cc
index c78b6d0fe3..ebfca52c74 100644
--- a/src/cripts/Urls.cc
+++ b/src/cripts/Urls.cc
@@ -331,6 +331,37 @@ Url::Query::erase(Cript::string_view param)
   }
 }
 
+void
+Url::Query::erase(std::initializer_list<Cript::string_view> list, bool keep)
+{
+  if (keep) {
+    // Make sure the hash and vector are populated
+    _parser();
+
+    for (auto viter = _ordered.begin(); viter != _ordered.end();) {
+      if (list.end() == std::find(list.begin(), list.end(), *viter)) {
+        auto iter = _hashed.find(*viter);
+
+        TSReleaseAssert(iter != _hashed.end());
+        _size -= iter->second.size(); // Size of the erased value
+        _size -= viter->size();       // Length of the erased key
+        _hashed.erase(iter);
+        viter     = _ordered.erase(viter);
+        _modified = true;
+      } else {
+        ++viter;
+      }
+    }
+    if (_ordered.size() == 0) {
+      reset();
+    }
+  } else {
+    for (auto &it : list) {
+      erase(it);
+    }
+  }
+}
+
 void
 Url::Query::reset()
 {
diff --git a/src/cripts/tests/query_test.cc b/src/cripts/tests/query_test.cc
new file mode 100644
index 0000000000..04bb6b1bea
--- /dev/null
+++ b/src/cripts/tests/query_test.cc
@@ -0,0 +1,52 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+*/
+#include <cripts/Preamble.hpp>
+
+// We do this so we can have one Cript for multiple remaps
+do_create_instance()
+{
+  if (instance.size() > 0) {
+    instance.data[0] = integer(AsString(instance.data[0]));
+  } else {
+    instance.data[0] = 0;
+  }
+}
+
+do_remap()
+{
+  borrow url = Client::URL::get();
+
+  switch (AsInteger(instance.data[0])) {
+  case 0:
+    url.query.erase({"foo", "bar"}, true);
+    break;
+  case 1:
+    url.query.erase({"foo", "bar"});
+    break;
+  case 2:
+    url.query.keep({"foo", "bar"});
+    break;
+  default:
+    break;
+  }
+
+  url.query.flush();
+  CDebug("Query: {}", url.query);
+}
+
+#include <cripts/Epilogue.hpp>

Reply via email to