source: trunk/libtransmission/bitfield.h @ 12921

Last change on this file since 12921 was 12921, checked in by jordan, 10 years ago

(trunk libt) in tr_bitfieldSetRaw(), add a `bounded' argument for cases where we know how large the final bitfield will be. This can be used ensure that the excess bits at the end of the array are zeroed out and safe for bitfield.c's countArray() function.

  • Property svn:keywords set to Date Rev Author Id
File size: 2.5 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: bitfield.h 12921 2011-09-26 22:50:42Z jordan $
11 */
12
13#ifndef __TRANSMISSION__
14 #error only libtransmission should #include this header.
15#endif
16
17#ifndef TR_BITFIELD_H
18#define TR_BITFIELD_H 1
19
20#include "transmission.h"
21
22/** @brief Implementation of the BitTorrent spec's Bitfield array of bits */
23typedef struct tr_bitfield
24{
25    uint8_t *  bits;
26    size_t     alloc_count;
27
28    size_t     bit_count;
29
30    size_t     true_count;
31
32    /* Special cases for when full or empty but we don't know the bitCount.
33       This occurs when a magnet link's peers send have all / have none */
34    bool       have_all_hint;
35    bool       have_none_hint;
36}
37tr_bitfield;
38
39/***
40****
41***/
42
43void   tr_bitfieldSetHasAll( tr_bitfield* );
44
45void   tr_bitfieldSetHasNone( tr_bitfield* );
46
47void   tr_bitfieldAdd( tr_bitfield*, size_t bit );
48
49void   tr_bitfieldRem( tr_bitfield*, size_t bit );
50
51void   tr_bitfieldAddRange( tr_bitfield*, size_t begin, size_t end );
52
53void   tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
54
55/***
56****  life cycle
57***/
58
59extern const tr_bitfield TR_BITFIELD_INIT;
60
61void   tr_bitfieldConstruct( tr_bitfield*, size_t bit_count );
62
63static inline void
64tr_bitfieldDestruct( tr_bitfield * b )
65{
66    tr_bitfieldSetHasNone( b );
67}
68
69/***
70****
71***/
72
73void   tr_bitfieldSetFromFlags( tr_bitfield*, const bool * bytes, size_t n );
74
75void   tr_bitfieldSetFromBitfield( tr_bitfield*, const tr_bitfield* );
76
77void   tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count, bool bounded );
78
79void*  tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count );
80
81/***
82****
83***/
84
85size_t  tr_bitfieldCountRange( const tr_bitfield*, size_t begin, size_t end );
86
87size_t  tr_bitfieldCountTrueBits( const tr_bitfield * b );
88
89static inline bool
90tr_bitfieldHasAll( const tr_bitfield * b )
91{
92    return b->bit_count ? ( b->true_count == b->bit_count ) : b->have_all_hint;
93}
94
95static inline bool
96tr_bitfieldHasNone( const tr_bitfield * b )
97{
98    return b->bit_count ? ( b->true_count == 0 ) : b->have_none_hint;
99}
100
101static inline bool
102tr_bitfieldHas( const tr_bitfield * b, size_t n )
103{
104    if( tr_bitfieldHasAll( b ) ) return true;
105    if( tr_bitfieldHasNone( b ) ) return false;
106    if( n>>3u >= b->alloc_count ) return false;
107    return ( b->bits[n>>3u] << ( n & 7u ) & 0x80 ) != 0;
108}
109
110#endif
Note: See TracBrowser for help on using the repository browser.