emailparse-0.2.0.6: src/Network/Mail/Parse/Parsers/Multipart.hs
module Network.Mail.Parse.Parsers.Multipart (parseMultipart) where
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString as BS
import Data.Word8
import Data.Attoparsec.ByteString
import Network.Mail.Parse.Utils
isBoundaryMatched :: BSC.ByteString -> Int -> Word8 -> Maybe Int
isBoundaryMatched boundary matchIdx char =
if char == BS.index boundary matchIdx
then if matchIdx == boundaryLength - 1
then Nothing
else Just $ matchIdx + 1
else Just 0
where boundaryLength = BS.length boundary
trimPayload :: BSC.ByteString -> BSC.ByteString -> BSC.ByteString
trimPayload boundary payload = BSC.take trimLength payload
where payloadLength = BSC.length payload
boundaryLength = BSC.length boundary
trimLength = payloadLength - boundaryLength + 1
parseMultipart :: BSC.ByteString -> Parser [BSC.ByteString]
parseMultipart boundary =
do
_ <- manyTill' anyWord8 (string completeBoundary) <* consumeTillEndLine
payloads <- many' (scan 0 (isBoundaryMatched completeBoundary) <* consumeTillEndLine)
return $ map (trimPayload completeBoundary) payloads
where completeBoundary = BSC.append "--" boundary