diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-06-07 23:27:31 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-06-07 23:27:31 +0400 |
commit | a30bb766e8f2bea19e5a8f1739354d5f7894df1d (patch) | |
tree | 5209629a266b6cc007f1e3d24469b70a0a4c6960 /src/Data | |
parent | ec063c9e50aa6f19e82e836a33c10d596f766290 (diff) |
~ Fix bitfield encoding.
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/Bitfield.hs | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/Data/Bitfield.hs b/src/Data/Bitfield.hs index ee0570e7..56365bf7 100644 --- a/src/Data/Bitfield.hs +++ b/src/Data/Bitfield.hs | |||
@@ -17,6 +17,7 @@ module Data.Bitfield | |||
17 | 17 | ||
18 | -- * Construction | 18 | -- * Construction |
19 | , haveAll, haveNone, have | 19 | , haveAll, haveNone, have |
20 | , adjustSize | ||
20 | 21 | ||
21 | -- * Query | 22 | -- * Query |
22 | , Data.Bitfield.null | 23 | , Data.Bitfield.null |
@@ -31,8 +32,7 @@ module Data.Bitfield | |||
31 | , difference | 32 | , difference |
32 | 33 | ||
33 | -- * Serialization | 34 | -- * Serialization |
34 | , getBitfield, putBitfield | 35 | , fromBitmap, toBitmap |
35 | , bitfieldByteCount | ||
36 | 36 | ||
37 | #if defined (TESTING) | 37 | #if defined (TESTING) |
38 | -- * Debug | 38 | -- * Debug |
@@ -42,15 +42,18 @@ module Data.Bitfield | |||
42 | 42 | ||
43 | import Control.Monad | 43 | import Control.Monad |
44 | import Control.Monad.ST | 44 | import Control.Monad.ST |
45 | import Data.ByteString (ByteString) | ||
46 | import qualified Data.ByteString as B | ||
47 | import qualified Data.ByteString.Lazy as Lazy | ||
45 | import Data.Vector.Unboxed (Vector) | 48 | import Data.Vector.Unboxed (Vector) |
46 | import qualified Data.Vector.Unboxed as V | 49 | import qualified Data.Vector.Unboxed as V |
47 | import qualified Data.Vector.Unboxed.Mutable as VM | 50 | import qualified Data.Vector.Unboxed.Mutable as VM |
48 | import Data.IntervalSet (IntSet) | 51 | import Data.IntervalSet (IntSet) |
49 | import qualified Data.IntervalSet as S | 52 | import qualified Data.IntervalSet as S |
53 | import qualified Data.IntervalSet.ByteString as S | ||
50 | import Data.List (foldl') | 54 | import Data.List (foldl') |
51 | import Data.Monoid | 55 | import Data.Monoid |
52 | import Data.Ratio | 56 | import Data.Ratio |
53 | import Data.Serialize | ||
54 | import Network.BitTorrent.PeerWire.Block | 57 | import Network.BitTorrent.PeerWire.Block |
55 | 58 | ||
56 | 59 | ||
@@ -97,6 +100,11 @@ have ix Bitfield {..} | |||
97 | | 0 <= ix && ix < bfSize = Bitfield bfSize (S.insert ix bfSet) | 100 | | 0 <= ix && ix < bfSize = Bitfield bfSize (S.insert ix bfSet) |
98 | | otherwise = Bitfield bfSize bfSet | 101 | | otherwise = Bitfield bfSize bfSet |
99 | 102 | ||
103 | -- | Assign new size to bitfield. FIXME Normally, size should be only | ||
104 | -- decreased, otherwise exception raised. | ||
105 | adjustSize :: PieceCount -> Bitfield -> Bitfield | ||
106 | adjustSize s Bitfield {..} = Bitfield s bfSet | ||
107 | |||
100 | {----------------------------------------------------------------------- | 108 | {----------------------------------------------------------------------- |
101 | Query | 109 | Query |
102 | -----------------------------------------------------------------------} | 110 | -----------------------------------------------------------------------} |
@@ -200,17 +208,22 @@ unions = foldl' union (haveNone 0) | |||
200 | Serialization | 208 | Serialization |
201 | -----------------------------------------------------------------------} | 209 | -----------------------------------------------------------------------} |
202 | 210 | ||
203 | -- | | 211 | -- | Unpack 'Bitfield' from tightly packed bit array. Note resulting |
204 | getBitfield :: Int -> Get Bitfield | 212 | -- size might be more than real bitfield size, use 'adjustSize'. |
205 | getBitfield = error "getBitfield" | 213 | fromBitmap :: ByteString -> Bitfield |
206 | 214 | fromBitmap bs = Bitfield { | |
207 | -- | | 215 | bfSize = B.length bs * 8 |
208 | putBitfield :: Bitfield -> Put | 216 | , bfSet = S.fromByteString bs |
209 | putBitfield = error "putBitfield" | 217 | } |
218 | {-# INLINE fromBitmap #-} | ||
210 | 219 | ||
211 | -- | | 220 | -- | Pack a 'Bitfield' to tightly packed bit array. |
212 | bitfieldByteCount :: Bitfield -> Int | 221 | toBitmap :: Bitfield -> Lazy.ByteString |
213 | bitfieldByteCount = error "bitfieldByteCount" | 222 | toBitmap Bitfield {..} = Lazy.fromChunks [intsetBM, alignment] |
223 | where | ||
224 | byteSize = bfSize `div` 8 + if bfSize `mod` 8 == 0 then 0 else 1 | ||
225 | alignment = B.replicate (byteSize - B.length intsetBM) 0 | ||
226 | intsetBM = S.toByteString bfSet | ||
214 | 227 | ||
215 | {----------------------------------------------------------------------- | 228 | {----------------------------------------------------------------------- |
216 | Debug | 229 | Debug |