ssize_t mid;
size_t remaining;
+ fr_sbuff_extend_status_t status = FR_SBUFF_EXTENDABLE;
if (!term) return false; /* If there's no terminals, we don't need to search */
term_idx = idx[(uint8_t)*p]; /* Fast path */
if (!term_idx) return false;
- remaining = fr_sbuff_remaining(in);
+ /*
+ * Special case for EOFlike states
+ */
+ remaining = fr_sbuff_extend_lowat(&status, in, 1);
+ if (remaining == 0) {
+ if (status & FR_SBUFF_EXTEND_ERROR) return false;
+ return (idx['\0'] != 0);
+ }
+
mid = term_idx - 1; /* Inform the mid point from the index */
while (start <= end) {
*/
fr_sbuff_terminal_idx_init(&needle_len, idx, tt);
- if (!fr_sbuff_extend_lowat(NULL, in, needle_len)) return false;
-
return fr_sbuff_terminal_search(in, in->p, idx, tt);
}
#define FR_SBUFF_FLAG_EXTENDABLE 0x01
#define FR_SBUFF_FLAG_EXTENDED 0x02
+#define FR_SBUFF_FLAG_EXTEND_ERROR 0x04
/** Whether the buffer is currently extendable and whether it was extended
*
FR_SBUFF_NOT_EXTENDABLE = 0x00,
FR_SBUFF_EXTENDABLE = FR_SBUFF_FLAG_EXTENDABLE,
FR_SBUFF_EXTENDABLE_EXTENDED = FR_SBUFF_FLAG_EXTENDABLE | FR_SBUFF_FLAG_EXTENDED,
- FR_SBUFF_EXTENDED = FR_SBUFF_FLAG_EXTENDED
+ FR_SBUFF_EXTENDED = FR_SBUFF_FLAG_EXTENDED,
+ FR_SBUFF_EXTEND_ERROR = FR_SBUFF_FLAG_EXTEND_ERROR
} fr_sbuff_extend_status_t;
#define fr_sbuff_is_extendable(_status) ((_status) & FR_SBUFF_FLAG_EXTENDABLE)
TEST_CHECK_STRCMP(out, " baz");
}
+static void test_unescape_eof_terminal(void)
+{
+ char const in[] = "foo, bar";
+ fr_sbuff_t sbuff;
+ ssize_t slen;
+ fr_sbuff_term_t tt_eof = FR_SBUFF_TERMS(
+ L(""),
+ L(","),
+ );
+ fr_sbuff_term_t tt = FR_SBUFF_TERMS(
+ L(",")
+ );
+ char out[100];
+
+ fr_sbuff_init(&sbuff, in, sizeof(in));
+
+ slen = fr_sbuff_out_bstrncpy_until(&FR_SBUFF_OUT(out, sizeof(out)), &sbuff, SIZE_MAX, &tt_eof, NULL);
+ TEST_CHECK(slen == 3);
+ TEST_CHECK_STRCMP(out, "foo");
+
+ fr_sbuff_advance(&sbuff, 1); /* Advance past comma */
+
+ slen = fr_sbuff_out_bstrncpy_until(&FR_SBUFF_OUT(out, sizeof(out)), &sbuff, SIZE_MAX, &tt_eof, NULL);
+ TEST_CHECK(slen == 4);
+ TEST_CHECK_STRCMP(out, " bar");
+
+ TEST_CHECK(fr_sbuff_is_terminal(&sbuff, &tt_eof) == true);
+ TEST_CHECK(fr_sbuff_is_terminal(&sbuff, &tt) == false);
+}
+
static void test_no_advance(void)
{
char const *in = "i am a test string";
{ "fr_sbuff_out_bstrncpy_until", test_bstrncpy_until },
{ "multi-char terminals", test_unescape_multi_char_terminals },
{ "fr_sbuff_out_unescape_until", test_unescape_until },
+ { "fr_sbuff_terminal_eof", test_unescape_eof_terminal },
/*
* Extending buffer