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 111