1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2007, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
37
#ifndef LIBTORRENT_BITFIELD_H
38
#define LIBTORRENT_BITFIELD_H
41
#include <torrent/common.h>
45
class LIBTORRENT_EXPORT Bitfield {
47
typedef uint32_t size_type;
48
typedef uint8_t value_type;
49
typedef const uint8_t const_value_type;
50
typedef value_type* iterator;
51
typedef const value_type* const_iterator;
53
Bitfield() : m_size(0), m_set(0), m_data(NULL) {}
54
~Bitfield() { clear(); }
56
bool empty() const { return m_data == NULL; }
58
bool is_all_set() const { return m_set == m_size; }
59
bool is_all_unset() const { return m_set == 0; }
61
bool is_tail_cleared() const { return m_size % 8 == 0 || !((*(end() - 1) & mask_from(m_size % 8))); }
63
size_type size_bits() const { return m_size; }
64
size_type size_bytes() const { return (m_size + 7) / 8; }
66
size_type size_set() const { return m_set; }
67
size_type size_unset() const { return m_size - m_set; }
69
void set_size_bits(size_type s);
70
void set_size_set(size_type s);
72
// Call update if you've changed the data directly and want to
73
// update the counters and unset the last unused bits.
75
// Resize clears the data?
78
void allocate() { if (m_data == NULL) m_data = new value_type[size_bytes()]; }
79
void unallocate() { delete [] m_data; m_data = NULL; }
81
void clear() { unallocate(); m_size = 0; m_set = 0; }
82
void clear_tail() { if (m_size % 8) *(end() - 1) &= mask_before(m_size % 8); }
84
void copy(const Bitfield& bf);
85
void swap(Bitfield& bf);
88
void set_range(size_type first, size_type last);
91
void unset_range(size_type first, size_type last);
93
bool get(size_type idx) const { return m_data[idx / 8] & mask_at(idx % 8); }
95
void set(size_type idx) { m_set += !get(idx); m_data[idx / 8] |= mask_at(idx % 8); }
96
void unset(size_type idx) { m_set -= get(idx); m_data[idx / 8] &= ~mask_at(idx % 8); }
98
iterator begin() { return m_data; }
99
const_iterator begin() const { return m_data; }
100
iterator end() { return m_data + size_bytes(); }
101
const_iterator end() const { return m_data + size_bytes(); }
103
size_type position(const_iterator itr) const { return (itr - m_data) * 8; }
105
void from_c_str(const char* str) { std::memcpy(m_data, str, size_bytes()); update(); }
107
// Remember to use modulo.
108
static value_type mask_at(size_type idx) { return 1 << (7 - idx); }
109
static value_type mask_before(size_type idx) { return (value_type)~0 << (8 - idx); }
110
static value_type mask_from(size_type idx) { return (value_type)~0 >> idx; }
113
Bitfield(const Bitfield& bf);
114
Bitfield& operator = (const Bitfield& bf);