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
pull/1/head
Tatsuhiro Tsujikawa 2009-04-25 10:30:25 +00:00
parent ea8668d80f
commit 35763a2ae0
3 changed files with 27 additions and 10 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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));
}