Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <mail@jlucke.com>2019-09-12 17:51:55 +0300
committerJacques Lucke <mail@jlucke.com>2019-09-12 17:55:35 +0300
commit058d218254418c1ae681b4b9e5c8a9be93ad69b3 (patch)
treea3e37bbb537809d798106fd00f40db94feb158d8 /source/blender
parent914f4308fb828941436c1ecfb4a58b18017fbd1c (diff)
BLI: new StringRef and StringRefNull data structures
These two data structures reference strings somewhere in memory. They do not own the referenced string. The string is considered const. A string referenced by StringRefNull can be expected to be null-terminated. That is not the case for StringRef. This commit is a continuation of rB369d5e8ad2bb7c2.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenlib/BLI_string_ref.h244
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
2 files changed, 245 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_string_ref.h b/source/blender/blenlib/BLI_string_ref.h
new file mode 100644
index 00000000000..9d4678f335f
--- /dev/null
+++ b/source/blender/blenlib/BLI_string_ref.h
@@ -0,0 +1,244 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * A StringRef is a pointer to a string somewhere in memory. It should not be used to transfer
+ * ownership of that string. When a function gets a StringRef as input, it cannot expect, that
+ * the string will still exist after the function ends.
+ *
+ * There are two types of string references: One that guarantees null termination and one that does
+ * not.
+ */
+
+#pragma once
+
+#include <cstring>
+#include <string>
+#include <sstream>
+
+#include "BLI_utildefines.h"
+#include "BLI_array_ref.h"
+
+namespace BLI {
+
+class StringRef;
+
+class StringRefBase {
+ public:
+ using size_type = size_t;
+
+ protected:
+ const char *m_data;
+ size_type m_size;
+
+ StringRefBase(const char *data, size_type size) : m_data(data), m_size(size)
+ {
+ }
+
+ public:
+ /**
+ * Return the (byte-)length of the referenced string, without any null-terminator.
+ */
+ size_type size() const
+ {
+ return m_size;
+ }
+
+ /**
+ * Return a pointer to the start of the string.
+ */
+ const char *data() const
+ {
+ return m_data;
+ }
+
+ char operator[](size_type index) const
+ {
+ BLI_assert(index <= m_size);
+ return m_data[index];
+ }
+
+ operator ArrayRef<char>() const
+ {
+ return ArrayRef<char>(m_data, m_size);
+ }
+
+ operator std::string() const
+ {
+ return std::string(m_data, m_size);
+ }
+
+ const char *begin() const
+ {
+ return m_data;
+ }
+
+ const char *end() const
+ {
+ return m_data + m_size;
+ }
+
+ void copy_to__with_null(char *dst) const
+ {
+ memcpy(dst, m_data, m_size);
+ dst[m_size] = '\0';
+ }
+
+ /**
+ * Returns true when the string begins with the given prefix. Otherwise false.
+ */
+ bool startswith(StringRef prefix) const;
+
+ /**
+ * Returns true when the string ends with the given suffix. Otherwise false.
+ */
+ bool endswith(StringRef suffix) const;
+};
+
+/**
+ * References a null-terminated char array.
+ */
+class StringRefNull : public StringRefBase {
+
+ public:
+ StringRefNull() : StringRefBase("", 0)
+ {
+ }
+
+ StringRefNull(const char *str) : StringRefBase(str, strlen(str))
+ {
+ BLI_assert(str != NULL);
+ BLI_assert(m_data[m_size] == '\0');
+ }
+
+ StringRefNull(const char *str, size_type size) : StringRefBase(str, size)
+ {
+ BLI_assert(str[size] == '\0');
+ }
+
+ StringRefNull(const std::string &str) : StringRefNull(str.data())
+ {
+ }
+};
+
+/**
+ * References a char array. It might not be null terminated.
+ */
+class StringRef : public StringRefBase {
+ public:
+ StringRef() : StringRefBase(nullptr, 0)
+ {
+ }
+
+ StringRef(StringRefNull other) : StringRefBase(other.data(), other.size())
+ {
+ }
+
+ StringRef(const char *str) : StringRefBase(str, str ? strlen(str) : 0)
+ {
+ }
+
+ StringRef(const char *str, size_type length) : StringRefBase(str, length)
+ {
+ }
+
+ StringRef(const std::string &str) : StringRefBase(str.data(), str.size())
+ {
+ }
+
+ /**
+ * Return a new StringRef that does not contain the first n chars.
+ */
+ StringRef drop_prefix(uint n) const
+ {
+ BLI_assert(n <= m_size);
+ return StringRef(m_data + n, m_size - n);
+ }
+
+ /**
+ * Return a new StringRef that with the given prefix being skipped.
+ * Asserts that the string begins with the given prefix.
+ */
+ StringRef drop_prefix(StringRef prefix) const
+ {
+ BLI_assert(this->startswith(prefix));
+ return this->drop_prefix(prefix.size());
+ }
+};
+
+/* More inline functions
+ ***************************************/
+
+inline std::ostream &operator<<(std::ostream &stream, StringRef ref)
+{
+ stream << std::string(ref);
+ return stream;
+}
+
+inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
+{
+ stream << std::string(ref.data(), ref.size());
+ return stream;
+}
+
+inline std::string operator+(StringRef a, StringRef b)
+{
+ return std::string(a) + std::string(b);
+}
+
+inline bool operator==(StringRef a, StringRef b)
+{
+ if (a.size() != b.size()) {
+ return false;
+ }
+ return STREQLEN(a.data(), b.data(), a.size());
+}
+
+inline bool operator!=(StringRef a, StringRef b)
+{
+ return !(a == b);
+}
+
+inline bool StringRefBase::startswith(StringRef prefix) const
+{
+ if (m_size < prefix.m_size) {
+ return false;
+ }
+ for (uint i = 0; i < prefix.m_size; i++) {
+ if (m_data[i] != prefix.m_data[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool StringRefBase::endswith(StringRef suffix) const
+{
+ if (m_size < suffix.m_size) {
+ return false;
+ }
+ uint offset = m_size - suffix.m_size;
+ for (uint i = 0; i < suffix.m_size; i++) {
+ if (m_data[offset + i] != suffix.m_data[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace BLI
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index b4db305ccd4..abef583913c 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -225,6 +225,7 @@ set(SRC
BLI_strict_flags.h
BLI_string.h
BLI_string_cursor_utf8.h
+ BLI_string_ref.h
BLI_string_utf8.h
BLI_string_utils.h
BLI_sys_types.h