home *** CD-ROM | disk | FTP | other *** search
/ Chip 2006 June / CHIP 2006-06.2.iso / program / freeware / Democracy-0.8.2.exe / xulrunner / python / BitTorrent / bitfield.py < prev    next >
Encoding:
Python Source  |  2006-04-10  |  2.5 KB  |  78 lines

  1. # The contents of this file are subject to the BitTorrent Open Source License
  2. # Version 1.0 (the License).  You may not copy or use this file, in either
  3. # source code or executable form, except in compliance with the License.  You
  4. # may obtain a copy of the License at http://www.bittorrent.com/license/.
  5. #
  6. # Software distributed under the License is distributed on an AS IS basis,
  7. # WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
  8. # for the specific language governing rights and limitations under the
  9. # License.
  10.  
  11. # Written by Bram Cohen, Uoti Urpala, and John Hoffman
  12.  
  13. from array import array
  14.  
  15. from BitTorrent.obsoletepythonsupport import *
  16.  
  17. counts = [chr(sum([(i >> j) & 1 for j in xrange(8)])) for i in xrange(256)]
  18. counts = ''.join(counts)
  19.  
  20.  
  21. class Bitfield:
  22.  
  23.     def __init__(self, length, bitstring=None):
  24.         self.length = length
  25.         rlen, extra = divmod(length, 8)
  26.         if bitstring is None:
  27.             self.numfalse = length
  28.             if extra:
  29.                 self.bits = array('B', chr(0) * (rlen + 1))
  30.             else:
  31.                 self.bits = array('B', chr(0) * rlen)
  32.         else:
  33.             if extra:
  34.                 if len(bitstring) != rlen + 1:
  35.                     raise ValueError
  36.                 if (ord(bitstring[-1]) << extra) & 0xFF != 0:
  37.                     raise ValueError
  38.             else:
  39.                 if len(bitstring) != rlen:
  40.                     raise ValueError
  41.             c = counts
  42.             self.numfalse = length - sum(array('B',
  43.                                                bitstring.translate(counts)))
  44.             if self.numfalse != 0:
  45.                 self.bits = array('B', bitstring)
  46.             else:
  47.                 self.bits = None
  48.  
  49.     def __setitem__(self, index, val):
  50.         assert val
  51.         pos = index >> 3
  52.         mask = 128 >> (index & 7)
  53.         if self.bits[pos] & mask:
  54.             return
  55.         self.bits[pos] |= mask
  56.         self.numfalse -= 1
  57.         if self.numfalse == 0:
  58.             self.bits = None
  59.  
  60.     def __getitem__(self, index):
  61.         bits = self.bits
  62.         if bits is None:
  63.             return 1
  64.         return bits[index >> 3] & 128 >> (index & 7)
  65.  
  66.     def __len__(self):
  67.         return self.length
  68.  
  69.     def tostring(self):
  70.         if self.bits is None:
  71.             rlen, extra = divmod(self.length, 8)
  72.             r = chr(0xFF) * rlen
  73.             if extra:
  74.                 r += chr((0xFF << (8 - extra)) & 0xFF)
  75.             return r
  76.         else:
  77.             return self.bits.tostring()
  78.