    {-# LANGUAGE CPP #-}
    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Trustworthy #-}
    #endif

    -- |
    -- Module      : Data.ByteString.Base64
    -- Copyright   : (c) 2010 Bryan O'Sullivan
    --
    -- License     : BSD-style
    -- Maintainer  : Emily Pillmore <emilypi@cohomolo.gy>,
    --               Herbert Valerio Riedel <hvr@gnu.org>,
    --               Mikhail Glushenkov <mikhail.glushenkov@gmail.com>
    -- Stability   : experimental
    -- Portability : GHC
    --
    -- Fast and efficient encoding and decoding of base64-encoded strings.
    --
    -- @since 0.1.0.0
    module Data.ByteString.Base64
      ( encode
      , decode
      , decodeLenient
      ) where

    import Data.ByteString.Base64.Internal
    import qualified Data.ByteString as B
    import Data.ByteString.Internal (ByteString(..))
    import Data.Word (Word8)
    import Foreign.ForeignPtr (ForeignPtr)

    -- | Encode a string into base64 form.  The result will always be a
    -- multiple of 4 bytes in length.
    encode :: ByteString -> ByteString
    encode :: ByteString -> ByteString
    encode ByteString
    s = Padding -> EncodeTable -> ByteString -> ByteString
    encodeWith Padding
    Padded (ByteString -> EncodeTable
    mkEncodeTable ByteString
    alphabet) ByteString
    s

    -- | Decode a base64-encoded string. This function strictly follows
    -- the specification in
    -- <http://tools.ietf.org/rfc/rfc4648 RFC 4648>.
    --
    -- (Note: this means that even @"\\n"@ and @"\\r\\n"@ as line breaks are rejected
    -- rather than ignored.  If you are using this in the context of a
    -- standard that overrules RFC 4648 such as HTTP multipart mime bodies,
    -- consider using 'decodeLenient'.)
    decode :: ByteString -> Either String ByteString
    decode :: ByteString -> Either String ByteString
    decode ByteString
    s = Padding
    -> ForeignPtr Word8 -> ByteString -> Either String ByteString
    decodeWithTable Padding
    Padded ForeignPtr Word8
    decodeFP ByteString
    s

    -- | Decode a base64-encoded string.  This function is lenient in
    -- following the specification from
    -- <http://tools.ietf.org/rfc/rfc4648 RFC 4648>, and will not
    -- generate parse errors no matter how poor its input.
    decodeLenient :: ByteString -> ByteString
    decodeLenient :: ByteString -> ByteString
    decodeLenient ByteString
    s = ForeignPtr Word8 -> ByteString -> ByteString
    decodeLenientWithTable ForeignPtr Word8
    decodeFP ByteString
    s

    alphabet :: ByteString
    alphabet :: ByteString
    alphabet = [Word8] -> ByteString
    B.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ [Word8
    65..Word8
    90] [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    97..Word8
    122] [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    48..Word8
    57] [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    43,Word8
    47]
    {-# NOINLINE alphabet #-}

    decodeFP :: ForeignPtr Word8
    #if MIN_VERSION_bytestring(0,11,0)
    BS ForeignPtr Word8
    decodeFP Int
    _ =
    #else
    PS decodeFP _ _ =
    #endif
      [Word8] -> ByteString
    B.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> [Word8]
    forall a. Int -> a -> [a]
    replicate Int
    43 Word8
    forall a. Integral a => a
    x
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    62,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    63]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    52..Word8
    61]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    done,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    0..Word8
    25]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x,Word8
    forall a. Integral a => a
    x]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ [Word8
    26..Word8
    51]
        [Word8] -> [Word8] -> [Word8]
    forall a. [a] -> [a] -> [a]
    ++ Int -> Word8 -> [Word8]
    forall a. Int -> a -> [a]
    replicate Int
    133 Word8
    forall a. Integral a => a
    x
    {-# NOINLINE decodeFP #-}

    x :: Integral a => a
    x :: forall a. Integral a => a
    x = a
    255
    {-# INLINE x #-}