source: trunk/libtransmission/bitfield.h @ 12251

Last change on this file since 12251 was 12251, checked in by jordan, 11 years ago

(trunk libT) more completion and bitfield cleanup: (1) fix regression in tr_cpSizeWhenDone() reported by Waldorf, (2) make simple one-liner functions inlined

  • Property svn:keywords set to Date Rev Author Id
File size: 3.1 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 12251 2011-03-29 01:17:18Z 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 <assert.h>
21#include "transmission.h"
22
23/** @brief Implementation of the BitTorrent spec's Bitfield array of bits */
24typedef struct tr_bitfield
25{
26    uint8_t *  bits;
27    size_t     bit_count;
28    size_t     byte_count;
29    size_t     true_count;
30
31    /* Special cases for when full or empty but we don't know the bitCount.
32       This occurs when a magnet link's peers send have all / have none */
33    bool       have_all_hint;
34    bool       have_none_hint;
35}
36tr_bitfield;
37
38/***
39****
40***/
41
42void   tr_bitfieldSetHasAll( tr_bitfield* );
43
44void   tr_bitfieldSetHasNone( tr_bitfield* );
45
46void   tr_bitfieldAdd( tr_bitfield*, size_t bit );
47
48void   tr_bitfieldRem( tr_bitfield*, size_t bit );
49
50void   tr_bitfieldAddRange( tr_bitfield*, size_t begin, size_t end );
51
52void   tr_bitfieldRemRange( tr_bitfield*, size_t begin, size_t end );
53
54/***
55****  life cycle
56***/
57
58extern const tr_bitfield TR_BITFIELD_INIT;
59
60void   tr_bitfieldConstruct( tr_bitfield*, size_t bit_count );
61
62static inline void
63tr_bitfieldDestruct( tr_bitfield * b )
64{
65    tr_bitfieldSetHasNone( b );
66}
67
68/***
69****
70***/
71
72bool   tr_bitfieldSetFromBitfield( tr_bitfield*, const tr_bitfield* );
73
74bool   tr_bitfieldSetRaw( tr_bitfield*, const void * bits, size_t byte_count );
75
76void*  tr_bitfieldGetRaw( const tr_bitfield * b, size_t * byte_count );
77
78/***
79****
80***/
81
82size_t  tr_bitfieldCountRange( const tr_bitfield*, size_t begin, size_t end );
83
84static inline size_t
85tr_bitfieldCountTrueBits( const tr_bitfield * b )
86{
87    assert( b->true_count == tr_bitfieldCountRange( b, 0, b->bit_count ) );
88    return b->true_count;
89}
90
91static inline bool
92tr_bitfieldHasAll( const tr_bitfield * b )
93{
94    return b->bit_count ? ( b->true_count == b->bit_count ) : b->have_all_hint;
95}
96
97static inline bool
98tr_bitfieldHasNone( const tr_bitfield * b )
99{
100    return b->bit_count ? ( b->true_count == 0 ) : b->have_none_hint;
101}
102
103/** A stripped-down version of bitfieldHas to be used
104    for speed when you're looping quickly. This version
105    has none of tr_bitfieldHas()'s safety checks, so you
106    need to call tr_bitfieldTestFast() first before you
107    start looping. */
108static inline bool
109tr_bitfieldHasFast( const tr_bitfield * b, const size_t n )
110{
111    if( tr_bitfieldHasAll( b ) ) return true;
112    if( tr_bitfieldHasNone( b ) ) return false;
113    return ( b->bits[n>>3u] << ( n & 7u ) & 0x80 ) != 0;
114}
115
116/** @param high the highest nth bit you're going to access */
117static inline bool
118tr_bitfieldTestFast( const tr_bitfield * b, const size_t high )
119{
120    return ( b != NULL )
121        && ( high < b->bit_count );
122}
123
124static inline bool
125tr_bitfieldHas( const tr_bitfield * b, size_t n )
126{
127    return tr_bitfieldTestFast( b, n )
128        && tr_bitfieldHasFast( b, n );
129}
130
131#endif
Note: See TracBrowser for help on using the repository browser.