e7c4bc442bb6955da611d1c99fe72b3d84f6d392
[mmh] / folder_realloc.c
1
2 /*
3  * folder_realloc.c -- realloc a folder/msgs structure
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13 #include <h/utils.h>
14
15 /*
16  * Reallocate some of the space in the folder
17  * structure (currently just message status array).
18  *
19  * Return pointer to new folder structure.
20  * If error, return NULL.
21  */
22
23 struct msgs *
24 folder_realloc (struct msgs *mp, int lo, int hi)
25 {
26     int msgnum;
27
28     /* sanity checks */
29     if (lo < 1)
30         adios (NULL, "BUG: called folder_realloc with lo (%d) < 1", lo);
31     if (hi < 1)
32         adios (NULL, "BUG: called folder_realloc with hi (%d) < 1", hi);
33     if (mp->nummsg > 0 && lo > mp->lowmsg)
34         adios (NULL, "BUG: called folder_realloc with lo (%d) > mp->lowmsg (%d)",
35                lo, mp->lowmsg);
36     if (mp->nummsg > 0 && hi < mp->hghmsg)
37         adios (NULL, "BUG: called folder_realloc with hi (%d) < mp->hghmsg (%d)",
38                hi, mp->hghmsg);
39
40     /* Check if we really need to reallocate anything */
41     if (lo == mp->lowoff && hi == mp->hghoff)
42         return mp;
43
44     if (lo == mp->lowoff) {
45         /*
46          * We are just extending (or shrinking) the end of message
47          * status array.  So we don't have to move anything and can
48          * just realloc the message status array.
49          */
50         mp->msgstats = mh_xrealloc (mp->msgstats, MSGSTATSIZE(mp, lo, hi));
51     } else {
52         /*
53          * We are changing the offset of the message status
54          * array.  So we will need to shift everything.
55          */
56         seqset_t *tmpstats;
57
58         /* first allocate the new message status space */
59         tmpstats = mh_xmalloc (MSGSTATSIZE(mp, lo, hi));
60
61         /* then copy messages status array with shift */
62         if (mp->nummsg > 0) {
63             for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++)
64                 tmpstats[msgnum - lo] = mp->msgstats[msgnum - mp->lowoff];
65         }
66         free(mp->msgstats);
67         mp->msgstats = tmpstats;
68     }
69
70     mp->lowoff = lo;
71     mp->hghoff = hi;
72
73     /*
74      * Clear all the flags for entries outside
75      * the current message range for this folder.
76      */
77     if (mp->nummsg > 0) {
78         for (msgnum = mp->lowoff; msgnum < mp->lowmsg; msgnum++)
79             clear_msg_flags (mp, msgnum);
80         for (msgnum = mp->hghmsg + 1; msgnum <= mp->hghoff; msgnum++)
81             clear_msg_flags (mp, msgnum);
82     } else {
83         /* no messages, so clear entire range */
84         for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++)
85             clear_msg_flags (mp, msgnum);
86     }
87
88     return mp;
89 }