/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "array.h"
#include "imap-seqset.h"
static uint32_t get_next_number(const char **str)
return 0;
}
+int imap_seq_set_ordered_parse(const char *str, ARRAY_TYPE(uint32_t) *dest)
+{
+ uint32_t seq1, seq2;
+
+ for (;;) {
+ seq1 = get_next_number(&str);
+ if (seq1 == 0)
+ return -1;
+ if (*str != ':')
+ seq2 = seq1;
+ else {
+ str++;
+ seq2 = get_next_number(&str);
+ if (seq2 == 0)
+ return -1;
+ }
+ if (seq1 > seq2)
+ return -1;
+
+ for (uint32_t seq = seq1; seq <= seq2; seq++)
+ array_push_back(dest, &seq);
+
+ if (*str == '\0')
+ break;
+ if (*str != ',')
+ return -1;
+ str++;
+ }
+ return 0;
+}
+
int imap_seq_range_parse(const char *str, uint32_t *seq1_r, uint32_t *seq2_r)
{
if (get_next_seq_range(&str, seq1_r, seq2_r) < 0)
int imap_seq_set_parse(const char *str, ARRAY_TYPE(seq_range) *dest);
/* Like imap_seq_set_parse(), but fail if '*' is used. */
int imap_seq_set_nostar_parse(const char *str, ARRAY_TYPE(seq_range) *dest);
+/* Parse IMAP sequence-set where the order of the sequences matter, such as
+ ESORT response. */
+int imap_seq_set_ordered_parse(const char *str, ARRAY_TYPE(uint32_t) *dest);
/* Parse IMAP seq-number / seq-range. */
int imap_seq_range_parse(const char *str, uint32_t *seq1_r, uint32_t *seq2_r);
test_end();
}
+static void test_imap_seq_set_ordered_parse(void)
+{
+ static const struct {
+ const char *input;
+ const char *output;
+ int ret;
+ } tests[] = {
+ { "", "", -1 },
+ { "0", "", -1 },
+ { "1,", "", -1 },
+ { "1:", "", -1 },
+ { ":1", "", -1 },
+ { "0:1", "", -1 },
+ { "*", "", -1 },
+ { "1:*", "", -1 },
+ { "1", "1", 0 },
+ { "3:4,1:2,5,700,500:503", "3 4 1 2 5 700 500 501 502 503", 0 },
+ };
+ ARRAY_TYPE(uint32_t) dest;
+ string_t *str = t_str_new(64);
+
+ test_begin("imap_seq_set_ordered_parse()");
+
+ t_array_init(&dest, 8);
+ for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
+ array_clear(&dest);
+ int ret = imap_seq_set_ordered_parse(tests[i].input, &dest);
+ test_assert_idx(ret == tests[i].ret, i);
+ if (ret == 0) {
+ str_truncate(str, 0);
+ const uint32_t *seqp;
+ array_foreach(&dest, seqp)
+ str_printfa(str, " %u", *seqp);
+ test_assert_strcmp_idx(str_c(str) + 1, tests[i].output, i);
+ }
+ }
+ test_end();
+}
+
int main(void)
{
static void (*const test_functions[])(void) = {
test_imap_seq_set_parse,
test_imap_seq_set_nostar_parse,
test_imap_seq_range_parse,
+ test_imap_seq_set_ordered_parse,
NULL
};
return test_run(test_functions);