{-# LANGUAGE OverloadedStrings #-}
module Data.PEM.Writer
( pemWriteLBS
, pemWriteBS
) where
import Data.PEM.Types
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as L
import Data.ByteArray.Encoding (Base(Base64), convertToBase)
pemWrite :: PEM -> L.ByteString
pemWrite :: PEM -> ByteString
pemWrite PEM
pem = [ByteString] -> ByteString
L.fromChunks ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ ([ByteString
begin,ByteString
header][ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++[ByteString]
section[ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++[ByteString
end])
where begin :: ByteString
begin = [ByteString] -> ByteString
B.concat [ByteString
"-----BEGIN ", ByteString
sectionName, ByteString
"-----\n"]
end :: ByteString
end = [ByteString] -> ByteString
B.concat [ByteString
"-----END ", ByteString
sectionName, ByteString
"-----\n" ]
section :: [ByteString]
section :: [ByteString]
section = (ByteString -> ByteString) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> ByteString
forall {bin}. ByteArrayAccess bin => bin -> ByteString
encodeLine ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
splitChunks (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall a b. (a -> b) -> a -> b
$ PEM -> ByteString
pemContent PEM
pem
header :: ByteString
header :: ByteString
header = if [(String, ByteString)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([(String, ByteString)] -> Bool) -> [(String, ByteString)] -> Bool
forall a b. (a -> b) -> a -> b
$ PEM -> [(String, ByteString)]
pemHeader PEM
pem
then ByteString
B.empty
else [ByteString] -> ByteString
B.concat ((((String, ByteString) -> [ByteString])
-> [(String, ByteString)] -> [ByteString]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String, ByteString) -> [ByteString]
toHeader (PEM -> [(String, ByteString)]
pemHeader PEM
pem)) [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString
"\n"])
toHeader :: (String, ByteString) -> [ByteString]
toHeader :: (String, ByteString) -> [ByteString]
toHeader (String
k,ByteString
v) = [ String -> ByteString
BC.pack String
k, ByteString
":", ByteString
v, ByteString
"\n" ]
sectionName :: ByteString
sectionName = String -> ByteString
BC.pack (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ PEM -> String
pemName PEM
pem
encodeLine :: bin -> ByteString
encodeLine bin
l = Base -> bin -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
convertToBase Base
Base64 bin
l ByteString -> ByteString -> ByteString
`B.append` ByteString
"\n"
splitChunks :: ByteString -> [ByteString]
splitChunks ByteString
b
| ByteString -> Int
B.length ByteString
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
48 = let (ByteString
x,ByteString
y) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
48 ByteString
b in ByteString
x ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: ByteString -> [ByteString]
splitChunks ByteString
y
| Bool
otherwise = [ByteString
b]
pemWriteBS :: PEM -> ByteString
pemWriteBS :: PEM -> ByteString
pemWriteBS = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString)
-> (PEM -> [ByteString]) -> PEM -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks (ByteString -> [ByteString])
-> (PEM -> ByteString) -> PEM -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PEM -> ByteString
pemWrite
pemWriteLBS :: PEM -> L.ByteString
pemWriteLBS :: PEM -> ByteString
pemWriteLBS = PEM -> ByteString
pemWrite