casa-reoc-0.1.0.0: src/ReOC/Render/Base64.hs
{-# OPTIONS_GHC -Wall #-}
-- | Base64, for images embedded in Flat ODF text.
module ReOC.Render.Base64 (
base64,
) where
import Data.Bits (shiftL, shiftR, (.&.), (.|.))
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Word (Word8)
{- $setup
>>> import qualified Data.ByteString.Char8 as Char8
-}
{- | The base64 encoding of bytes (RFC 4648), with padding.
>>> base64 (Char8.pack "Man")
"TWFu"
>>> base64 (Char8.pack "Ma")
"TWE="
>>> base64 (Char8.pack "M")
"TQ=="
-}
base64 :: ByteString -> Text
base64 =
Text.pack . go . ByteString.unpack
where
go (a : b : c : rest) =
quad a b c <> go rest
go [a, b] =
take 3 (quad a b 0) <> "="
go [a] =
take 2 (quad a 0 0) <> "=="
go [] =
[]
quad :: Word8 -> Word8 -> Word8 -> String
quad a b c =
let n = (fromIntegral a `shiftL` 16) .|. (fromIntegral b `shiftL` 8) .|. fromIntegral c :: Int
in map (\k -> alphabet !! ((n `shiftR` k) .&. 63)) [18, 12, 6, 0]
alphabet =
['A' .. 'Z'] <> ['a' .. 'z'] <> ['0' .. '9'] <> "+/"