source: trunk/libtransmission/bitfield.c @ 12007

Last change on this file since 12007 was 12007, checked in by jordan, 12 years ago

(trunk libT) remove unused code: tr_bitfieldIsEmpty()

  • Property svn:keywords set to Date Rev Author Id
File size: 4.4 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.c 12007 2011-02-21 15:43:41Z jordan $
11 */
12
13#include <assert.h>
14#include <string.h> /* memset */
15
16#include "transmission.h"
17#include "bitfield.h"
18#include "bitset.h"
19
20tr_bitfield*
21tr_bitfieldConstruct( tr_bitfield * b, size_t bitCount )
22{
23    b->bitCount = bitCount;
24    b->byteCount = ( bitCount + 7u ) / 8u;
25    b->bits = tr_new0( uint8_t, b->byteCount );
26    return b;
27}
28
29tr_bitfield*
30tr_bitfieldDestruct( tr_bitfield * b )
31{
32    if( b )
33        tr_free( b->bits );
34    return b;
35}
36
37tr_bitfield*
38tr_bitfieldDup( const tr_bitfield * in )
39{
40    tr_bitfield * ret = tr_new0( tr_bitfield, 1 );
41
42    ret->bitCount = in->bitCount;
43    ret->byteCount = in->byteCount;
44    ret->bits = tr_memdup( in->bits, in->byteCount );
45    return ret;
46}
47
48void
49tr_bitfieldClear( tr_bitfield * bitfield )
50{
51    memset( bitfield->bits, 0, bitfield->byteCount );
52}
53
54int
55tr_bitfieldAdd( tr_bitfield * bitfield,
56                size_t        nth )
57{
58    assert( bitfield );
59    assert( bitfield->bits );
60
61    if( nth >= bitfield->bitCount )
62        return -1;
63
64    bitfield->bits[nth >> 3u] |= ( 0x80 >> ( nth & 7u ) );
65    return 0;
66}
67
68/* Sets bit range [begin, end) to 1 */
69int
70tr_bitfieldAddRange( tr_bitfield * b,
71                     size_t        begin,
72                     size_t        end )
73{
74    size_t        sb, eb;
75    unsigned char sm, em;
76
77    end--;
78
79    if( ( end >= b->bitCount ) || ( begin > end ) )
80        return -1;
81
82    sb = begin >> 3;
83    sm = ~( 0xff << ( 8 - ( begin & 7 ) ) );
84    eb = end >> 3;
85    em = 0xff << ( 7 - ( end & 7 ) );
86
87    if( sb == eb )
88    {
89        b->bits[sb] |= ( sm & em );
90    }
91    else
92    {
93        b->bits[sb] |= sm;
94        b->bits[eb] |= em;
95        if( ++sb < eb )
96            memset ( b->bits + sb, 0xff, eb - sb );
97    }
98
99    return 0;
100}
101
102int
103tr_bitfieldRem( tr_bitfield * bitfield,
104                size_t        nth )
105{
106    assert( bitfield );
107    assert( bitfield->bits );
108
109    if( nth >= bitfield->bitCount )
110        return -1;
111
112    bitfield->bits[nth >> 3u] &= ( 0xff7f >> ( nth & 7u ) );
113    return 0;
114}
115
116/* Clears bit range [begin, end) to 0 */
117int
118tr_bitfieldRemRange( tr_bitfield * b,
119                     size_t        begin,
120                     size_t        end )
121{
122    size_t        sb, eb;
123    unsigned char sm, em;
124
125    end--;
126
127    if( ( end >= b->bitCount ) || ( begin > end ) )
128        return -1;
129
130    sb = begin >> 3;
131    sm = 0xff << ( 8 - ( begin & 7 ) );
132    eb = end >> 3;
133    em = ~( 0xff << ( 7 - ( end & 7 ) ) );
134
135    if( sb == eb )
136    {
137        b->bits[sb] &= ( sm | em );
138    }
139    else
140    {
141        b->bits[sb] &= sm;
142        b->bits[eb] &= em;
143        if( ++sb < eb )
144            memset ( b->bits + sb, 0, eb - sb );
145    }
146
147    return 0;
148}
149
150tr_bitfield*
151tr_bitfieldOr( tr_bitfield * a, const tr_bitfield * b )
152{
153    uint8_t * ait = a->bits;
154    const uint8_t * aend = ait + a->byteCount;
155    const uint8_t * bit = b->bits;
156    const uint8_t * bend = bit + b->byteCount;
157
158    while( ait!=aend && bit!=bend )
159        *ait++ |= *bit++;
160
161    return a;
162}
163
164size_t
165tr_bitfieldCountTrueBits( const tr_bitfield* b )
166{
167    size_t           ret = 0;
168    const uint8_t *  it, *end;
169    static const int trueBitCount[256] = {
170        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
171        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
172        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
173        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
174        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
175        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
176        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
177        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
178    };
179
180    if( !b )
181        return 0;
182
183    for( it = b->bits, end = it + b->byteCount; it != end; ++it )
184        ret += trueBitCount[*it];
185
186    return ret;
187}
Note: See TracBrowser for help on using the repository browser.