{-# LINE 1 "OpenSSL/EVP/Base64.hsc" #-}{- -*- haskell -*- -}{-# LINE 2 "OpenSSL/EVP/Base64.hsc" #-}-- |An interface to Base64 codec.moduleOpenSSL.EVP.Base64(-- * EncodingencodeBase64,encodeBase64BS,encodeBase64LBS-- * Decoding,decodeBase64,decodeBase64BS,decodeBase64LBS)whereimportControl.Exceptionhiding(block)importData.ByteString.Internal(createAndTrim)importData.ByteString.Unsafe(unsafeUseAsCStringLen)importqualifiedData.ByteString.Lazy.InternalasL8InternalimportqualifiedData.ByteString.Char8asB8importqualifiedData.ByteString.Lazy.Char8asL8importData.ListimportForeignhiding(unsafePerformIO)importForeign.CimportSystem.IO.Unsafe(unsafePerformIO)-- On encoding, we keep fetching the next block until we get at least-- 3 bytes. Then we apply B8.concat to the returned [ByteString] and-- split it at the offset in multiple of 3, then prepend the remaining-- bytes to the next block.---- On decoding, we apply the same algorithm but we split the input in-- multiple of 4.nextBlock::Int->([B8.ByteString],L8.ByteString)->([B8.ByteString],L8.ByteString)nextBlockminLen(xs,src)=iffoldl'(+)0(mapB8.lengthxs)>=minLenthen(xs,src)elsecasesrcofL8Internal.Empty->(xs,src)L8Internal.Chunkyys->nextBlockminLen(xs++[y],ys){- encode -------------------------------------------------------------------- -}foreignimportccallunsafe"EVP_EncodeBlock"_EncodeBlock::PtrCChar->PtrCChar->CInt->IOCIntencodeBlock::B8.ByteString->B8.ByteStringencodeBlockinBS=unsafePerformIO$unsafeUseAsCStringLeninBS$\(inBuf,inLen)->createAndTrimmaxOutLen$\outBuf->fmapfromIntegral(_EncodeBlock(castPtroutBuf)inBuf(fromIntegralinLen))wheremaxOutLen=(inputLen`div`3+1)*4+1-- +1: '\0'inputLen=B8.lengthinBS-- |@'encodeBase64' str@ lazilly encodes a stream of data to-- Base64. The string doesn't have to be finite. Note that the string-- must not contain any letters which aren't in the range of U+0000 --- U+00FF.encodeBase64::String->StringencodeBase64=L8.unpack.encodeBase64LBS.L8.pack-- |@'encodeBase64BS' bs@ strictly encodes a chunk of data to Base64.encodeBase64BS::B8.ByteString->B8.ByteStringencodeBase64BS=encodeBlock-- |@'encodeBase64LBS' lbs@ lazilly encodes a stream of data to-- Base64. The string doesn't have to be finite.encodeBase64LBS::L8.ByteString->L8.ByteStringencodeBase64LBSinLBS|L8.nullinLBS=L8.empty|otherwise=let(blockParts',remain')=nextBlock3([],inLBS)block'=B8.concatblockParts'blockLen'=B8.lengthblock'(block,leftover)=ifblockLen'<3then-- The last remnant.(block',B8.empty)elseB8.splitAt(blockLen'-blockLen'`mod`3)block'remain=ifB8.nullleftoverthenremain'elseL8.fromChunks[leftover]`L8.append`remain'encodedBlock=encodeBlockblockencodedRemain=encodeBase64LBSremaininL8.fromChunks[encodedBlock]`L8.append`encodedRemain{- decode -------------------------------------------------------------------- -}foreignimportccallunsafe"EVP_DecodeBlock"_DecodeBlock::PtrCChar->PtrCChar->CInt->IOCIntdecodeBlock::B8.ByteString->B8.ByteStringdecodeBlockinBS=assert(B8.lengthinBS`mod`4==0)$unsafePerformIO$unsafeUseAsCStringLeninBS$\(inBuf,inLen)->createAndTrim(B8.lengthinBS)$\outBuf->_DecodeBlock(castPtroutBuf)inBuf(fromIntegralinLen)>>=\outLen->return(fromIntegraloutLen-paddingLen)wherepaddingLen::IntpaddingLen=B8.count'='inBS-- |@'decodeBase64' str@ lazilly decodes a stream of data from-- Base64. The string doesn't have to be finite.decodeBase64::String->StringdecodeBase64=L8.unpack.decodeBase64LBS.L8.pack-- |@'decodeBase64BS' bs@ strictly decodes a chunk of data from-- Base64.decodeBase64BS::B8.ByteString->B8.ByteStringdecodeBase64BS=decodeBlock-- |@'decodeBase64LBS' lbs@ lazilly decodes a stream of data from-- Base64. The string doesn't have to be finite.decodeBase64LBS::L8.ByteString->L8.ByteStringdecodeBase64LBSinLBS|L8.nullinLBS=L8.empty|otherwise=let(blockParts',remain')=nextBlock4([],inLBS)block'=B8.concatblockParts'blockLen'=B8.lengthblock'(block,leftover)=assert(blockLen'>=4)$B8.splitAt(blockLen'-blockLen'`mod`4)block'remain=ifB8.nullleftoverthenremain'elseL8.fromChunks[leftover]`L8.append`remain'decodedBlock=decodeBlockblockdecodedRemain=decodeBase64LBSremaininL8.fromChunks[decodedBlock]`L8.append`decodedRemain