1 /*
2  * This file Copyright (C) 2008-2014 Mnemosyne LLC
3  *
4  * It may be used under the GNU GPL versions 2 or 3
5  * or any future license endorsed by Mnemosyne LLC.
6  *
7  */
8 
9 #pragma once
10 
11 #ifndef __TRANSMISSION__
12 #error only libtransmission should #include this header.
13 #endif
14 
15 #include "transmission.h"
16 
17 /** @brief Implementation of the BitTorrent spec's Bitfield array of bits */
18 typedef struct tr_bitfield
19 {
20     uint8_t* bits;
21     size_t alloc_count;
22 
23     size_t bit_count;
24 
25     size_t true_count;
26 
27     /* Special cases for when full or empty but we don't know the bitCount.
28        This occurs when a magnet link's peers send have all / have none */
29     bool have_all_hint;
30     bool have_none_hint;
31 }
32 tr_bitfield;
33 
34 /***
35 ****
36 ***/
37 
38 void tr_bitfieldSetHasAll(tr_bitfield*);
39 
40 void tr_bitfieldSetHasNone(tr_bitfield*);
41 
42 void tr_bitfieldAdd(tr_bitfield*, size_t bit);
43 
44 void tr_bitfieldRem(tr_bitfield*, size_t bit);
45 
46 void tr_bitfieldAddRange(tr_bitfield*, size_t begin, size_t end);
47 
48 void tr_bitfieldRemRange(tr_bitfield*, size_t begin, size_t end);
49 
50 /***
51 ****  life cycle
52 ***/
53 
54 extern tr_bitfield const TR_BITFIELD_INIT;
55 
56 void tr_bitfieldConstruct(tr_bitfield*, size_t bit_count);
57 
tr_bitfieldDestruct(tr_bitfield * b)58 static inline void tr_bitfieldDestruct(tr_bitfield* b)
59 {
60     tr_bitfieldSetHasNone(b);
61 }
62 
63 /***
64 ****
65 ***/
66 
67 void tr_bitfieldSetFromFlags(tr_bitfield*, bool const* bytes, size_t n);
68 
69 void tr_bitfieldSetFromBitfield(tr_bitfield*, tr_bitfield const*);
70 
71 void tr_bitfieldSetRaw(tr_bitfield*, void const* bits, size_t byte_count, bool bounded);
72 
73 void* tr_bitfieldGetRaw(tr_bitfield const* b, size_t* byte_count);
74 
75 /***
76 ****
77 ***/
78 
79 size_t tr_bitfieldCountRange(tr_bitfield const*, size_t begin, size_t end);
80 
81 size_t tr_bitfieldCountTrueBits(tr_bitfield const* b);
82 
tr_bitfieldHasAll(tr_bitfield const * b)83 static inline bool tr_bitfieldHasAll(tr_bitfield const* b)
84 {
85     return b->bit_count != 0 ? (b->true_count == b->bit_count) : b->have_all_hint;
86 }
87 
tr_bitfieldHasNone(tr_bitfield const * b)88 static inline bool tr_bitfieldHasNone(tr_bitfield const* b)
89 {
90     return b->bit_count != 0 ? (b->true_count == 0) : b->have_none_hint;
91 }
92 
93 bool tr_bitfieldHas(tr_bitfield const* b, size_t n);
94