]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rgw/rgw_string.h
update sources to v12.1.0
[ceph.git] / ceph / src / rgw / rgw_string.h
index 74e023b4cb19e006017e90f049f9f9e205c9aba3..062880cc1acac23830ae88a4911eb730c7f895ce 100644 (file)
@@ -4,33 +4,37 @@
 #ifndef CEPH_RGW_STRING_H
 #define CEPH_RGW_STRING_H
 
+#include <errno.h>
 #include <stdlib.h>
 #include <limits.h>
 
+#include <boost/container/small_vector.hpp>
+#include <boost/utility/string_view.hpp>
+
 struct ltstr_nocase
 {
-  bool operator()(const string& s1, const string& s2) const
+  bool operator()(const std::string& s1, const std::string& s2) const
   {
     return strcasecmp(s1.c_str(), s2.c_str()) < 0;
   }
 };
 
-static inline int stringcasecmp(const string& s1, const string& s2)
+static inline int stringcasecmp(const std::string& s1, const std::string& s2)
 {
   return strcasecmp(s1.c_str(), s2.c_str());
 }
 
-static inline int stringcasecmp(const string& s1, const char *s2)
+static inline int stringcasecmp(const std::string& s1, const char *s2)
 {
   return strcasecmp(s1.c_str(), s2);
 }
 
-static inline int stringcasecmp(const string& s1, int ofs, int size, const string& s2)
+static inline int stringcasecmp(const std::string& s1, int ofs, int size, const std::string& s2)
 {
   return strncasecmp(s1.c_str() + ofs, s2.c_str(), size);
 }
 
-static inline int stringtoll(const string& s, int64_t *val)
+static inline int stringtoll(const std::string& s, int64_t *val)
 {
   char *end;
 
@@ -46,7 +50,7 @@ static inline int stringtoll(const string& s, int64_t *val)
   return 0;
 }
 
-static inline int stringtoull(const string& s, uint64_t *val)
+static inline int stringtoull(const std::string& s, uint64_t *val)
 {
   char *end;
 
@@ -62,7 +66,7 @@ static inline int stringtoull(const string& s, uint64_t *val)
   return 0;
 }
 
-static inline int stringtol(const string& s, int32_t *val)
+static inline int stringtol(const std::string& s, int32_t *val)
 {
   char *end;
 
@@ -78,7 +82,7 @@ static inline int stringtol(const string& s, int32_t *val)
   return 0;
 }
 
-static inline int stringtoul(const string& s, uint32_t *val)
+static inline int stringtoul(const std::string& s, uint32_t *val)
 {
   char *end;
 
@@ -94,4 +98,129 @@ static inline int stringtoul(const string& s, uint32_t *val)
   return 0;
 }
 
+/* A converter between boost::string_view and null-terminated C-strings.
+ * It copies memory while trying to utilize the local memory instead of
+ * issuing dynamic allocations. */
+template<std::size_t N = 128>
+static inline boost::container::small_vector<char, N>
+sview2cstr(const boost::string_view& sv)
+{
+  boost::container::small_vector<char, N> cstr;
+  cstr.reserve(sv.size() + sizeof('\0'));
+
+  cstr.assign(std::begin(sv), std::end(sv));
+  cstr.push_back('\0');
+
+  return cstr;
+}
+
+/* std::strlen() isn't guaranteed to be computable at compile-time. Although
+ * newer GCCs actually do that, Clang doesn't. Please be aware this function
+ * IS NOT A DROP-IN REPLACEMENT FOR STRLEN -- it returns a different result
+ * for strings having \0 in the middle. */
+template<size_t N>
+static inline constexpr size_t sarrlen(const char (&arr)[N]) {
+  return N - 1;
+}
+
+namespace detail {
+
+// variadic sum() to add up string lengths for reserve()
+static inline constexpr size_t sum() { return 0; }
+template <typename... Args>
+constexpr size_t sum(size_t v, Args... args) { return v + sum(args...); }
+
+// traits for string_size()
+template <typename T>
+struct string_traits {
+  static constexpr size_t size(const T& s) { return s.size(); }
+};
+// specializations for char*/const char* use strlen()
+template <>
+struct string_traits<const char*> {
+  static size_t size(const char* s) { return std::strlen(s); }
+};
+template <>
+struct string_traits<char*> : string_traits<const char*> {};
+// constexpr specializations for char[]/const char[]
+template <std::size_t N>
+struct string_traits<const char[N]> {
+  static constexpr size_t size_(const char* s, size_t i) {
+    return i < N ? (*(s + i) == '\0' ? i : size_(s, i + 1))
+        : throw std::invalid_argument("Unterminated string constant.");
+  }
+  static constexpr size_t size(const char(&s)[N]) { return size_(s, 0); }
+};
+template <std::size_t N>
+struct string_traits<char[N]> : string_traits<const char[N]> {};
+
+// helpers for string_cat_reserve()
+static inline void append_to(std::string& s) {}
+template <typename... Args>
+void append_to(std::string& s, const boost::string_view& v, const Args&... args)
+{
+  s.append(v.begin(), v.end());
+  append_to(s, args...);
+}
+
+// helpers for string_join_reserve()
+static inline void join_next(std::string& s, const boost::string_view& d) {}
+template <typename... Args>
+void join_next(std::string& s, const boost::string_view& d,
+               const boost::string_view& v, const Args&... args)
+{
+  s.append(d.begin(), d.end());
+  s.append(v.begin(), v.end());
+  join_next(s, d, args...);
+}
+
+static inline void join(std::string& s, const boost::string_view& d) {}
+template <typename... Args>
+void join(std::string& s, const boost::string_view& d,
+          const boost::string_view& v, const Args&... args)
+{
+  s.append(v.begin(), v.end());
+  join_next(s, d, args...);
+}
+
+} // namespace detail
+
+/// return the length of a c string, string literal, or string type
+template <typename T>
+constexpr size_t string_size(const T& s)
+{
+  return detail::string_traits<T>::size(s);
+}
+
+/// concatenates the given string arguments, returning as a std::string that
+/// gets preallocated with reserve()
+template <typename... Args>
+std::string string_cat_reserve(const Args&... args)
+{
+  size_t total_size = detail::sum(string_size(args)...);
+  std::string result;
+  result.reserve(total_size);
+  detail::append_to(result, args...);
+  return result;
+}
+
+/// joins the given string arguments with a delimiter, returning as a
+/// std::string that gets preallocated with reserve()
+template <typename... Args>
+std::string string_join_reserve(const boost::string_view& delim,
+                                const Args&... args)
+{
+  size_t delim_size = delim.size() * std::max<ssize_t>(0, sizeof...(args) - 1);
+  size_t total_size = detail::sum(string_size(args)...) + delim_size;
+  std::string result;
+  result.reserve(total_size);
+  detail::join(result, delim, args...);
+  return result;
+}
+template <typename... Args>
+std::string string_join_reserve(char delim, const Args&... args)
+{
+  return string_join_reserve(boost::string_view{&delim, 1}, args...);
+}
+
 #endif