tin  2.4.4
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.4.4.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

newsrc.h
Go to the documentation of this file.
1 /*
2  * Project : tin - a Usenet reader
3  * Module : newsrc.h
4  * Author : I. Lea & R. Skrenta
5  * Created : 1991-04-01
6  * Updated : 2003-11-18
7  * Notes : newsrc bit handling
8  *
9  * Copyright (c) 1997-2020 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pbm.com>
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution.
22  *
23  * 3. Neither the name of the copyright holder nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #ifndef NEWSRC_H
41 #define NEWSRC_H 1
42 
43 /*
44  * The following macros are used to simplify and speed up the
45  * manipulation of the bitmaps in memory which record which articles
46  * are read or unread in each news group.
47  *
48  * Data representation:
49  *
50  * Each bitmap is handled as an array of bytes; the least-significant
51  * bit of the 0th byte is the 0th bit; the most significant bit of
52  * the 0th byte is the 7th bit. Thus, the most-significant bit of the
53  * 128th byte is the 1023rd bit, and in general the mth bit of the nth
54  * byte is considered to be bit (n*8)+m of the map as a whole. Conversely,
55  * the position of bit q in the map is the bit (q & 7) of byte (q >> 3).
56  * A bitmap of b bits will be allocated as ((b+7) >> 3) bytes.
57  *
58  * The routines could be changed to operate on a word-oriented bitmap by
59  * changing the constants used from 8 to 16, 3 to 4, 7 to 15, etc. and
60  * changing the allocate/deallocate routines.
61  *
62  * In the newsrc context, a 0 bit represents an article which is read
63  * or expired; a 1 represents an unread article. The 0th bit corresponds
64  * to the minimum article number for this group, and (max-min+7)/8 bytes
65  * are allocated to the bitmap.
66  *
67  * Constants:
68  *
69  * NBITS = total number of bits per byte;
70  * NMAXBIT = number of bits per byte or word;
71  * NBITPOS = number of bit in NMAXBIT;
72  * NBITSON = byte/word used to set all bits in byte/word to 1;
73  * NBITNEG1 = binary negation of 1, used in constructing masks.
74  *
75  * Macro naming and use:
76  *
77  * The NOFFSET and NBITIDX macro construct the byte and bit indexes in
78  * the map, given a bit number.
79  *
80  * The NSET0 macro sets a bit to binary 0
81  * The NSET1 macro sets a bit to binary 1
82  * The NSETBLK0 macro sets the same bit or bits to binary 0
83  * The NSETBLK1 macro sets the same bit or bits to binary 1
84  * The NTEST macro tests a single bit.
85  * These are used frequently to access the group bitmap.
86  *
87  * NSETBLK0 and NSETBLK1 operate on whole numbers of bytes, and are
88  * mainly useful for initializing complete bitmaps to one state or
89  * another. Both use the memset function, which is assumed to be
90  * optimized for the target architecture. NSETBLK is currently used to
91  * initialize the group bitmap to 1s (unread).
92  *
93  * NSETRNG0 and NSETRNG1 operate on ranges of bits, from a low bit number
94  * to a high bit number (inclusive), and are especially useful for
95  * efficiently setting a contiguous range of bits to one state or another.
96  * NSETRNG0 is currently used on the group bitmap to mark the ranges the
97  * newsrc file says are read or expired.
98  *
99  * The algorithm is this. If the high number is less than the low, then
100  * do nothing (error); if both fall within the same byte, construct a
101  * single mask expressing the range and AND or OR it into the byte; else:
102  * construct a mask for the byte containing the low bit, AND or OR it in;
103  * use memset to fill in the intervening bytes efficiently; then construct
104  * a mask for the byte containing the high bit, and AND or OR this mask
105  * in. Masks are constructed by left-shift of 0xff (to set high-order bits
106  * to 1), negating a left-shift of 0xfe (to set low-order bits to 1), and
107  * the various negations and combinations of the same. This procedure is
108  * complex, but 1 to 2 orders of magnitude faster than a shift inside a
109  * loop for each bit inside a loop for each individual byte.
110  *
111  */
112 #define NBITS 8
113 #define NMAXBIT 7
114 #define NBITPOS 3
115 #define NBITSON 0xff
116 #define NBITNEG1 0xfe
117 #define NOFFSET(b) ((b) >> NBITPOS)
118 #define NBITIDX(b) ((b) & NMAXBIT)
119 
120 #define NBITMASK(beg,end) (unsigned char) ~(((1 << (((NMAXBIT - beg) - (NMAXBIT - end)) + 1)) - 1) << (NMAXBIT - end))
121 
122 #define NTEST(n,b) (n[NOFFSET(b)] & (1 << NBITIDX(b)))
123 
124 #define NSETBLK1(n,i) (memset(n, NBITSON, (size_t) NOFFSET(i) + 1))
125 #define NSETBLK0(n,i) (memset(n, 0, (size_t) NOFFSET(i) + 1))
126 
127 /* dbmalloc checks memset() parameters, so we'll use it to check the assignments */
128 #ifdef USE_DBMALLOC
129 # define NSET1(n,b) memset(n + NOFFSET(b), n[NOFFSET(b)] | NTEST(n,b), 1)
130 # define NSET0(n,b) memset(n + NOFFSET(b), n[NOFFSET(b)] & ~NTEST(n,b), 1)
131 # define BIT_OR(n, b, mask) memset(n + NOFFSET(b), n[NOFFSET(b)] | (mask), 1)
132 # define BIT_AND(n, b, mask) memset(n + NOFFSET(b), n[NOFFSET(b)] & (mask), 1)
133 # include <dbmalloc.h> /* dbmalloc 1.4 */
134 #else
135 # define NSET1(n,b) (n[NOFFSET(b)] |= (1 << NBITIDX(b)))
136 # define NSET0(n,b) (n[NOFFSET(b)] &= ~(1 << NBITIDX(b)))
137 # define BIT_OR(n, b, mask) n[NOFFSET(b)] |= mask
138 # define BIT_AND(n, b, mask) n[NOFFSET(b)] &= mask
139 #endif /* USE_DBMALLOC */
140 
141 #define BITS_TO_BYTES(n) ((size_t) ((n + NBITS - 1) / NBITS))
142 
143 #endif /* !NEWSRC_H */