Browse Source

2009-04-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	
	Fixed the bug that prevents torrent download from finishing.
	The bug doesn't reveal for all torrents. The torrents affected
	this bug satisfies ((N+7)/8)%4 == 0 and N%32 != 0 where N is the
	number of pieces.	
	* src/bitfield.h
	* test/bitfieldTest.cc
Tatsuhiro Tsujikawa 16 years ago
parent
commit
35763a2ae0
3 changed files with 27 additions and 10 deletions
  1. 10 0
      ChangeLog
  2. 6 5
      src/bitfield.h
  3. 11 5
      test/bitfieldTest.cc

+ 10 - 0
ChangeLog

@@ -1,3 +1,13 @@
+2009-04-25  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	
+	Fixed the bug that prevents torrent download from finishing.  The
+	bug doesn't reveal for all torrents. The torrents affected this
+	bug satisfies ((N+7)/8)%4 == 0 and N%32 != 0 where N is the number
+	of pieces.	
+	* src/bitfield.h
+	* test/bitfieldTest.cc
+
 2009-04-24  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Code cleanup

+ 6 - 5
src/bitfield.h

@@ -97,17 +97,18 @@ inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
   size_t count = 0;
   size_t size = sizeof(uint32_t);
   size_t len = (nbits+7)/8;
+  if(nbits%32 != 0) {
+    --len;
+    count +=
+      countBit32(static_cast<uint32_t>(bitfield[len]&lastByteMask(nbits)));
+  }
   size_t to = len/size;
   for(size_t i = 0; i < to; ++i) {
     count += countBit32(*reinterpret_cast<const uint32_t*>(&bitfield[i*size]));
   }
-  for(size_t i = len-len%size; i < len-1; ++i) {
+  for(size_t i = len-len%size; i < len; ++i) {
     count += countBit32(static_cast<uint32_t>(bitfield[i]));
   }
-  if(nbits%32 != 0) {
-    count +=
-      countBit32(static_cast<uint32_t>(bitfield[len-1]&lastByteMask(nbits)));
-  }
   return count;
 }
 

+ 11 - 5
test/bitfieldTest.cc

@@ -40,11 +40,17 @@ void bitfieldTest::testCountBit32()
 
 void bitfieldTest::testCountSetBit()
 {
-  unsigned char bitfield[] = { 0xff, 0xff, 0xff, 0xf0, 0xff, 0x01 };
-
-  CPPUNIT_ASSERT_EQUAL((size_t)37, bitfield::countSetBit(bitfield, 48));
-  CPPUNIT_ASSERT_EQUAL((size_t)36, bitfield::countSetBit(bitfield, 47));
-  CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
+  unsigned char bitfield[] = { 0xff, 0xff, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xf9 };
+  // (nbits+7)/8 == 0 && nbits%32 == 0
+  CPPUNIT_ASSERT_EQUAL((size_t)62, bitfield::countSetBit(bitfield, 64));
+  // (nbits+7)/8 != 0 && nbits%32 != 0 && len%4 == 0
+  CPPUNIT_ASSERT_EQUAL((size_t)56, bitfield::countSetBit(bitfield, 56));
+  // (nbits+7)/8 != 0 && nbits%32 != 0 && len%4 != 0
+  CPPUNIT_ASSERT_EQUAL((size_t)40, bitfield::countSetBit(bitfield, 40));
+  // (nbits+7)/8 == 0 && nbits%32 != 0
+  CPPUNIT_ASSERT_EQUAL((size_t)61, bitfield::countSetBit(bitfield, 63));
+  // nbts == 0
   CPPUNIT_ASSERT_EQUAL((size_t)0, bitfield::countSetBit(bitfield, 0));
 }