aboutsummaryrefslogtreecommitdiffstats
path: root/uid_db.h
blob: f76f740f11180dec5a7ec504c18f8d8e565327e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
  POP3 UID database

	Copyright (c) 2010 MAD Partners, Ltd. (rweikusat@mssgmbh.com)

	This file is being published in accordance with the GPLv2 terms
	contained in the COPYING file being part of the fetchmail
	6.3.17 release, including the OpenSSL exemption.
*/
#ifndef fetchmail_uid_db_h
#define fetchmail_uid_db_h

/*  includes */
#include <stddef.h>

/*  types */
struct uid_db_record {
    char *id;
    size_t id_len;

    /*
      num	-	message number assigned by server
      status	-	message status (eg seen, deleted, ...)
      pos	-	position in record list
    */
    unsigned num, status, pos;

    struct uid_db_record *next;
};

struct num_ndx {
    /*
      Used to find uid records by message number.

      pos_0_value	-	highest message number
      end_value		-	lowest known message number

      Grows downwards because the fastuidl-code may record
      message numbers in non-ascending order but the
      lookup array should ideally only be large enough to
      store pointers to interesting ('new') messages.
    */
    struct uid_db_record **records;
    unsigned pos_0_value, end_value;
};

struct uid_db
{
    struct pat_node *pat_root;

    struct uid_db_record **records;
    unsigned records_max, records_next;

    struct num_ndx num_ndx;
};

typedef int uid_db_traversal_routine(struct uid_db_record *, void *);

/*  routines */
/**  initialization/ finalization */
void init_uid_db(struct uid_db *db);

void free_uid_db(struct uid_db *db);

static inline void clear_uid_db(struct uid_db *db)
{
    free_uid_db(db);
    init_uid_db(db);
}

/**  message number index handling */
static inline unsigned uid_db_num_ofs(struct num_ndx const *num_ndx, unsigned num)
{
    return num_ndx->pos_0_value - num;
}

void set_uid_db_num(struct uid_db *db, struct uid_db_record *rec,
		    unsigned num);

static inline void set_uid_db_num_pos_0(struct uid_db *db, unsigned num)
{
    db->num_ndx.pos_0_value = num;
    db->num_ndx.end_value = num + 1;
}

void reset_uid_db_nums(struct uid_db *db);

/**  various uidl db manipulatiors */
struct uid_db_record *uid_db_insert(struct uid_db *db,
				    char const *id, unsigned status);

void swap_uid_db_data(struct uid_db *db_0, struct uid_db *db_1);

/**  search routines */
struct uid_db_record *find_uid_by_id(struct uid_db *db, char const *id);

static inline struct uid_db_record *
find_uid_by_num(struct uid_db *db, unsigned num)
{
    struct num_ndx *num_ndx;

    num_ndx = &db->num_ndx;
    return num >= num_ndx->end_value ?
	num_ndx->records[uid_db_num_ofs(num_ndx, num)] : NULL;
}

static inline struct uid_db_record *
find_uid_by_pos(struct uid_db *db, unsigned pos)
{
    return pos < db->records_next ? db->records[pos] : NULL;
}

static inline struct uid_db_record *
first_uid_in_db(struct uid_db *db, char const *id)
{
    return find_uid_by_id(db, id);
}

struct uid_db_record *last_uid_in_db(struct uid_db *db, char const *id);

/**  various accessors */
static inline unsigned uid_db_n_records(struct uid_db const *db)
{
    return db->records_next;
}

/*
  Traverses the struct uid_db records array in insert order,
  invoking the subroutine pointed to by r with a pointer to
  each record and the arg pointer as arguments. If the return
  value of that is non-zero, traverse_uid_db immediately returns
  with this value. Otherwise, zero is returned after the last
  record was visited.

  The uid_db_traversal_routine must not modify the uid_db during
  traversal.
*/
int traverse_uid_db(struct uid_db *db,
		    uid_db_traversal_routine *r, void *arg);

#endif