summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClint Adams <clint@debian.org>2012-04-26 19:34:16 -0400
committerClint Adams <clint@debian.org>2012-04-26 19:34:16 -0400
commit1ddca48c27cece9352e85ce6188f697eb9124750 (patch)
tree2fd164848c8ba34180c27a843cb69ab720469c24
parent716dd382221343e5da5daf1a9a8ac40304a7d74b (diff)
Introduce some lazy bytestrings internally.
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs16
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs5
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs10
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs2
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs7
-rw-r--r--tests/suite.hs18
6 files changed, 36 insertions, 22 deletions
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
index b0033a8..b89fbfa 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
@@ -18,6 +18,7 @@ import Data.Attoparsec.Combinator (manyTill)
18import Data.Bits (shiftL) 18import Data.Bits (shiftL)
19import Data.ByteString (ByteString) 19import Data.ByteString (ByteString)
20import qualified Data.ByteString as B 20import qualified Data.ByteString as B
21import qualified Data.ByteString.Lazy as BL
21import qualified Data.ByteString.Char8 as BC8 22import qualified Data.ByteString.Char8 as BC8
22import qualified Data.ByteString.Base64 as Base64 23import qualified Data.ByteString.Base64 as Base64
23import Data.Digest.CRC24 (crc24) 24import Data.Digest.CRC24 (crc24)
@@ -48,7 +49,7 @@ clearsigned = do
48 blankishLine <?> "blank line" 49 blankishLine <?> "blank line"
49 cleartext <- dashEscapedCleartext 50 cleartext <- dashEscapedCleartext
50 sig <- armor 51 sig <- armor
51 return $ ClearSigned headers cleartext sig 52 return $ ClearSigned headers (BL.fromChunks [cleartext]) sig
52 53
53armor :: Parser Armor 54armor :: Parser Armor
54armor = do 55armor = do
@@ -57,7 +58,7 @@ armor = do
57 blankishLine <?> "blank line" 58 blankishLine <?> "blank line"
58 payload <- base64Data <?> "base64 data" 59 payload <- base64Data <?> "base64 data"
59 endLine atype <?> "end line" 60 endLine atype <?> "end line"
60 return $ Armor atype headers payload 61 return $ Armor atype headers (BL.fromChunks [payload])
61 62
62beginLine :: Parser ArmorType 63beginLine :: Parser ArmorType
63beginLine = do 64beginLine = do
@@ -77,8 +78,8 @@ beginLine = do
77 firstnum <- num 78 firstnum <- num
78 word8 (fromIntegral . fromEnum $ '/') 79 word8 (fromIntegral . fromEnum $ '/')
79 secondnum <- num 80 secondnum <- num
80 return $ ArmorSplitMessage (B.pack firstnum) (B.pack secondnum) 81 return $ ArmorSplitMessage (BL.pack firstnum) (BL.pack secondnum)
81 partsindef = ArmorSplitMessageIndefinite . B.pack <$> num 82 partsindef = ArmorSplitMessageIndefinite . BL.pack <$> num
82 num = many1 (satisfy isDigit_w8) <?> "number" 83 num = many1 (satisfy isDigit_w8) <?> "number"
83 84
84lineEnding :: Parser ByteString 85lineEnding :: Parser ByteString
@@ -109,10 +110,13 @@ aType :: ArmorType -> ByteString
109aType (ArmorMessage) = BC8.pack "MESSAGE" 110aType (ArmorMessage) = BC8.pack "MESSAGE"
110aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK" 111aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK"
111aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK" 112aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK"
112aType (ArmorSplitMessage x y) = BC8.pack "MESSAGE, PART " `B.append` x `B.append` BC8.singleton '/' `B.append` y 113aType (ArmorSplitMessage x y) = BC8.pack "MESSAGE, PART " `B.append` (l2s x) `B.append` BC8.singleton '/' `B.append` (l2s y)
113aType (ArmorSplitMessageIndefinite x) = BC8.pack "MESSAGE, PART " `B.append` x 114aType (ArmorSplitMessageIndefinite x) = BC8.pack "MESSAGE, PART " `B.append` (l2s x)
114aType (ArmorSignature) = BC8.pack "SIGNATURE" 115aType (ArmorSignature) = BC8.pack "SIGNATURE"
115 116
117l2s :: BL.ByteString -> ByteString
118l2s = B.concat . BL.toChunks
119
116base64Data :: Parser ByteString 120base64Data :: Parser ByteString
117base64Data = do 121base64Data = do
118 ls <- many1 base64Line 122 ls <- many1 base64Line
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
index 00d9dd3..06d7f1a 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
@@ -10,6 +10,7 @@ module Codec.Encryption.OpenPGP.ASCIIArmor.Encode (
10import Codec.Encryption.OpenPGP.ASCIIArmor.Types 10import Codec.Encryption.OpenPGP.ASCIIArmor.Types
11import Data.ByteString (ByteString) 11import Data.ByteString (ByteString)
12import qualified Data.ByteString as B 12import qualified Data.ByteString as B
13import qualified Data.ByteString.Lazy as BL
13import qualified Data.ByteString.Char8 as BC8 14import qualified Data.ByteString.Char8 as BC8
14import qualified Data.ByteString.Base64 as Base64 15import qualified Data.ByteString.Base64 as Base64
15import Data.Digest.CRC24 (crc24) 16import Data.Digest.CRC24 (crc24)
@@ -21,8 +22,8 @@ encode :: [Armor] -> ByteString
21encode = B.concat . map armor 22encode = B.concat . map armor
22 23
23armor :: Armor -> ByteString 24armor :: Armor -> ByteString
24armor (Armor atype ahs bs) = beginLine atype `B.append` armorHeaders ahs `B.append` blankLine `B.append` armorData bs `B.append` armorChecksum bs `B.append` endLine atype 25armor (Armor atype ahs bs) = beginLine atype `B.append` armorHeaders ahs `B.append` blankLine `B.append` armorData (B.concat . BL.toChunks $ bs) `B.append` armorChecksum (B.concat . BL.toChunks $ bs) `B.append` endLine atype
25armor (ClearSigned chs ctxt csig) = BC8.pack "-----BEGIN PGP SIGNED MESSAGE-----\n" `B.append` armorHeaders chs `B.append` blankLine `B.append` dashEscape ctxt `B.append` armor csig 26armor (ClearSigned chs ctxt csig) = BC8.pack "-----BEGIN PGP SIGNED MESSAGE-----\n" `B.append` armorHeaders chs `B.append` blankLine `B.append` dashEscape (B.concat . BL.toChunks $ ctxt) `B.append` armor csig
26 27
27blankLine :: ByteString 28blankLine :: ByteString
28blankLine = BC8.singleton '\n' 29blankLine = BC8.singleton '\n'
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
index 8719c7c..313c3bc 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
@@ -9,16 +9,16 @@ module Codec.Encryption.OpenPGP.ASCIIArmor.Multipart (
9 9
10import Codec.Encryption.OpenPGP.ASCIIArmor.Types 10import Codec.Encryption.OpenPGP.ASCIIArmor.Types
11 11
12import Data.ByteString (ByteString) 12import Data.ByteString.Lazy (ByteString)
13import qualified Data.ByteString as B 13import qualified Data.ByteString.Lazy as BL
14 14
15multipartMerge :: [Armor] -> Armor 15multipartMerge :: [Armor] -> Armor
16multipartMerge as = go as (Armor ArmorMessage [] B.empty) 16multipartMerge as = go as (Armor ArmorMessage [] BL.empty)
17 where 17 where
18 go :: [Armor] -> Armor -> Armor 18 go :: [Armor] -> Armor -> Armor
19 go [] state = state 19 go [] state = state
20 go ((Armor at hs bs):as) state = go as (go' at hs bs state) 20 go ((Armor at hs bs):as) state = go as (go' at hs bs state)
21 go' :: ArmorType -> [(String,String)] -> ByteString -> Armor -> Armor 21 go' :: ArmorType -> [(String,String)] -> ByteString -> Armor -> Armor
22 go' (ArmorSplitMessage _ _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `B.append` bs) 22 go' (ArmorSplitMessage _ _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `BL.append` bs)
23 go' (ArmorSplitMessageIndefinite _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `B.append` bs) 23 go' (ArmorSplitMessageIndefinite _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `BL.append` bs)
24 go' _ _ _ state = state 24 go' _ _ _ state = state
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
index 88a03ce..fa83d23 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
@@ -8,7 +8,7 @@ module Codec.Encryption.OpenPGP.ASCIIArmor.Types (
8 , ArmorType(..) 8 , ArmorType(..)
9) where 9) where
10 10
11import Data.ByteString (ByteString) 11import Data.ByteString.Lazy (ByteString)
12 12
13data Armor = Armor ArmorType [(String, String)] ByteString 13data Armor = Armor ArmorType [(String, String)] ByteString
14 | ClearSigned [(String, String)] ByteString Armor 14 | ClearSigned [(String, String)] ByteString Armor
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
index 014c8aa..dddecab 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
@@ -5,13 +5,20 @@
5 5
6module Codec.Encryption.OpenPGP.ASCIIArmor.Utils ( 6module Codec.Encryption.OpenPGP.ASCIIArmor.Utils (
7 crlfUnlines 7 crlfUnlines
8 , crlfUnlinesLazy
8) where 9) where
9 10
10import Data.ByteString (ByteString) 11import Data.ByteString (ByteString)
11import qualified Data.ByteString as B 12import qualified Data.ByteString as B
12import qualified Data.ByteString.Char8 as BC8 13import qualified Data.ByteString.Char8 as BC8
14import qualified Data.ByteString.Lazy as BL
15import qualified Data.ByteString.Lazy.Char8 as BLC8
13import Data.List (intersperse) 16import Data.List (intersperse)
14 17
15crlfUnlines :: [ByteString] -> ByteString 18crlfUnlines :: [ByteString] -> ByteString
16crlfUnlines [] = B.empty 19crlfUnlines [] = B.empty
17crlfUnlines ss = B.concat $ intersperse (BC8.pack "\r\n") ss 20crlfUnlines ss = B.concat $ intersperse (BC8.pack "\r\n") ss
21
22crlfUnlinesLazy :: [BL.ByteString] -> BL.ByteString
23crlfUnlinesLazy [] = BL.empty
24crlfUnlinesLazy ss = BL.concat $ intersperse (BLC8.pack "\r\n") ss
diff --git a/tests/suite.hs b/tests/suite.hs
index 838a5f3..ffe8b50 100644
--- a/tests/suite.hs
+++ b/tests/suite.hs
@@ -9,7 +9,9 @@ import Codec.Encryption.OpenPGP.ASCIIArmor.Utils
9 9
10import Data.ByteString (ByteString) 10import Data.ByteString (ByteString)
11import qualified Data.ByteString as B 11import qualified Data.ByteString as B
12import qualified Data.ByteString.Lazy as BL
12import qualified Data.ByteString.Char8 as BC8 13import qualified Data.ByteString.Char8 as BC8
14import qualified Data.ByteString.Lazy.Char8 as BLC8
13import Data.Digest.CRC24 (crc24) 15import Data.Digest.CRC24 (crc24)
14import Data.Word (Word32) 16import Data.Word (Word32)
15 17
@@ -19,7 +21,7 @@ testCRC24 bs crc = assertEqual "crc24" crc (crc24 bs)
19testArmorDecode :: FilePath -> [FilePath] -> Assertion 21testArmorDecode :: FilePath -> [FilePath] -> Assertion
20testArmorDecode fp targets = do 22testArmorDecode fp targets = do
21 bs <- B.readFile $ "tests/data/" ++ fp 23 bs <- B.readFile $ "tests/data/" ++ fp
22 tbss <- mapM (\target -> B.readFile $ "tests/data/" ++ target) targets 24 tbss <- mapM (\target -> BL.readFile $ "tests/data/" ++ target) targets
23 case decode bs of 25 case decode bs of
24 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp 26 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
25 Right as -> assertEqual ("for " ++ fp) tbss (map getPayload as) 27 Right as -> assertEqual ("for " ++ fp) tbss (map getPayload as)
@@ -29,7 +31,7 @@ testArmorDecode fp targets = do
29testArmorMultipartDecode :: FilePath -> FilePath -> Assertion 31testArmorMultipartDecode :: FilePath -> FilePath -> Assertion
30testArmorMultipartDecode fp target = do 32testArmorMultipartDecode fp target = do
31 bs <- B.readFile $ "tests/data/" ++ fp 33 bs <- B.readFile $ "tests/data/" ++ fp
32 tbs <- B.readFile $ "tests/data/" ++ target 34 tbs <- BL.readFile $ "tests/data/" ++ target
33 case decode bs of 35 case decode bs of
34 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp 36 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
35 Right as -> assertEqual ("for " ++ fp) tbs (getPayload (multipartMerge as)) 37 Right as -> assertEqual ("for " ++ fp) tbs (getPayload (multipartMerge as))
@@ -39,18 +41,18 @@ testArmorMultipartDecode fp target = do
39testClearsignedDecodeBody :: FilePath -> FilePath -> Assertion 41testClearsignedDecodeBody :: FilePath -> FilePath -> Assertion
40testClearsignedDecodeBody fp target = do 42testClearsignedDecodeBody fp target = do
41 bs <- B.readFile $ "tests/data/" ++ fp 43 bs <- B.readFile $ "tests/data/" ++ fp
42 tbs <- B.readFile $ "tests/data/" ++ target 44 tbs <- BL.readFile $ "tests/data/" ++ target
43 case decode bs of 45 case decode bs of
44 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp 46 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
45 Right [a] -> assertEqual ("for " ++ fp) (convertEndings tbs) (getBody a) 47 Right [a] -> assertEqual ("for " ++ fp) (convertEndings tbs) (getBody a)
46 where 48 where
47 getBody (ClearSigned _ txt _) = txt 49 getBody (ClearSigned _ txt _) = txt
48 convertEndings = crlfUnlines . BC8.lines 50 convertEndings = crlfUnlinesLazy . BLC8.lines
49 51
50testClearsignedDecodeSig :: FilePath -> FilePath -> Assertion 52testClearsignedDecodeSig :: FilePath -> FilePath -> Assertion
51testClearsignedDecodeSig fp target = do 53testClearsignedDecodeSig fp target = do
52 bs <- B.readFile $ "tests/data/" ++ fp 54 bs <- B.readFile $ "tests/data/" ++ fp
53 tbs <- B.readFile $ "tests/data/" ++ target 55 tbs <- BL.readFile $ "tests/data/" ++ target
54 case decode bs of 56 case decode bs of
55 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp 57 Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
56 Right [a] -> assertEqual ("for " ++ fp) tbs (getSig a) 58 Right [a] -> assertEqual ("for " ++ fp) tbs (getSig a)
@@ -59,14 +61,14 @@ testClearsignedDecodeSig fp target = do
59 61
60testArmorEncode :: [FilePath] -> FilePath -> Assertion 62testArmorEncode :: [FilePath] -> FilePath -> Assertion
61testArmorEncode fps target = do 63testArmorEncode fps target = do
62 bss <- mapM (\fp -> B.readFile $ "tests/data/" ++ fp) fps 64 bss <- mapM (\fp -> BL.readFile $ "tests/data/" ++ fp) fps
63 tbs <- B.readFile $ "tests/data/" ++ target 65 tbs <- B.readFile $ "tests/data/" ++ target
64 assertEqual ("literaldata") tbs (encode (map (\bs -> Armor ArmorMessage [("Version","OpenPrivacy 0.99")] bs) bss)) 66 assertEqual ("literaldata") tbs (encode (map (\bs -> Armor ArmorMessage [("Version","OpenPrivacy 0.99")] bs) bss))
65 67
66testClearsignedEncode :: FilePath -> FilePath -> FilePath -> Assertion 68testClearsignedEncode :: FilePath -> FilePath -> FilePath -> Assertion
67testClearsignedEncode ftxt fsig ftarget = do 69testClearsignedEncode ftxt fsig ftarget = do
68 txt <- B.readFile $ "tests/data/" ++ ftxt 70 txt <- BL.readFile $ "tests/data/" ++ ftxt
69 sig <- B.readFile $ "tests/data/" ++ fsig 71 sig <- BL.readFile $ "tests/data/" ++ fsig
70 target <- B.readFile $ "tests/data/" ++ ftarget 72 target <- B.readFile $ "tests/data/" ++ ftarget
71 assertEqual ("clearsigned encode") target (encode [ClearSigned [("Hash","SHA1")] txt (Armor ArmorSignature [("Version","OpenPrivacy 0.99")] sig)]) 73 assertEqual ("clearsigned encode") target (encode [ClearSigned [("Hash","SHA1")] txt (Armor ArmorSignature [("Version","OpenPrivacy 0.99")] sig)])
72 74