tin  2.6.1
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.6.1.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-2022 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 */