crypton-pem-0.3.0: src/Data/PEM/Writer.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Data.PEM.Writer
License : BSD-style
Copyright : (c) 2010-2018 Vincent Hanquez <vincent@snarc.org>
Stability : experimental
Portability : portable
-}
module Data.PEM.Writer
( pemWriteBS
, pemWriteLBS
) where
#if MIN_VERSION_base64(1,0,0)
import Data.Base64.Types ( extractBase64 )
#endif
import Data.ByteString ( ByteString )
import qualified Data.ByteString as B
import Data.ByteString.Base64 ( encodeBase64' )
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as L
import Data.PEM.Types ( PEM (..) )
-- | A helper function while base64 < 1.0 is supported.
encodeBase64 :: ByteString -> ByteString
#if MIN_VERSION_base64(1,0,0)
encodeBase64 = extractBase64 . encodeBase64'
#else
encodeBase64 = encodeBase64'
#endif
-- | Write a t'PEM' to a lazy 'Data.ByteString.Lazy.ByteString'.
pemWrite :: PEM -> L.ByteString
pemWrite pem = L.fromChunks ([begin, header] ++ section ++ [end])
where
begin = B.concat ["-----BEGIN ", sectionName, "-----\n"]
end = B.concat ["-----END ", sectionName, "-----\n" ]
section :: [ByteString]
section = map encodeLine $ splitChunks $ pemContent pem
header :: ByteString
header = if null $ pemHeader pem
then B.empty
else B.concat (concatMap toHeader (pemHeader pem) ++ ["\n"])
toHeader :: (String, ByteString) -> [ByteString]
toHeader (k,v) = [ BC.pack k, ":", v, "\n" ]
-- expect only ASCII. need to find a type to represent it.
sectionName = BC.pack $ pemName pem
encodeLine l = encodeBase64 l `B.append` "\n"
splitChunks b
| B.length b > 48 = let (x,y) = B.splitAt 48 b in x : splitChunks y
| otherwise = [b]
-- | Convert the specified t'PEM' to a strict 'ByteString'.
pemWriteBS :: PEM -> ByteString
pemWriteBS = B.concat . L.toChunks . pemWrite
-- | Convert the specified t'PEM' to a lazy 'Data.ByteString.Lazy.ByteString'.
pemWriteLBS :: PEM -> L.ByteString
pemWriteLBS = pemWrite