diff --git a/src/lib/eina/eina_inline_slice.x b/src/lib/eina/eina_inline_slice.x index 2f272ad778..a66d753779 100644 --- a/src/lib/eina/eina_inline_slice.x +++ b/src/lib/eina/eina_inline_slice.x @@ -186,6 +186,23 @@ eina_slice_find(const Eina_Slice slice, const Eina_Slice needle) return NULL; } +static inline Eina_Bool +eina_slice_startswith(const Eina_Slice slice, const Eina_Slice prefix) +{ + if (prefix.len == 0) return EINA_FALSE; + if (slice.len < prefix.len) return EINA_FALSE; + return memcmp(slice.mem, prefix.mem, prefix.len) == 0; +} + +static inline Eina_Bool +eina_slice_endswith(const Eina_Slice slice, const Eina_Slice suffix) +{ + if (suffix.len == 0) return EINA_FALSE; + if (slice.len < suffix.len) return EINA_FALSE; + return memcmp(slice.bytes + slice.len - suffix.len, + suffix.mem, suffix.len) == 0; +} + static inline void * eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c) { @@ -199,6 +216,23 @@ eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle) return (void *)eina_slice_find(eina_rw_slice_slice_get(rw_slice), needle); } +static inline Eina_Bool +eina_rw_slice_startswith(const Eina_Rw_Slice rw_slice, const Eina_Slice prefix) +{ + if (prefix.len == 0) return EINA_FALSE; + if (rw_slice.len < prefix.len) return EINA_FALSE; + return memcmp(rw_slice.mem, prefix.mem, prefix.len) == 0; +} + +static inline Eina_Bool +eina_rw_slice_endswith(const Eina_Rw_Slice rw_slice, const Eina_Slice suffix) +{ + if (suffix.len == 0) return EINA_FALSE; + if (rw_slice.len < suffix.len) return EINA_FALSE; + return memcmp(rw_slice.bytes + rw_slice.len - suffix.len, + suffix.mem, suffix.len) == 0; +} + static inline const void * eina_slice_end_get(const Eina_Slice slice) { diff --git a/src/lib/eina/eina_slice.h b/src/lib/eina/eina_slice.h index 7d393ec912..35042d953a 100644 --- a/src/lib/eina/eina_slice.h +++ b/src/lib/eina/eina_slice.h @@ -252,6 +252,28 @@ static inline const void *eina_slice_strchr(const Eina_Slice slice, int c); */ static inline const void *eina_slice_find(const Eina_Slice slice, const Eina_Slice needle); +/** + * @brief Checks if the slice starts with a prefix. + * + * @param slice the reference memory. + * @param prefix the slice to check if @a slice ends with. + * @return #EINA_TRUE if @a slice ends with @a prefix, #EINA_FALSE otherwise. + * + * @since 1.19 + */ +static inline Eina_Bool eina_slice_startswith(const Eina_Slice slice, const Eina_Slice prefix); + +/** + * @brief Checks if the slice ends with a suffix. + * + * @param slice the reference memory. + * @param suffix the slice to check if @a slice ends with. + * @return #EINA_TRUE if @a slice ends with @a suffix, #EINA_FALSE otherwise. + * + * @since 1.19 + */ +static inline Eina_Bool eina_slice_endswith(const Eina_Slice slice, const Eina_Slice suffix); + /** * @brief Find a character inside the slice, similar to memchr(). * @@ -274,6 +296,28 @@ static inline void *eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c); */ static inline void *eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle); +/** + * @brief Checks if the slice starts with a prefix. + * + * @param slice the reference memory. + * @param prefix the slice to check if @a slice ends with. + * @return #EINA_TRUE if @a slice ends with @a prefix, #EINA_FALSE otherwise. + * + * @since 1.19 + */ +static inline Eina_Bool eina_rw_slice_startswith(const Eina_Rw_Slice slice, const Eina_Slice prefix); + +/** + * @brief Checks if the slice ends with a suffix. + * + * @param slice the reference memory. + * @param suffix the slice to check if @a slice ends with. + * @return #EINA_TRUE if @a slice ends with @a suffix, #EINA_FALSE otherwise. + * + * @since 1.19 + */ +static inline Eina_Bool eina_rw_slice_endswith(const Eina_Rw_Slice slice, const Eina_Slice suffix); + /** * @brief The memory position where the slice ends. * diff --git a/src/tests/eina/eina_test_slice.c b/src/tests/eina/eina_test_slice.c index 5634ed4565..7cab7cbda7 100644 --- a/src/tests/eina/eina_test_slice.c +++ b/src/tests/eina/eina_test_slice.c @@ -55,6 +55,7 @@ START_TEST(eina_test_slice_ro) Eina_Slice slice = EINA_SLICE_STR_LITERAL("hi there"); Eina_Slice a, needle; Eina_Rw_Slice dup; + Eina_Bool r; const void *p; char *str; @@ -112,6 +113,24 @@ START_TEST(eina_test_slice_ro) needle = (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD"); /* would go out of boundaries */ p = eina_slice_find(slice, needle); fail_unless(p == NULL); + + r = eina_slice_startswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("HEL")); + fail_unless(r == EINA_TRUE); + + r = eina_slice_startswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD")); + fail_unless(r == EINA_FALSE); + + r = eina_slice_startswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("")); + fail_unless(r == EINA_FALSE); + + r = eina_slice_endswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WO")); + fail_unless(r == EINA_TRUE); + + r = eina_slice_endswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD")); + fail_unless(r == EINA_FALSE); + + r = eina_slice_endswith(slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("")); + fail_unless(r == EINA_FALSE); } END_TEST @@ -121,6 +140,7 @@ START_TEST(eina_test_slice_rw) Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf); Eina_Slice ro_slice; Eina_Rw_Slice a; + Eina_Bool r; const void *p; char *str; @@ -191,6 +211,24 @@ START_TEST(eina_test_slice_rw) fail_unless(p == NULL); fail_unless(buf[sizeof(buf) - 1] == 0xff); + + r = eina_rw_slice_startswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("HEL")); + fail_unless(r == EINA_TRUE); + + r = eina_rw_slice_startswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD")); + fail_unless(r == EINA_FALSE); + + r = eina_rw_slice_startswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("")); + fail_unless(r == EINA_FALSE); + + r = eina_rw_slice_endswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WO")); + fail_unless(r == EINA_TRUE); + + r = eina_rw_slice_endswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD")); + fail_unless(r == EINA_FALSE); + + r = eina_rw_slice_endswith(rw_slice, (Eina_Slice)EINA_SLICE_STR_LITERAL("")); + fail_unless(r == EINA_FALSE); } END_TEST