]> diplodocus.org Git - nmh/blob - sbr/folder_realloc.c
4287f31b71c55344fdfbb2829aacfa169b663cfe
[nmh] / 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 bvector_t *v;
43 size_t old_size = mp->num_msgstats;
44 size_t new_size = hi - lo + 1;
45 size_t i;
46
47 /*
48 * We are just extending (or shrinking) the end of message
49 * status array. So we don't have to move anything and can
50 * just realloc the message status array.
51 */
52
53 for (i = old_size, v = &mp->msgstats[old_size-1]; i > new_size;
54 --i, --v) {
55 bvector_free (*v);
56 }
57 mp->num_msgstats = MSGSTATNUM (lo, hi);
58 mp->msgstats =
59 mh_xrealloc (mp->msgstats, MSGSTATSIZE(mp));
60 for (i = old_size, v = &mp->msgstats[old_size]; i < new_size;
61 ++i, ++v) {
62 *v = bvector_create (0);
63 }
64 } else {
65 /*
66 * We are changing the offset of the message status
67 * array. So we will need to shift everything.
68 */
69 bvector_t *tmpstats, *t;
70 size_t i;
71
72 /* first allocate the new message status space */
73 mp->num_msgstats = MSGSTATNUM (lo, hi);
74 tmpstats = mh_xmalloc (MSGSTATSIZE(mp));
75 for (i = 0, t = tmpstats; i < mp->num_msgstats; ++i, ++t) {
76 *t = bvector_create (0);
77 }
78
79 /* then copy messages status array with shift */
80 if (mp->nummsg > 0) {
81 for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++)
82 bvector_copy (tmpstats[msgnum - lo], msgstat (mp, msgnum));
83 }
84 free(mp->msgstats);
85 mp->msgstats = tmpstats;
86 }
87
88 mp->lowoff = lo;
89 mp->hghoff = hi;
90
91 /*
92 * Clear all the flags for entries outside
93 * the current message range for this folder.
94 */
95 if (mp->nummsg > 0) {
96 for (msgnum = mp->lowoff; msgnum < mp->lowmsg; msgnum++)
97 clear_msg_flags (mp, msgnum);
98 for (msgnum = mp->hghmsg + 1; msgnum <= mp->hghoff; msgnum++)
99 clear_msg_flags (mp, msgnum);
100 } else {
101 /* no messages, so clear entire range */
102 for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++)
103 clear_msg_flags (mp, msgnum);
104 }
105
106 return mp;
107 }