| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- # The contents of this file are subject to the BitTorrent Open Source License
- # Version 1.1 (the License). You may not copy or use this file, in either
- # source code or executable form, except in compliance with the License. You
- # may obtain a copy of the License at http://www.bittorrent.com/license/.
- #
- # Software distributed under the License is distributed on an AS IS basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- # Written by Bram Cohen, Uoti Urpala, and John Hoffman
- from array import array
- #counts = [chr(sum([(i >> j) & 1 for j in xrange(8)])) for i in xrange(256)]
- counts = []
- for i in xrange(256):
- t = 0
- for j in xrange(8):
- t = t + ((i >> j) & 1)
- counts.append(chr(t))
- counts = ''.join(counts)
- class Bitfield:
- def __init__(self, length, bitstring=None):
- self.length = length
- rlen, extra = divmod(length, 8)
- if bitstring is None:
- self.numfalse = length
- if extra:
- self.bits = array('B', chr(0) * (rlen + 1))
- else:
- self.bits = array('B', chr(0) * rlen)
- else:
- if extra:
- if len(bitstring) != rlen + 1:
- raise ValueError("%s != %s" % (len(bitstring), rlen + 1))
- if (ord(bitstring[-1]) << extra) & 0xFF != 0:
- raise ValueError("%s != %s" %
- ((ord(bitstring[-1]) << extra) & 0xFF, 0))
- else:
- if len(bitstring) != rlen:
- raise ValueError("%s != %s" % (len(bitstring), rlen))
- self.numfalse = length - sum(array('B',
- bitstring.translate(counts)))
- if self.numfalse != 0:
- self.bits = array('B', bitstring)
- else:
- self.bits = None
- def __setitem__(self, index, val):
- assert val
- pos = index >> 3
- mask = 128 >> (index & 7)
- if self.bits[pos] & mask:
- return
- self.bits[pos] = self.bits[pos] | mask
- self.numfalse = self.numfalse - 1
- if self.numfalse == 0:
- self.bits = None
- def __getitem__(self, index):
- bits = self.bits
- if bits is None:
- return 1
- return bits[index >> 3] & 128 >> (index & 7)
- def __len__(self):
- return self.length
- def tostring(self):
- if self.bits is None:
- rlen, extra = divmod(self.length, 8)
- r = chr(0xFF) * rlen
- if extra:
- r = r + chr((0xFF << (8 - extra)) & 0xFF)
- return r
- else:
- return self.bits.tostring()
- def __getstate__(self):
- d = {}
- d['length'] = self.length
- d['s'] = self.tostring()
- return d
- def __setstate__(self, d):
- Bitfield.__init__(self, d['length'], d['s'])
- old_Bitfield = Bitfield
- try:
- import BTL.cBitfield
- Bitfield = BTL.cBitfield.Bitfield
- except ImportError:
- pass
|