diff options
author | rcombs <rcombs@rcombs.me> | 2021-05-05 21:06:19 -0500 |
---|---|---|
committer | rcombs <rcombs@rcombs.me> | 2021-08-11 23:05:46 -0500 |
commit | e2c096cca95e47274e4820d90171114ea7e6544e (patch) | |
tree | 0109aec510350265fd5f7e2995002e98972bd01c | |
parent | 3db8662c8d70600848afbe409a2279f502ca45f9 (diff) | |
download | libass-e2c096cca95e47274e4820d90171114ea7e6544e.tar.bz2 libass-e2c096cca95e47274e4820d90171114ea7e6544e.tar.xz |
ass_string: add various ASS_StringView utility routines
-rw-r--r-- | libass/ass_string.c | 14 | ||||
-rw-r--r-- | libass/ass_string.h | 71 |
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 |