summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Paul Weber <singpolyma@singpolyma.net>2012-09-11 11:34:49 -0500
committerStephen Paul Weber <singpolyma@singpolyma.net>2012-09-11 11:34:49 -0500
commita595481760fe5c4dc2e970a3a164ac12d4005d73 (patch)
tree927efcc32372ff4697a469149159b782f2c3d692
parent2be234f7a2db4880ea7f66c58d93539c18ddc81e (diff)
Better bit counting. Handle the bitlength of 0
Closes #17
-rw-r--r--Data/OpenPGP.hs15
1 files changed, 10 insertions, 5 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index 70bd29a..a268dff 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -62,6 +62,7 @@ module Data.OpenPGP (
62 62
63import Numeric 63import Numeric
64import Control.Monad 64import Control.Monad
65import Control.Arrow
65import Control.Exception (assert) 66import Control.Exception (assert)
66import Data.Bits 67import Data.Bits
67import Data.Word 68import Data.Word
@@ -790,19 +791,23 @@ signatures_and_data (Message lst) =
790newtype MPI = MPI Integer deriving (Show, Read, Eq, Ord) 791newtype MPI = MPI Integer deriving (Show, Read, Eq, Ord)
791instance BINARY_CLASS MPI where 792instance BINARY_CLASS MPI where
792 put (MPI i) = do 793 put (MPI i) = do
793 put (((fromIntegral . B.length $ bytes) - 1) * 8 794 put (bitl :: Word16)
794 + floor (logBase (2::Double) $ fromIntegral (bytes `B.index` 0))
795 + 1 :: Word16)
796 putSomeByteString bytes 795 putSomeByteString bytes
797 where 796 where
798 bytes = if B.null bytes' then B.singleton 0 else bytes' 797 (bytes, bitl)
798 | B.null bytes' = (B.singleton 0, 1)
799 | otherwise =
800 (bytes', (fromIntegral (B.length bytes') - 1) * 8 + sigBit)
801
802 sigBit = fst $ until ((==0) . snd)
803 (first (+1) . second (`shiftR` 1)) (0,B.index bytes 0)
799 bytes' = B.reverse $ B.unfoldr (\x -> 804 bytes' = B.reverse $ B.unfoldr (\x ->
800 if x == 0 then Nothing else 805 if x == 0 then Nothing else
801 Just (fromIntegral x, x `shiftR` 8) 806 Just (fromIntegral x, x `shiftR` 8)
802 ) (assertProp (>=0) i) 807 ) (assertProp (>=0) i)
803 get = do 808 get = do
804 length <- fmap fromIntegral (get :: Get Word16) 809 length <- fmap fromIntegral (get :: Get Word16)
805 bytes <- getSomeByteString ((length + 7) `div` 8) 810 bytes <- getSomeByteString (assertProp (>0) $ (length + 7) `div` 8)
806 return (MPI (B.foldl (\a b -> 811 return (MPI (B.foldl (\a b ->
807 a `shiftL` 8 .|. fromIntegral b) 0 bytes)) 812 a `shiftL` 8 .|. fromIntegral b) 0 bytes))
808 813