-- |
-- Module      : Amazonka.S3.Encryption.Body
-- Copyright   : (c) 2013-2021 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability   : provisional
-- Portability : non-portable (GHC extensions)
module Amazonka.S3.Encryption.Body where

import Amazonka.Core
import Amazonka.Prelude
import Conduit ((.|))
import qualified Conduit
import qualified Data.ByteString as BS

-- Resides here since it's unsafe without the use of enforceChunks,
-- which incurs extra dependencies not desired in core.
class ToChunkedBody a where
  toChunked :: a -> ChunkedBody

instance ToChunkedBody ChunkedBody where
  toChunked :: ChunkedBody -> ChunkedBody
toChunked = ChunkedBody -> ChunkedBody
forall a. a -> a
id

instance ToChunkedBody HashedBody where
  toChunked :: HashedBody -> ChunkedBody
toChunked = \case
    HashedStream Digest SHA256
_ Integer
n ConduitM () ByteString (ResourceT IO) ()
s -> Integer -> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
forall a.
Integral a =>
a -> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
enforceChunks Integer
n ConduitM () ByteString (ResourceT IO) ()
s
    HashedBytes Digest SHA256
_ ByteString
b -> Int -> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
forall a.
Integral a =>
a -> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
enforceChunks (ByteString -> Int
BS.length ByteString
b) ((ByteString -> ConduitM () ByteString (ResourceT IO) ())
-> [ByteString] -> ConduitM () ByteString (ResourceT IO) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ByteString -> ConduitM () ByteString (ResourceT IO) ()
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
Conduit.yield [ByteString
b])

instance ToChunkedBody RequestBody where
  toChunked :: RequestBody -> ChunkedBody
toChunked = \case
    Chunked ChunkedBody
c -> ChunkedBody
c
    Hashed HashedBody
h -> HashedBody -> ChunkedBody
forall a. ToChunkedBody a => a -> ChunkedBody
toChunked HashedBody
h

enforceChunks ::
  Integral a =>
  a ->
  Conduit.ConduitT () ByteString (Conduit.ResourceT IO) () ->
  ChunkedBody
enforceChunks :: a -> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
enforceChunks a
size ConduitM () ByteString (ResourceT IO) ()
c =
  ChunkSize
-> Integer
-> ConduitM () ByteString (ResourceT IO) ()
-> ChunkedBody
ChunkedBody ChunkSize
defaultChunkSize (a -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
size) (ConduitM () ByteString (ResourceT IO) () -> ChunkedBody)
-> ConduitM () ByteString (ResourceT IO) () -> ChunkedBody
forall a b. (a -> b) -> a -> b
$
    ConduitM () ByteString (ResourceT IO) ()
c ConduitM () ByteString (ResourceT IO) ()
-> ConduitM ByteString ByteString (ResourceT IO) ()
-> ConduitM () ByteString (ResourceT IO) ()
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| Index ByteString
-> ConduitM ByteString ByteString (ResourceT IO) ()
forall (m :: * -> *) seq.
(Monad m, IsSequence seq) =>
Index seq -> ConduitT seq seq m ()
Conduit.chunksOfCE (ChunkSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ChunkSize
defaultChunkSize)