summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrcombs <rcombs@rcombs.me>2021-05-05 21:06:19 -0500
committerrcombs <rcombs@rcombs.me>2021-08-11 23:05:46 -0500
commite2c096cca95e47274e4820d90171114ea7e6544e (patch)
tree0109aec510350265fd5f7e2995002e98972bd01c
parent3db8662c8d70600848afbe409a2279f502ca45f9 (diff)
downloadlibass-e2c096cca95e47274e4820d90171114ea7e6544e.tar.bz2
libass-e2c096cca95e47274e4820d90171114ea7e6544e.tar.xz
ass_string: add various ASS_StringView utility routines
-rw-r--r--libass/ass_string.c14
-rw-r--r--libass/ass_string.h71
2 files changed, 85 insertions, 0 deletions
diff --git a/libass/ass_string.c b/libass/ass_string.c
index 7c6d6ee..1072586 100644
--- a/libass/ass_string.c
+++ b/libass/ass_string.c
@@ -76,3 +76,17 @@ int ass_strncasecmp(const char *s1, const char *s2, size_t n)
return a - b;
}
+bool ass_sv_iequal_cstr(ASS_StringView s1, const char *s2)
+{
+ unsigned char a, b;
+
+ do {
+ if (s1.len--)
+ a = lowertab[(unsigned char)*s1.str++];
+ else
+ a = 0;
+ b = lowertab[(unsigned char)*s2++];
+ } while (a && a == b);
+
+ return a - b;
+}
diff --git a/libass/ass_string.h b/libass/ass_string.h
index e77a3a6..a55f3d9 100644
--- a/libass/ass_string.h
+++ b/libass/ass_string.h
@@ -44,6 +44,8 @@ typedef struct {
size_t len;
} ASS_StringView;
+#define ASS_SV(lit) (ASS_StringView){ lit, sizeof(lit) - 1 }
+
static inline char *ass_copy_string(ASS_StringView src)
{
char *buf = malloc(src.len + 1);
@@ -54,9 +56,78 @@ static inline char *ass_copy_string(ASS_StringView src)
return buf;
}
+static inline char ass_sv_peekc(ASS_StringView str)
+{
+ if (!str.len)
+ return 0;
+
+ return *str.str;
+}
+
+static inline ASS_StringView ass_sv_peek(ASS_StringView str, size_t n)
+{
+ if (n > str.len)
+ n = str.len;
+
+ return (ASS_StringView){ str.str, n };
+}
+
+static inline char ass_sv_getc(ASS_StringView* str)
+{
+ if (!str->len)
+ return 0;
+
+ str->len--;
+ return *str->str++;
+}
+
+static inline ASS_StringView ass_sv_get(ASS_StringView* str, size_t n)
+{
+ if (n > str->len)
+ n = str->len;
+
+ ASS_StringView ret = { str->str, n };
+
+ str->str += n;
+ str->len -= n;
+
+ return ret;
+}
+
static inline bool ass_string_equal(ASS_StringView str1, ASS_StringView str2)
{
return str1.len == str2.len && !memcmp(str1.str, str2.str, str1.len);
}
+#define ASS_SV_EQ(view, lit) ass_string_equal(view, ASS_SV(lit))
+
+static inline bool ass_sv_equal_cstr(ASS_StringView str1, const char *str2)
+{
+ return !strncmp(str1.str, str2, str1.len) && str2[str1.len] == 0;
+}
+
+// Check if str1 starts with str2
+static inline bool ass_sv_startswith(ASS_StringView str1, ASS_StringView str2)
+{
+ return str1.len >= str2.len && !memcmp(str1.str, str2.str, str2.len);
+}
+
+#define ASS_SV_STARTSWITH(view, lit) ass_sv_startswith(view, ASS_SV(lit))
+
+static inline bool ass_sv_iequal(ASS_StringView str1, ASS_StringView str2)
+{
+ return str1.len == str2.len && !ass_strncasecmp(str1.str, str2.str, str1.len);
+}
+
+#define ASS_SV_IEQ(view, lit) ass_sv_iequal(view, ASS_SV(lit))
+
+bool ass_sv_iequal_cstr(ASS_StringView str1, const char *str2);
+
+static inline bool ass_sv_istartswith(ASS_StringView str, ASS_StringView check)
+{
+ return ass_sv_iequal(ass_sv_peek(str, check.len), check);
+}
+
+#define ASS_SV_ISTARTSWITH(view, lit) ass_sv_istartswith(view, ASS_SV(lit))
+
#endif