diff options
Diffstat (limited to '')
-rw-r--r-- | archive.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/archive.h b/archive.h index d6b9608..921ae06 100644 --- a/archive.h +++ b/archive.h @@ -218,6 +218,35 @@ char *decodeHeader(const char *header); char *decodeToString(const struct BodyPart *part, const char *content); int decodeToFile(FILE *file, const struct BodyPart *part, const char *content); +static inline uint32_t threadRoot(struct List thread) { + if (!thread.len) errx(EX_PROTOCOL, "empty thread"); + while (thread.ptr[0].type == List) { + thread = thread.ptr[0].list; + if (!thread.len) errx(EX_PROTOCOL, "empty subthread"); + } + return dataCheck(thread.ptr[0], Number).number; +} + +static inline void compressUIDs(FILE *imap, struct List uids) { + uint32_t base = 0, prev = 0; + for (size_t i = 0; i < uids.len; ++i) { + uint32_t uid = uids.ptr[i].type == List + ? threadRoot(uids.ptr[i].list) + : dataCheck(uids.ptr[i], Number).number; + if (!base) { + fprintf(imap, "%" PRIu32, uid); + base = prev = uid; + } else if (uid == prev + 1) { + prev = uid; + } else { + if (prev > base) fprintf(imap, ":%" PRIu32, prev); + fprintf(imap, ",%" PRIu32, uid); + base = prev = uid; + } + } + if (prev > base) fprintf(imap, ":%" PRIu32, prev); +} + bool exportFetch(FILE *imap, enum Atom tag, struct List threads); bool exportData(FILE *imap, enum Atom tag, struct List items); |