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